[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: \"\"\nlabels: \"\"\nassignees: \"\"\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**Reproduction steps**\nSteps to reproduce the issue seen.\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Additional context**\n\n- `rails` version:\n- `rails_admin` version:\n- `rails_admin` npm package version:\n- full stack trace (if there's an exception)\n\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: \"\"\nlabels: enhancement\nassignees: \"\"\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe proposed solution(s)**\nA clear and concise description of what you want to happen.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/workflows/code-ql.yml",
    "content": "name: \"CodeQL\"\n\non:\n  push:\n    branches: [master]\n  pull_request:\n    # The branches below must be a subset of the branches above\n    branches: [master]\n  schedule:\n    - cron: \"12 00 * * 5\"\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [\"ruby\"]\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v3\n\n      # Initializes the CodeQL tools for scanning.\n      - name: Initialize CodeQL\n        uses: github/codeql-action/init@v2\n        with:\n          languages: ${{ matrix.language }}\n\n      - name: Perform CodeQL Analysis\n        uses: github/codeql-action/analyze@v2\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\non: [push, pull_request]\n\njobs:\n  rspec:\n    name: RSpec\n    strategy:\n      fail-fast: false\n      matrix:\n        ruby:\n          - \"3.2\"\n          - \"3.3\"\n          - \"3.4\"\n        gemfile: [gemfiles/rails_8.0.gemfile]\n        orm: [active_record]\n        adapter: [sqlite3]\n        asset: [webpack]\n        include:\n          - ruby: 2.6\n            gemfile: gemfiles/rails_6.0.gemfile\n            orm: active_record\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: 2.7\n            gemfile: gemfiles/rails_6.1.gemfile\n            orm: active_record\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: 2.7\n            gemfile: gemfiles/rails_6.1.gemfile\n            orm: active_record\n            adapter: sqlite3\n            asset: webpacker\n          - ruby: \"3.0\"\n            gemfile: gemfiles/rails_7.0.gemfile\n            orm: active_record\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: \"3.1\"\n            gemfile: gemfiles/rails_7.1.gemfile\n            orm: active_record\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: \"3.2\"\n            gemfile: gemfiles/rails_7.2.gemfile\n            orm: active_record\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: \"3.4\"\n            gemfile: gemfiles/rails_8.0.gemfile\n            orm: active_record\n            adapter: mysql2\n            asset: importmap\n          - ruby: \"3.4\"\n            gemfile: gemfiles/rails_8.0.gemfile\n            orm: active_record\n            adapter: postgresql\n            asset: sprockets\n          - ruby: \"3.4\"\n            gemfile: gemfiles/rails_8.0.gemfile\n            orm: active_record\n            adapter: sqlite3\n            asset: vite\n          - ruby: \"3.4\"\n            gemfile: gemfiles/rails_8.0.gemfile\n            orm: active_record\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: \"3.2\"\n            gemfile: gemfiles/composite_primary_keys.gemfile\n            orm: active_record\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: 2.7\n            gemfile: gemfiles/rails_6.0.gemfile\n            orm: mongoid\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: \"3.0\"\n            gemfile: gemfiles/rails_6.1.gemfile\n            orm: mongoid\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: \"3.1\"\n            gemfile: gemfiles/rails_7.0.gemfile\n            orm: mongoid\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: \"3.2\"\n            gemfile: gemfiles/rails_7.1.gemfile\n            orm: mongoid\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: \"3.3\"\n            gemfile: gemfiles/rails_7.2.gemfile\n            orm: mongoid\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: \"3.4\"\n            gemfile: gemfiles/rails_8.0.gemfile\n            orm: mongoid\n            adapter: sqlite3\n            asset: sprockets\n          - ruby: jruby-9.4\n            gemfile: gemfiles/rails_7.1.gemfile\n            orm: active_record\n            adapter: mysql2\n            asset: sprockets\n          - ruby: jruby-9.4\n            gemfile: gemfiles/rails_7.1.gemfile\n            orm: mongoid\n            adapter: sqlite3\n            asset: sprockets\n    runs-on: ubuntu-latest\n    services:\n      mysql:\n        image: mysql:8.0\n        ports:\n          - 3306:3306\n        env:\n          MYSQL_ALLOW_EMPTY_PASSWORD: yes\n      postgres:\n        image: postgres:11\n        ports:\n          - 5432:5432\n        env:\n          POSTGRES_USER: postgres\n          POSTGRES_PASSWORD: postgres\n        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5\n      mongo:\n        image: mongo:4.4\n        ports:\n          - 27017:27017\n    env:\n      BUNDLE_GEMFILE: ${{ matrix.gemfile }}\n      CI_ORM: ${{ matrix.orm }}\n      CI_ASSET: ${{ matrix.asset }}\n      JRUBY_OPTS: --debug\n    steps:\n      - uses: actions/checkout@v4\n      - name: Set up Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: ${{ matrix.ruby }}\n          bundler-cache: true\n          cache-version: gems-${{ hashFiles('Gemfile', 'gemfiles/*.gemfile') }}\n        env:\n          MAKEFLAGS: make --jobs 4\n          BUNDLE_WITHOUT: development\n      - name: Set up Node\n        uses: actions/setup-node@v4\n        with:\n          node-version: \"20\"\n      - name: Install ImageMagick\n        run: sudo apt-get install imagemagick\n      - name: Setup application\n        env:\n          BUNDLE_GEMFILE: ../../${{ matrix.gemfile }}\n          CI_ASSET: ${{ matrix.asset }}\n          CI_DB_ADAPTER: ${{ matrix.adapter }}\n          RAILS_ENV: test\n          NODE_OPTIONS: --openssl-legacy-provider\n        run: |\n          yarn install\n          cd spec/dummy_app\n          bundle exec rake rails_admin:prepare_ci_env db:create db:schema:load\n          yarn install\n          case \"$CI_ASSET\" in\n          \"webpack\" ) yarn build && yarn build:css ;;\n          \"importmap\" ) yarn build:css ;;\n          esac\n          cd ../../\n      - name: Run tests\n        run: bundle exec rspec\n      - name: Coveralls Parallel\n        if: ${{ github.repository_owner == 'railsadminteam' }}\n        uses: coverallsapp/github-action@v2\n        continue-on-error: true\n        with:\n          github-token: ${{ secrets.github_token }}\n          flag-name: run-${{ matrix.ruby }}-${{ matrix.gemfile }}-${{ matrix.orm }}-${{ matrix.adapter }}\n          parallel: true\n\n  coveralls:\n    name: Coveralls\n    if: ${{ github.repository_owner == 'railsadminteam' }}\n    needs: rspec\n    runs-on: ubuntu-latest\n    steps:\n      - name: Coveralls Finished\n        uses: coverallsapp/github-action@v2\n        with:\n          github-token: ${{ secrets.github_token }}\n          parallel-finished: true\n\n  prettier:\n    name: Prettier\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - name: Set up Node.js\n        uses: actions/setup-node@v4\n      - name: Install dependencies\n        run: yarn install\n      - name: Run check\n        run: yarn run prettier --check .\n\n  rubocop:\n    name: RuboCop\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - name: Set up Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.2\"\n          bundler-cache: true\n          cache-version: gems-${{ hashFiles('Gemfile') }}\n      - name: Install dependencies\n        run: bundle install --without development --jobs=3 --retry=3 --path=vendor/bundle\n      - name: Run check\n        run: bundle exec rake rubocop\n"
  },
  {
    "path": ".gitignore",
    "content": "*.gem\n*.log\n*.rbc\n*.swp\n.bundle\n.idea/\n.vscode/\n.rvmrc\n.sass-cache\n.yardoc\n/.emacs.desktop\n/gemfiles/*.lock\n/node_modules/*\n/rails_admin.gems\n/spec/generators/tmp\n/spec/lib/tmp\n/yarn.lock\nGemfile.lock\ncoverage/*\ndb/*.sqlite3\ndb/*.sqlite3-journal\ndoc/*\nlog/*.log\npkg/*\nspec/dummy_app/db/*.sqlite3\nspec/dummy_app/db/*.sqlite3-journal\nspec/dummy_app/log/*.log\nspec/dummy_app/public/uploads\nspec/dummy_app/Gemfile*.lock\ntmp/**/*\nnbproject\n"
  },
  {
    "path": ".prettierignore",
    "content": "coverage\nlib/generators/rails_admin/templates\nspec/dummy_app/app/assets/builds\nspec/dummy_app/public\nspec/dummy_app/tmp\nspec/support/jquery.simulate.drag-sortable.js\nvendor\n"
  },
  {
    "path": ".rspec",
    "content": "--color\n--order=random\n--profile\n--exclude-pattern 'dummy_app/node_modules/rails_admin/**/*_spec.rb'\n"
  },
  {
    "path": ".rubocop.yml",
    "content": "inherit_from: .rubocop_todo.yml\n\nrequire:\n  - rubocop-performance\n\nAllCops:\n  Exclude:\n    - \"gemfiles/*\"\n    - \"node_modules/**/*\"\n    - \"spec/dummy_app/bin/**/*\"\n    - \"spec/dummy_app/db/schema.rb\"\n    - \"spec/dummy_app/node_modules/**/*\"\n    - \"spec/dummy_app/tmp/**/*\"\n    - \"vendor/bundle/**/*\"\n  NewCops: disable\n  SuggestExtensions: false\n  TargetRubyVersion: 2.6\n\nGemspec/DeprecatedAttributeAssignment:\n  Enabled: true\n\nLayout/AccessModifierIndentation:\n  EnforcedStyle: outdent\n\nLayout/DotPosition:\n  EnforcedStyle: trailing\n\nLayout/LineEndStringConcatenationIndentation:\n  Enabled: true\n\nLayout/LineLength:\n  AllowURI: true\n  Enabled: false\n\nLayout/MultilineAssignmentLayout:\n  Enabled: true\n  SupportedTypes: [case, if]\n\nLayout/SpaceBeforeBrackets:\n  Enabled: true\n\nLayout/SpaceInsideHashLiteralBraces:\n  EnforcedStyle: no_space\n\nLint/AmbiguousAssignment:\n  Enabled: true\n\nLint/AmbiguousRange:\n  Enabled: true\n\nLint/DeprecatedConstants:\n  Enabled: true\n\nLint/DuplicateBranch:\n  Enabled: true\n  IgnoreLiteralBranches: true\n\nLint/DuplicateRegexpCharacterClassElement:\n  Enabled: true\n\nLint/EmptyBlock:\n  Enabled: true\n  Exclude:\n    - \"spec/**/*\"\n\nLint/EmptyClass:\n  Enabled: true\n  Exclude:\n    - \"spec/**/*\"\n\nLint/EmptyInPattern:\n  Enabled: true\n\nLint/LambdaWithoutLiteralBlock:\n  Enabled: true\n\nLint/NoReturnInBeginEndBlocks:\n  Enabled: true\n\nLint/NumberedParameterAssignment:\n  Enabled: true\n\nLint/OrAssignmentToConstant:\n  Enabled: true\n\nLint/RedundantDirGlobSort:\n  Enabled: true\n\nLint/SymbolConversion:\n  Enabled: true\n\nLint/ToEnumArguments:\n  Enabled: true\n\nLint/TripleQuotes:\n  Enabled: true\n\nLint/UnexpectedBlockArity:\n  Enabled: true\n\nLint/UnmodifiedReduceAccumulator:\n  Enabled: true\n\nMetrics/AbcSize:\n  Max: 69.98 # TODO: Lower to 15\n\nMetrics/BlockNesting:\n  Max: 3\n\nMetrics/ClassLength:\n  CountComments: false\n  Max: 201 # TODO: Lower to 100\n\nMetrics/CyclomaticComplexity:\n  Max: 15 # TODO: Lower to 6\n\nMetrics/MethodLength:\n  CountComments: false\n  Max: 29 # TODO: Lower to 15\n\nMetrics/ModuleLength:\n  Max: 219 # TODO: Lower to 100\n\nMetrics/ParameterLists:\n  Max: 8 # TODO: Lower to 4\n  CountKeywordArgs: true\n\nMetrics/PerceivedComplexity:\n  Max: 17 # TODO: Lower to 7\n\nNaming/FileName:\n  Exclude:\n    - \"lib/rails_admin/bootstrap-sass.rb\"\n\nNaming/InclusiveLanguage:\n  Enabled: true\n\nStyle/Alias:\n  Enabled: false\n\nStyle/ArgumentsForwarding:\n  Enabled: true\n\nStyle/CollectionCompact:\n  Enabled: true\n\nStyle/CollectionMethods:\n  PreferredMethods:\n    map: \"collect\"\n    reduce: \"inject\"\n    find: \"detect\"\n    find_all: \"select\"\n\nStyle/Documentation:\n  Enabled: false\n\nStyle/DocumentDynamicEvalDefinition:\n  Enabled: false\n\nStyle/DoubleNegation:\n  Enabled: false\n\nStyle/EachWithObject:\n  Enabled: false\n\nStyle/EndlessMethod:\n  Enabled: true\n\nStyle/HashConversion:\n  Enabled: true\n\nStyle/HashExcept:\n  Enabled: true\n\nStyle/IfWithBooleanLiteralBranches:\n  Enabled: true\n\nStyle/InPatternThen:\n  Enabled: true\n\nStyle/Lambda:\n  Enabled: false\n\nStyle/MultilineInPatternThen:\n  Enabled: true\n\nStyle/NegatedIfElseCondition:\n  Enabled: true\n\nStyle/NumericPredicate:\n  Enabled: false\n\nStyle/NilLambda:\n  Enabled: true\n\nStyle/QuotedSymbols:\n  Enabled: true\n\nStyle/RaiseArgs:\n  EnforcedStyle: compact\n\nStyle/RedundantArgument:\n  Enabled: true\n\nStyle/RedundantParentheses:\n  Enabled: false\n\nStyle/RedundantSelfAssignmentBranch:\n  Enabled: true\n\nStyle/StringChars:\n  Enabled: true\n\nStyle/SwapValues:\n  Enabled: true\n\nStyle/TrailingCommaInArguments:\n  EnforcedStyleForMultiline: \"comma\"\n\nStyle/TrailingCommaInArrayLiteral:\n  EnforcedStyleForMultiline: \"comma\"\n\nStyle/TrailingCommaInHashLiteral:\n  EnforcedStyleForMultiline: \"comma\"\n"
  },
  {
    "path": ".rubocop_todo.yml",
    "content": "# This configuration was generated by\n# `rubocop --auto-gen-config`\n# on 2021-11-20 13:57:54 UTC using RuboCop version 1.23.0.\n# The point is for the user to remove these configuration records\n# one by one as the offenses are removed from the code base.\n# Note that changes in the inspected code, or installation of new\n# versions of RuboCop, may require this file to be generated again.\n\n# Offense count: 51\n# Configuration parameters: AllowedMethods.\n# AllowedMethods: enums\nLint/ConstantDefinitionInBlock:\n  Enabled: false\n\n# Offense count: 1\nLint/ReturnInVoidContext:\n  Exclude:\n    - \"lib/rails_admin/support/csv_converter.rb\"\n\n# Offense count: 226\n# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.\n# IgnoredMethods: refine\nMetrics/BlockLength:\n  Max: 1135\n\n# Offense count: 1\n# Configuration parameters: Max, CountKeywordArgs.\nMetrics/ParameterLists:\n  MaxOptionalParameters: 4\n\n# Offense count: 6\nNaming/AccessorMethodName:\n  Exclude:\n    - \"app/controllers/rails_admin/application_controller.rb\"\n    - \"app/controllers/rails_admin/main_controller.rb\"\n    - \"lib/rails_admin/abstract_model.rb\"\n\n# Offense count: 2\n# Configuration parameters: EnforcedStyleForLeadingUnderscores.\n# SupportedStylesForLeadingUnderscores: disallowed, required, optional\nNaming/MemoizedInstanceVariableName:\n  Exclude:\n    - \"app/controllers/rails_admin/application_controller.rb\"\n    - \"lib/rails_admin/config/has_description.rb\"\n\n# Offense count: 2\n# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.\n# AllowedNames: at, by, db, id, in, io, ip, of, on, os, pp, to\nNaming/MethodParameterName:\n  Exclude:\n    - \"lib/rails_admin/abstract_model.rb\"\n    - \"spec/rails_admin/adapters/mongoid/property_spec.rb\"\n\n# Offense count: 1\n# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers.\n# SupportedStyles: snake_case, normalcase, non_integer\n# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339\nNaming/VariableNumber:\n  Exclude:\n    - \"spec/helpers/rails_admin/application_helper_spec.rb\"\n\n# Offense count: 11\nStyle/ClassVars:\n  Exclude:\n    - \"lib/rails_admin/abstract_model.rb\"\n    - \"lib/rails_admin/config.rb\"\n    - \"lib/rails_admin/config/actions.rb\"\n    - \"lib/rails_admin/config/fields.rb\"\n    - \"lib/rails_admin/config/fields/types.rb\"\n\n# Offense count: 2\n# Configuration parameters: MaxUnannotatedPlaceholdersAllowed, IgnoredMethods.\n# SupportedStyles: annotated, template, unannotated\nStyle/FormatStringToken:\n  EnforcedStyle: template\n\n# Offense count: 8\n# Configuration parameters: MinBodyLength.\nStyle/GuardClause:\n  Exclude:\n    - \"app/helpers/rails_admin/main_helper.rb\"\n    - \"lib/rails_admin.rb\"\n    - \"lib/rails_admin/bootstrap-sass.rb\"\n    - \"lib/rails_admin/config.rb\"\n    - \"lib/rails_admin/config/actions.rb\"\n    - \"lib/rails_admin/config/fields/types/polymorphic_association.rb\"\n    - \"lib/rails_admin/config/sections/list.rb\"\n\n# Offense count: 2\nStyle/MissingRespondToMissing:\n  Exclude:\n    - \"lib/rails_admin/config/model.rb\"\n    - \"lib/rails_admin/config/proxyable/proxy.rb\"\n\n# Offense count: 17\n# Configuration parameters: AllowedMethods.\n# AllowedMethods: respond_to_missing?\nStyle/OptionalBooleanParameter:\n  Exclude:\n    - \"app/helpers/rails_admin/application_helper.rb\"\n    - \"lib/rails_admin/config/fields/types/active_storage.rb\"\n    - \"lib/rails_admin/config/fields/types/carrierwave.rb\"\n    - \"lib/rails_admin/config/fields/types/dragonfly.rb\"\n    - \"lib/rails_admin/config/fields/types/multiple_active_storage.rb\"\n    - \"lib/rails_admin/config/fields/types/multiple_carrierwave.rb\"\n    - \"lib/rails_admin/config/fields/types/multiple_file_upload.rb\"\n    - \"lib/rails_admin/config/fields/types/paperclip.rb\"\n    - \"lib/rails_admin/config/has_fields.rb\"\n    - \"spec/integration/fields/file_upload_spec.rb\"\n    - \"spec/integration/fields/multiple_file_upload_spec.rb\"\n    - \"spec/orm/active_record.rb\"\n    - \"spec/orm/mongoid.rb\"\n    - \"spec/rails_admin/config/fields/types/multiple_file_upload_spec.rb\"\n\n# Offense count: 3\n# Cop supports --auto-correct.\n# Configuration parameters: Mode.\nStyle/StringConcatenation:\n  Exclude:\n    - \"app/helpers/rails_admin/application_helper.rb\"\n    - \"lib/rails_admin/extensions/paper_trail/auditing_adapter.rb\"\n\n# Offense count: 2\n# Cop supports --auto-correct.\n# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.\n# SupportedStyles: single_quotes, double_quotes\nStyle/StringLiterals:\n  Exclude:\n    - \"app/helpers/rails_admin/application_helper.rb\"\n"
  },
  {
    "path": ".teatro.yml",
    "content": "project:\n  platform: rails\n\nstage:\n  before:\n    - export CI_DB_ADAPTER=postgresql\n    - export CI_ORM=active_record\n    - cp Procfile.teatro Procfile\n    - cd spec/dummy_app\n    - cp ../../config/database.yml config/\n    - bundle install --without development --jobs=3 --retry=3\n    - ln -sf $PWD/public ../../public\n\n  database:\n    - bundle exec rake db:create db:migrate db:seed\n\nconfig:\n  database: postgresql\n  services:\n    - postgresql\n"
  },
  {
    "path": ".yardopts",
    "content": "--no-private\n--protected\n--markup markdown\n-\nLICENSE.md\n"
  },
  {
    "path": "Appraisals",
    "content": "# frozen_string_literal: true\n\nappraise 'rails-6.0' do\n  gem 'rails', '~> 6.0.0'\n  gem 'concurrent-ruby', '1.3.4' # Workaround for https://github.com/rails/rails/issues/54260\n  gem 'psych', '~> 3.3'\n  gem 'turbo-rails', '< 2.0.8'\n\n  group :test do\n    gem 'cancancan', ['~> 3.0', '< 3.6']\n    gem 'pundit', '~> 2.1.0'\n  end\n\n  group :active_record do\n    platforms :jruby do\n      gem 'activerecord-jdbcmysql-adapter', '~> 60.0'\n      gem 'activerecord-jdbcpostgresql-adapter', '~> 60.0'\n      gem 'activerecord-jdbcsqlite3-adapter', '~> 60.0'\n    end\n  end\n\n  group :mongoid do\n    gem 'cancancan-mongoid'\n    gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid'\n    gem 'database_cleaner-mongoid', '>= 2.0', require: false\n    gem 'kaminari-mongoid'\n    gem 'mongoid', '~> 7.0'\n    gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip'\n    gem 'shrine-mongoid', '~> 1.0'\n  end\nend\n\nappraise 'rails-6.1' do\n  gem 'rails', '~> 6.1.0'\n  gem 'concurrent-ruby', '1.3.4' # Workaround for https://github.com/rails/rails/issues/54260\n\n  group :active_record do\n    platforms :jruby do\n      gem 'activerecord-jdbcmysql-adapter', '~> 61.0'\n      gem 'activerecord-jdbcpostgresql-adapter', '~> 61.0'\n      gem 'activerecord-jdbcsqlite3-adapter', '~> 61.0'\n    end\n  end\n\n  group :mongoid do\n    gem 'cancancan-mongoid'\n    gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid'\n    gem 'database_cleaner-mongoid', '>= 2.0', require: false\n    gem 'kaminari-mongoid'\n    gem 'mongoid', '~> 7.0'\n    gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip'\n    gem 'shrine-mongoid', '~> 1.0'\n  end\nend\n\nappraise 'rails-7.0' do\n  gem 'rails', '~> 7.0.0', '7.0.8.6' # Pinning until the fix for https://github.com/basecamp/trix/issues/1209 become available in actiontext\n  gem 'concurrent-ruby', '1.3.4' # Workaround for https://github.com/rails/rails/issues/54260\n  gem 'importmap-rails', require: false\n  gem 'nokogiri', '~> 1.16.0', platform: :jruby\n\n  group :active_record do\n    platforms :ruby, :mswin, :mingw, :x64_mingw do\n      gem 'sqlite3', '~> 1.3'\n    end\n\n    platforms :jruby do\n      gem 'activerecord-jdbcmysql-adapter', '~> 70.0'\n      gem 'activerecord-jdbcpostgresql-adapter', '~> 70.0'\n      gem 'activerecord-jdbcsqlite3-adapter', '~> 70.0'\n    end\n  end\n\n  group :mongoid do\n    gem 'cancancan-mongoid'\n    gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid'\n    gem 'database_cleaner-mongoid', '>= 2.0', require: false\n    gem 'kaminari-mongoid'\n    gem 'mongoid', '~> 8.0'\n    gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip'\n    gem 'shrine-mongoid', '~> 1.0'\n  end\nend\n\nappraise 'rails-7.1' do\n  gem 'rails', '~> 7.1.0'\n  gem 'importmap-rails', require: false\n\n  group :active_record do\n    platforms :ruby, :mswin, :mingw, :x64_mingw do\n      gem 'sqlite3', '~> 1.3'\n    end\n\n    platforms :jruby do\n      gem 'activerecord-jdbcmysql-adapter', '~> 71.0'\n      gem 'activerecord-jdbcpostgresql-adapter', '~> 71.0'\n      gem 'activerecord-jdbcsqlite3-adapter', '~> 71.0'\n    end\n  end\n\n  group :mongoid do\n    gem 'cancancan-mongoid'\n    gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid'\n    gem 'database_cleaner-mongoid', '>= 2.0', require: false\n    gem 'kaminari-mongoid'\n    gem 'mongoid', '~> 8.0'\n    gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip'\n    gem 'shrine-mongoid', '~> 1.0'\n  end\nend\n\nappraise 'rails-7.2' do\n  gem 'rails', '~> 7.2.0'\n  gem 'importmap-rails', require: false\n\n  group :mongoid do\n    gem 'cancancan-mongoid'\n    gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid'\n    gem 'database_cleaner-mongoid', '>= 2.0', require: false\n    gem 'kaminari-mongoid'\n    gem 'mongoid', '~> 8.0'\n    gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip'\n    gem 'shrine-mongoid', '~> 1.0'\n  end\nend\n\nappraise 'rails-8.0' do\n  gem 'rails', '~> 8.0.0'\n  gem 'importmap-rails', require: false\n\n  group :mongoid do\n    gem 'cancancan-mongoid'\n    gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid'\n    gem 'database_cleaner-mongoid', '>= 2.0', require: false\n    gem 'kaminari-mongoid'\n    gem 'mongoid', '~> 9.0'\n    gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip'\n    gem 'shrine-mongoid', '~> 1.0'\n  end\nend\n\nappraise 'composite_primary_keys' do\n  gem 'rails', '~> 7.0.0', '7.0.8.6' # Pinning until the fix for https://github.com/basecamp/trix/issues/1209 become available in actiontext\n  gem 'concurrent-ruby', '1.3.4' # Workaround for https://github.com/rails/rails/issues/54260\n\n  group :active_record do\n    gem 'composite_primary_keys'\n\n    platforms :ruby, :mswin, :mingw, :x64_mingw do\n      gem 'sqlite3', '~> 1.3'\n    end\n  end\nend\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# RailsAdmin Changelog\n\n## [Unreleased](https://github.com/railsadminteam/rails_admin/tree/HEAD)\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.3.0...HEAD)\n\n## [3.3.0](https://github.com/railsadminteam/rails_admin/tree/v3.3.0) - 2024-12-08\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.2.1...v3.3.0)\n\n### Added\n\n- Rails 8.0 support ([#3702](https://github.com/railsadminteam/rails_admin/pull/3702))\n\n## [3.2.1](https://github.com/railsadminteam/rails_admin/tree/v3.2.0) - 2024-10-10\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.2.0...v3.2.1)\n\n### Fixed\n\n- Disable Turbo's prefetch behavior globally, to prevent custom actions unintentionally triggered ([f54a102](https://github.com/railsadminteam/rails_admin/commit/f54a102c6b0a420244ef044503944574ef1dfbd2), [#3701](https://github.com/railsadminteam/rails_admin/issues/3701))\n\n## [3.2.0](https://github.com/railsadminteam/rails_admin/tree/v3.2.0) - 2024-09-08\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.2.0.rc...v3.2.0)\n\n### Fixed\n\n- Fix polymorphic id doesn't reset properly in an edge case ([7b2ffb1](https://github.com/railsadminteam/rails_admin/commit/7b2ffb12386e06a0e6e0bace6d331fc5af989e38), [#3630](https://github.com/railsadminteam/rails_admin/pull/3630))\n\n## [3.2.0.rc](https://github.com/railsadminteam/rails_admin/tree/v3.2.0.rc) - 2024-08-25\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.2.0.beta...v3.2.0.rc)\n\n### Added\n\n- ActiveRecord 7.1 composite primary keys support ([53b89c9](https://github.com/railsadminteam/rails_admin/commit/53b89c9161e48c0f9b4ecd5f544398c9360ea50f))\n\n### Changed\n\n- Introduce SingularAssociation and CollectionAssociation to tidy up the view files ([876be11](https://github.com/railsadminteam/rails_admin/commit/876be11ec01237596b2f27e15239e86418ce7610))\n\n### Fixed\n\n- Fix to show a thumbnail of all representable ActiveStorage attachments ([#3656](https://github.com/railsadminteam/rails_admin/pull/3656), [7754ac3](https://github.com/railsadminteam/rails_admin/commit/7754ac34eb8e0af7605b2e52ae0646b17e9bb0c6))\n- Fix to detect images properly in FileUpload and MultipleFileUpload field ([35c8702](https://github.com/railsadminteam/rails_admin/commit/35c8702351aa300bddcc950d36d68b80742f5011), [#3633](https://github.com/railsadminteam/rails_admin/pull/3633))\n- Fix to reset polymorphic id selection upon type change ([#3630](https://github.com/railsadminteam/rails_admin/pull/3630), [13114e5](https://github.com/railsadminteam/rails_admin/commit/13114e5629d49eab14d58df1319eb068dacedba7))\n- Lock jQuery UI version due to incompatibility with 1.14 ([5245d5b](https://github.com/railsadminteam/rails_admin/commit/5245d5bb91691d646219b5243f3f881a0144a3fd), [#3692](https://github.com/railsadminteam/rails_admin/issues/3692))\n\n## [3.2.0.beta](https://github.com/railsadminteam/rails_admin/tree/v3.2.0.beta) - 2024-07-13\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.4...v3.2.0.beta)\n\n### Added\n\n- Allow turbo-rails 2 in gemspec ([#3671](https://github.com/railsadminteam/rails_admin/pull/3671))\n- ViteRuby integration ([#3643](https://github.com/railsadminteam/rails_admin/pull/3643), [0e12e5b](https://github.com/railsadminteam/rails_admin/commit/0e12e5b465997c14d5b7a4d500a0d4cebed21aa9))\n- Support client-side dynamic scoping ([12715f2](https://github.com/railsadminteam/rails_admin/commit/12715f2dd12d97f0676e548e4271906df424b89d), [#2934](https://github.com/railsadminteam/rails_admin/issues/2934))\n- Add support for `%-l` option to Flatpickr ([#3616](https://github.com/railsadminteam/rails_admin/pull/3616))\n\n### Changed\n\n- Handle has_one assignment on the field level, making patched has_one getters/setters unnecessary ([91737ab](https://github.com/railsadminteam/rails_admin/commit/91737ab3c2fa22cbe08aedd28770a12704fde6c7))\n\n### Fixed\n\n- Use require_relative to avoid modifying $LOAD_PATH in gemspec ([#3690](https://github.com/railsadminteam/rails_admin/pull/3690))\n- Tidy up trailing whitespace in gem post_install_message ([#3689](https://github.com/railsadminteam/rails_admin/pull/3689))\n- Fix enum filter breaking when pre-populated ([d62f604](https://github.com/railsadminteam/rails_admin/commit/d62f604cc8d7d1434f7dfe0c5aca3aaf3dc2547b), [#3651](https://github.com/railsadminteam/rails_admin/issues/3651))\n- Fix error on searching or sorting by ActiveStorage field ([dba6c4b](https://github.com/railsadminteam/rails_admin/commit/dba6c4b815fbe4aa4f62a13b660e865a89151838), [#3678](https://github.com/railsadminteam/rails_admin/issues/3678))\n- Fix to remove trailing slash from meta tags ([#3672](https://github.com/railsadminteam/rails_admin/pull/3672))\n- Fix default config path for ImportmapFormatter being misspelled ([#3676](https://github.com/railsadminteam/rails_admin/pull/3676))\n- Fix table names not quoted properly on sorting ([#3652](https://github.com/railsadminteam/rails_admin/pull/3652), [#1631](https://github.com/railsadminteam/rails_admin/issues/1631))\n- Fix ActiveStorage/ActionText detection less likely to cause false positives ([073b809](https://github.com/railsadminteam/rails_admin/commit/073b809853b6bc231841e3f8dd9d35875220c616), [#3659](https://github.com/railsadminteam/rails_admin/issues/3659))\n- Fix boolean fields in a Mongoid embedded document fails to be updated ([#3555](https://github.com/railsadminteam/rails_admin/pull/3555), [#3554](https://github.com/railsadminteam/rails_admin/issues/3554))\n- Fix wrongly referring to `:update_only` in nested fields ([#3649](https://github.com/railsadminteam/rails_admin/pull/3649))\n- Fix to use HTML `q` element for better localization support ([#3636](https://github.com/railsadminteam/rails_admin/pull/3636))\n- Fix `is_blank` and `is_present` filters breaking for uuid columns ([#3629](https://github.com/railsadminteam/rails_admin/pull/3629), [#3669](https://github.com/railsadminteam/rails_admin/issues/3669))\n- Fix polymorphic association target classes not set correctly in subclasses ([2a89ebc](https://github.com/railsadminteam/rails_admin/commit/2a89ebcfa96243697988f6570b9c9be19a7a01b5), [#3631](https://github.com/railsadminteam/rails_admin/issues/3631))\n\n### Security\n\n- Validate `return_to` param using `request.base_url` to prevent arbitrary redirection ([#3627](https://github.com/railsadminteam/rails_admin/pull/3627))\n\n## [3.1.4](https://github.com/railsadminteam/rails_admin/tree/v3.1.4) - 2024-07-09\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.3...v3.1.4)\n\n### Fixed\n\n- Fix [32f91e4](https://github.com/railsadminteam/rails_admin/commit/32f91e4b49205e44d3931c2e36d9f7273384a250) broke fields with HTML tags ([758d249](https://github.com/railsadminteam/rails_admin/commit/758d249d950062be6840f9c96e2a286e02b92a1e), [#3686](https://github.com/railsadminteam/rails_admin/issues/3686#issuecomment-2215491140))\n\n## [3.1.3](https://github.com/railsadminteam/rails_admin/tree/v3.1.3) - 2024-07-06\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.2...v3.1.3)\n\n### Fixed\n\n- Fix bson 5.0 compatibility ([13da4f0](https://github.com/railsadminteam/rails_admin/commit/13da4f0191f5185dadecdfe9e6fc9ca808f7f73d))\n- Fix Importmap 2.0 compatibility ([bd0cf97](https://github.com/railsadminteam/rails_admin/commit/bd0cf97530d93dc66577e5d1ea0da2ebf3b57737))\n\n### Security\n\n- Fix XSS vulnerability in the list view ([b5a287d](https://github.com/railsadminteam/rails_admin/commit/b5a287d82e2cbd1737a1a01e11ede2911cce7fef), [GHSA-8qgm-g2vv-vwvc](https://github.com/railsadminteam/rails_admin/security/advisories/GHSA-8qgm-g2vv-vwvc))\n\n## [3.1.2](https://github.com/railsadminteam/rails_admin/tree/v3.1.2) - 2023-03-23\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.1...v3.1.2)\n\n### Fixed\n\n- Fix install failing with importmap setup ([aca22b6](https://github.com/railsadminteam/rails_admin/commit/aca22b6ba1eca1ac618525334cf14fc946e1c99e), [#3609](https://github.com/railsadminteam/rails_admin/issues/3609))\n- Fix to show non-eager-loaded models which are explicitly configured ([87c9d5b](https://github.com/railsadminteam/rails_admin/commit/87c9d5bc5b6ffb423e72054b3cfe8f949c12c178), [#3604](https://github.com/railsadminteam/rails_admin/issues/3604))\n- Fix `rails_admin.dom_ready` event not triggered with jQuery `on` ([2ee43de](https://github.com/railsadminteam/rails_admin/commit/2ee43deb1fa8d3a9e3ea0e589c1687d684e19ad6), [33773d7](https://github.com/railsadminteam/rails_admin/commit/33773d7f8dd43eeb0f6a7c125c4bee170132e5d2), [#3600](https://github.com/railsadminteam/rails_admin/discussions/3600))\n- Restore caching in RailsAdmin::Config::Model#excluded? ([#3587](https://github.com/railsadminteam/rails_admin/pull/3587))\n- Optimize/simplify viable_models file path to class name logic ([#3589](https://github.com/railsadminteam/rails_admin/pull/3589))\n\n## [3.1.1](https://github.com/railsadminteam/rails_admin/tree/v3.1.1) - 2022-12-18\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.0...v3.1.1)\n\n### Changed\n\n- Relax Font-Awesome dependency to allow Webpacker users to stay on 5.x ([3a7f348](https://github.com/railsadminteam/rails_admin/commit/3a7f34875248e446b48fd76870f0c337fee6dcf9), [#3565](https://github.com/railsadminteam/rails_admin/issues/3565))\n\n### Removed\n\n- Remove unused glphyicon assets ([#3578](https://github.com/railsadminteam/rails_admin/pull/3578))\n\n### Fixed\n\n- Simplify uses of defined? ([#3561](https://github.com/railsadminteam/rails_admin/pull/3561))\n- Define jQuery object in separate file to support esbuild ([#3571](https://github.com/railsadminteam/rails_admin/pull/3571))\n- Fix filter box being duplicated on browser back ([c6b1893](https://github.com/railsadminteam/rails_admin/commit/c6b18934cff3db0768836d799ee1bea54045709c), [#3570](https://github.com/railsadminteam/rails_admin/issues/3570))\n- Fix sidebar menu expanding horizontally, preventing vertical scroll ([9997c10](https://github.com/railsadminteam/rails_admin/commit/9997c1095066aaac39afb27bf8de705cf6ccb1ef), [#3564](https://github.com/railsadminteam/rails_admin/issues/3564))\n\n## [3.1.0](https://github.com/railsadminteam/rails_admin/tree/v3.1.0) - 2022-11-06\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.0.rc2...v3.1.0)\n\n### Fixed\n\n- Fix to use defer instead of async to ensure script loading order ([2a40976](https://github.com/railsadminteam/rails_admin/commit/2a409764b13a4e23fc848725c604d318e3375484), [#3513](https://github.com/railsadminteam/rails_admin/issues/3513))\n- Improve filter method select box appearance ([#3559](https://github.com/railsadminteam/rails_admin/pull/3559))\n\n## [3.1.0.rc2](https://github.com/railsadminteam/rails_admin/tree/v3.1.0.rc2) - 2022-10-02\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.0.rc...v3.1.0.rc2)\n\n### Fixed\n\n- Fix sidebar style broken in attempt to support Bootstrap 5.2 ([d7abba4](https://github.com/railsadminteam/rails_admin/commit/d7abba4e8a2e380b4d7f8fb3b37302300af63de5), [#3553](https://github.com/railsadminteam/rails_admin/issues/3553))\n\n## [3.1.0.rc](https://github.com/railsadminteam/rails_admin/tree/v3.1.0.rc) - 2022-09-22\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.1.0.beta...v3.1.0.rc)\n\n### Added\n\n- Add ability to limit filter operators ([be9a75e](https://github.com/railsadminteam/rails_admin/commit/be9a75e504edd9a754157a4ddba590e8a5d14149))\n- Support filtering has_one associations ([9657774](https://github.com/railsadminteam/rails_admin/commit/9657774b423912357d8ad8a476b644bb4e36dc30))\n- Add ability to set default order of PaperTrail versions ([a1c4c67](https://github.com/railsadminteam/rails_admin/commit/a1c4c673041642ae2a2aa07e3f0555e17be9d940), [#3095](https://github.com/railsadminteam/rails_admin/pull/3095))\n- Add block-style DSL support for extension adapters ([951b708](https://github.com/railsadminteam/rails_admin/commit/951b70878cb007d54b4a7aeadd708d4c7668727b))\n- Make sidebar navigation collapsible ([e8cb8ed](https://github.com/railsadminteam/rails_admin/commit/e8cb8edd39246bf75ed72295b7832faf5056367c), [#3198](https://github.com/railsadminteam/rails_admin/pull/3198))\n- Add ability to show a help text under the search box ([94f16fb](https://github.com/railsadminteam/rails_admin/commit/94f16fb5fdfdaa867173e95820583a68e5a306c5))\n- Support for ActiveStorage direct uploads ([e13c7e2](https://github.com/railsadminteam/rails_admin/commit/e13c7e23f789ed2a575eff01b75e52a41cc930b7), [#3296](https://github.com/railsadminteam/rails_admin/issues/3296))\n\n### Changed\n\n- Load ActionText assets statically to enable full-featured setup ([458d0fb](https://github.com/railsadminteam/rails_admin/commit/458d0fb56d79d4fa0a252ad1ca715fd0a3b4b900), [#3251](https://github.com/railsadminteam/rails_admin/issues/3251), [#3386](https://github.com/railsadminteam/rails_admin/issues/3386))\n- Change ES Module processing not to affect non-RailsAdmin assets ([f8219bf](https://github.com/railsadminteam/rails_admin/commit/f8219bf3bc508c5e42f5d044cf6355a56726f8b2))\n- Change RailsAdmin initialization process to evaluate the config block immediately but load constants lazily ([#3541](https://github.com/railsadminteam/rails_admin/pull/3541), [33e9214](https://github.com/railsadminteam/rails_admin/commit/33e92147214975cddace61737cbbde3117663efe))\n- Restore the loading indicator back ([32e6b14](https://github.com/railsadminteam/rails_admin/commit/32e6b1463ecf66b38e6fdc7924426d9753d71eab), [b9ee7f0](https://github.com/railsadminteam/rails_admin/commit/b9ee7f0c202abc7c09726bdaa28536e7ec25127e), [#3500](https://github.com/railsadminteam/rails_admin/issues/3500))\n\n### Fixed\n\n- Fix Bootstrap 5.2 compatibility ([ef76fce](https://github.com/railsadminteam/rails_admin/commit/ef76fcea0b23aed04f6568448cd157ccc9ba30a0))\n- Fix filtering select widget options being empty on browser back ([3cffc00](https://github.com/railsadminteam/rails_admin/commit/3cffc0002079bc9d515dc0f3b31513c7166aa2b9))\n- Fix RailsAdmin widgets not activated after a validation error ([a604da5](https://github.com/railsadminteam/rails_admin/commit/a604da5670378e57da7b5492afad40e4f4ad083d))\n- Fix export action didn't use export section for eager loading ([4cc3f30](https://github.com/railsadminteam/rails_admin/commit/4cc3f304cc0bc4a7dbaf41a6e4e12ecbdbba6e22), [#1954](https://github.com/railsadminteam/rails_admin/issues/1954))\n- Fix Dart Sass 2.0 division deprecations ([#3544](https://github.com/railsadminteam/rails_admin/pull/3544), [3a177c2](https://github.com/railsadminteam/rails_admin/commit/3a177c2e8c1b1d782186ee5bbb3c0d44cc4c0060))\n- Fix unable to focus elements on modals opened from remote forms ([#3539](https://github.com/railsadminteam/rails_admin/pull/3539), [#3538](https://github.com/railsadminteam/rails_admin/issues/3538))\n- Improve pagination appearance on smaller screens ([a2e366e](https://github.com/railsadminteam/rails_admin/commit/a2e366e8839c9046b9f9fde219875a05bc1a66bb), [#3516](https://github.com/railsadminteam/rails_admin/issues/3516))\n- Fix the value of submit buttons being lost on submission ([60e1150](https://github.com/railsadminteam/rails_admin/commit/60e115053ea34fa42c3099464106cf6e58dbfa03), [#3513](https://github.com/railsadminteam/rails_admin/issues/3513))\n- Fix breaking with a has_and_belongs_to_many association with scope given ([c2bf6db](https://github.com/railsadminteam/rails_admin/commit/c2bf6db41a97b46741bc41b56fd9700c8bdfc9e4), [#2067](https://github.com/railsadminteam/rails_admin/issues/2067))\n- Fix nested fields don't toggle properly after pushing 'Add a new ...' button ([d1f1154](https://github.com/railsadminteam/rails_admin/commit/d1f115425c4a8d119fdeb37802fe472ae278918d), [#3528](https://github.com/railsadminteam/rails_admin/issues/3528))\n\n## [3.1.0.beta](https://github.com/railsadminteam/rails_admin/tree/v3.1.0.beta) - 2022-06-20\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.0.0...v3.1.0.beta)\n\n### Added\n\n- Support Importmap and Webpack, via [importmap-rails](https://github.com/rails/importmap-rails) / [jsbundling-rails](https://github.com/rails/jsbundling-rails) and [cssbundling-rails](https://github.com/rails/cssbundling-rails) ([#3488](https://github.com/railsadminteam/rails_admin/pull/3488))\n- Support [Composite Primary Keys](https://github.com/composite-primary-keys/composite_primary_keys) gem ([#3527](https://github.com/railsadminteam/rails_admin/pull/3527))\n- Allow configuration of Navbar css class ([126f7ac](https://github.com/railsadminteam/rails_admin/commit/126f7ac79b2ce7846cbbed7bbca1cc26dfe46fb6), [#3507](https://github.com/railsadminteam/rails_admin/issues/3507))\n\n### Changed\n\n- Update vendorized jQuery to 3.6.0 ([#3524](https://github.com/railsadminteam/rails_admin/pull/3524))\n- Enable frozen string literals across the project ([#3483](https://github.com/railsadminteam/rails_admin/pull/3483))\n\n### Fixed\n\n- Fix edit user link in the top navigation pointing to wrong URL ([#3531](https://github.com/railsadminteam/rails_admin/pull/3531))\n- Fix MultipleActiveStorage field deleting previous attachments when updating a record in Rails 7.0 ([974c54a](https://github.com/railsadminteam/rails_admin/commit/974c54a2a3372690ca189f6e7e90ce365bcd4ff5), [#3520](https://github.com/railsadminteam/rails_admin/issues/3520))\n- Fix remote form submission breaking when used with HTTP/2 ([#3515](https://github.com/railsadminteam/rails_admin/pull/3515))\n- Fix to maintain 2.x hover / active behavior for side navigation links ([#3511](https://github.com/railsadminteam/rails_admin/pull/3511))\n- Fix default sort by behavior when `list.sort_by` points to a field with a table reference for `:sortable` ([#3509](https://github.com/railsadminteam/rails_admin/pull/3509), [9959925](https://github.com/railsadminteam/rails_admin/commit/9959925e49812d6fdaf7341ede4b1d66d926e8d8))\n- Fix to insert whitespace after sidebar navigation icon to maintain visual consistency ([#3504](https://github.com/railsadminteam/rails_admin/pull/3504))\n- Fix orderable multiselect buttons not rendered correctly ([#3506](https://github.com/railsadminteam/rails_admin/pull/3506))\n- Fix to use badges instead of labels, which are removed in Bootstrap 5 ([#3503](https://github.com/railsadminteam/rails_admin/pull/3503))\n\n## [3.0.0](https://github.com/railsadminteam/rails_admin/tree/v3.0.0) - 2022-03-21\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.0.0.rc4...v3.0.0)\n\n### Fixed\n\n- Fix table sorting not working ([83a0c88](https://github.com/railsadminteam/rails_admin/commit/83a0c889f1de38a0b24c412b0f0f7484add86b29), [#3497](https://github.com/railsadminteam/rails_admin/issues/3497))\n- Fix reset button by the query box not working ([4a583e9](https://github.com/railsadminteam/rails_admin/commit/4a583e924c5bef6bfc46d6a49ab751c2323ba23e))\n\n## [3.0.0.rc4](https://github.com/railsadminteam/rails_admin/tree/v3.0.0.rc4) - 2022-03-13\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.0.0.rc3...v3.0.0.rc4)\n\n### Added\n\n- Instruct users on potential issues with npm package installation ([2b0594c](https://github.com/railsadminteam/rails_admin/commit/2b0594c6824eb4eed217cbab9477639b61eb99db), [c7a74f1](https://github.com/railsadminteam/rails_admin/commit/c7a74f1ce7a040b8c87b24fe1907ddd9088bf1e5))\n\n### Changed\n\n- Upgrade vendorized Flatpickr to 4.6.11 ([7f8c831](https://github.com/railsadminteam/rails_admin/commit/7f8c831b9aa407987ba89191c21040e2e72e366e))\n\n### Fixed\n\n- Fix not utilizing full browser width after Bootstrap 5 upgrade ([#3493](https://github.com/railsadminteam/rails_admin/pull/3493))\n- Fix the style for show views broken on Bootstrap 5 upgrade ([#3491](https://github.com/railsadminteam/rails_admin/pull/3491))\n- Fix Pundit 2.2 deprecation for not using Pundit::Authorization ([e38eb46](https://github.com/railsadminteam/rails_admin/commit/e38eb46ffe79cd866c34b837dd4cfbb65361558f))\n- Fix JS issues when navigating across the main app and RailsAdmin ([eb4a185](https://github.com/railsadminteam/rails_admin/commit/eb4a18558e9d8c69aeea3fd733f5dc251f3f79f9), [#3484](https://github.com/railsadminteam/rails_admin/pull/3484))\n\n## [3.0.0.rc3](https://github.com/railsadminteam/rails_admin/tree/v3.0.0.rc3) - 2022-02-27\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.0.0.rc2...v3.0.0.rc3)\n\n### Fixed\n\n- Fix the style of list scope tabs ([#3477](https://github.com/railsadminteam/rails_admin/pull/3477))\n- Fix rake tasks executed twice ([7d56cd6](https://github.com/railsadminteam/rails_admin/commit/7d56cd6af2d468cca44af5211559af0e744f5cb4))\n- Fix the style of the header user link when show_gravatar is false ([#3475](https://github.com/railsadminteam/rails_admin/pull/3475))\n- Fix 'Cancel' button for delete/bulk_delete action also didn't work ([1fa8486](https://github.com/railsadminteam/rails_admin/commit/1fa8486ead39596e9e0ac62a945fb0aed63929a8), [#3468](https://github.com/railsadminteam/rails_admin/issues/3468))\n- Fix failing to export after introducing Turbo Drive ([c749d93](https://github.com/railsadminteam/rails_admin/commit/c749d939e29434937e8558bcb1f3e219fe98c69d), [#3461 (comment)](https://github.com/railsadminteam/rails_admin/pull/3461#issuecomment-1048588801))\n\n## [3.0.0.rc2](https://github.com/railsadminteam/rails_admin/tree/v3.0.0.rc2) - 2022-02-20\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.0.0.rc...v3.0.0.rc2)\n\n### Added\n\n- Some improvements to make the upgrade process more friendlier ([#3471](https://github.com/railsadminteam/rails_admin/pull/3471), [3771542](https://github.com/railsadminteam/rails_admin/commit/377154268257d3753093dcd3dd2fd79b7438b9aa), [3b04a96](https://github.com/railsadminteam/rails_admin/commit/3b04a9616169d568b1a6cee26becf9bfea0ee386))\n\n### Fixed\n\n- Fix 'Save and add another', 'Save and edit', 'Cancel' buttons didn't work right ([ac0a563](https://github.com/railsadminteam/rails_admin/commit/ac0a563a0bf91bf33c693e19717148ed77f843fd), [#3468](https://github.com/railsadminteam/rails_admin/issues/3468))\n- Fix failing to precompile assets when the database connection is unavailable ([#3470](https://github.com/railsadminteam/rails_admin/pull/3470), [#3469](https://github.com/railsadminteam/rails_admin/issues/3469))\n- Fix custom theme overrides not working ([3d7f3b3](https://github.com/railsadminteam/rails_admin/commit/3d7f3b33a1ca6fabbd8606bb178babae930cce25), [#3466](https://github.com/railsadminteam/rails_admin/issues/3466))\n\n## [3.0.0.rc](https://github.com/railsadminteam/rails_admin/tree/v3.0.0.rc) - 2022-02-06\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.0.0.beta2...v3.0.0.rc)\n\n### Added\n\n- Support Mongoid's Storage Field Names ([cefa23c](https://github.com/railsadminteam/rails_admin/commit/cefa23c9d23d06dc1134228e142e6f0aa4655c54), [#1745](https://github.com/railsadminteam/rails_admin/issues/1745))\n- Allow save/delete operations to be disabled based on an object's `#read_only?` status ([9cd7541](https://github.com/railsadminteam/rails_admin/commit/9cd7541a2e6af4ae4941b200840a1474baeb2f06), [#1684](https://github.com/railsadminteam/rails_admin/issues/1684))\n- Allow customizing model's last created time ([d6d380a](https://github.com/railsadminteam/rails_admin/commit/d6d380a02e955c3b14ff7dc30f1809a2a6cd0f47), [#3010](https://github.com/railsadminteam/rails_admin/issues/3010))\n- Add ability to hide the dashboard history section ([#3189](https://github.com/railsadminteam/rails_admin/pull/3189))\n- Add model scope configuration option, which enables 'unscoped' mode ([8d905f9](https://github.com/railsadminteam/rails_admin/commit/8d905f9e2f1102e8addf324b496720e3fd47bf1d), [#1348](https://github.com/railsadminteam/rails_admin/issues/1348))\n\n### Changed\n\n- Switch from pjax to Turbo Drive, due to pjax's low maintenance activity ([#3461](https://github.com/railsadminteam/rails_admin/pull/3461), [#3435](https://github.com/railsadminteam/rails_admin/pull/3435))\n- Upgrade Bootstrap to 5.1.3 ([#3455](https://github.com/railsadminteam/rails_admin/pull/3455), [#3083](https://github.com/railsadminteam/rails_admin/issues/3083))\n- Switch datetime picker library to Flatpickr ([#3455](https://github.com/railsadminteam/rails_admin/pull/3455))\n\n### Removed\n\n- Drop support for Ruby 2.5 ([#3430](https://github.com/railsadminteam/rails_admin/pull/3430))\n- Remove Sections::List#sort_reverse because of having very limited usecase ([0c7bc61](https://github.com/railsadminteam/rails_admin/commit/0c7bc6124a189e5307f2bd1f960dd06495932d10), [#1181](https://github.com/railsadminteam/rails_admin/issues/1181))\n\n### Fixed\n\n- Fix failing to detect encoding with JDBC MySQL adapter ([0dfe2e4](https://github.com/railsadminteam/rails_admin/commit/0dfe2e4d1301cc353f972b28ab19554a53cad482))\n- Fix unable to start app when using redis-session-store ([#3462](https://github.com/railsadminteam/rails_admin/pull/3462))\n- Fix ActiveRecord ObjectExtension has_one setter breaks with custom primary key class ([0e2e0e4](https://github.com/railsadminteam/rails_admin/commit/0e2e0e4e24328a063813a3a5266a15faee7960c8), [#3460](https://github.com/railsadminteam/rails_admin/issues/3460))\n- Fix inheritance of parent_controller not updated properly when controllers were eagerly loaded ([#3458](https://github.com/railsadminteam/rails_admin/pull/3458))\n- Fix to retrieve actions correctly in the action `#bulk_action` ([#3407](https://github.com/railsadminteam/rails_admin/pull/3407))\n- Fix issue when RailsAdmin::MainController needs to dispatch a method call using `#respond_to_missing?` ([da51b91](https://github.com/railsadminteam/rails_admin/commit/da51b91f712b235c0c6e2a120724fcb31ff28168), [#3454](https://github.com/railsadminteam/rails_admin/issues/3454))\n- Fix modal foreign keys are not prepopulated unless the association inverse_of is configured ([75504d0](https://github.com/railsadminteam/rails_admin/commit/75504d08ee6197a3a2c72a56ea30f01272b1d28b), [#2585](https://github.com/railsadminteam/rails_admin/issues/2585))\n\n## [3.0.0.beta2](https://github.com/railsadminteam/rails_admin/tree/v3.0.0.beta2) - 2021-12-25\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v3.0.0.beta...v3.0.0.beta2)\n\n### Fixed\n\n- Fix NameError 'uninitialized constant RailsAdmin::Version' on install ([d2ad520](https://github.com/railsadminteam/rails_admin/commit/d2ad5209f98d8678c6317b49f13727b8605048b3), [#3452](https://github.com/railsadminteam/rails_admin/issues/3452))\n\n## [3.0.0.beta](https://github.com/railsadminteam/rails_admin/tree/v3.0.0.beta) - 2021-12-20\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v2.2.1...v3.0.0.beta)\n\n### Added\n\n- Rails 7.0.0 support ([011b9ae](https://github.com/railsadminteam/rails_admin/commit/011b9aea12d2c3a5e8654786e49071254baacf18), [670d803](https://github.com/railsadminteam/rails_admin/commit/670d803c262429600c6eb7f59f8b36aa145081e5))\n- Webpacker support ([#3414](https://github.com/railsadminteam/rails_admin/pull/3414))\n- Add #link_target to action configuration ([#3419](https://github.com/railsadminteam/rails_admin/pull/3419))\n- Add not like (=does not contain) operator ([#3410](https://github.com/railsadminteam/rails_admin/pull/3410))\n- Support for PostgreSQL citext data type ([#3413](https://github.com/railsadminteam/rails_admin/pull/3413), [#2177](https://github.com/railsadminteam/rails_admin/issues/2177))\n- Allow #configure to handle multiple fields for a section at once ([#3406](https://github.com/railsadminteam/rails_admin/pull/3406), [#2667](https://github.com/railsadminteam/rails_admin/issues/2667))\n- Add has_one id setters/getters, eliminating the need for explicitly defining them ([42f0a5f](https://github.com/railsadminteam/rails_admin/commit/42f0a5f5aac4b7481dcd4950803d12077b598ce5), [#2625](https://github.com/railsadminteam/rails_admin/issues/2625))\n- Support for Mongoid's has_and_belongs_to_many custom primary_key ([3f67637](https://github.com/railsadminteam/rails_admin/commit/3f676371ce7fc088220095afa12d3e20c2c6123a), [#3097](https://github.com/railsadminteam/rails_admin/pull/3097))\n- Support for eager-loading arbitrary associations ([4404758](https://github.com/railsadminteam/rails_admin/commit/44047580b7d536a84a92c173a3bd00dc9d211399), [#2928](https://github.com/railsadminteam/rails_admin/issues/2928))\n- Support for nullable boolean field ([7583369](https://github.com/railsadminteam/rails_admin/commit/7583369a1d1763e542d36930a968726425cacb6c), [#3145](https://github.com/railsadminteam/rails_admin/issues/3145))\n- Support for configuration reload in development mode ([e4ae669](https://github.com/railsadminteam/rails_admin/commit/e4ae6698e52e56a1cefdf5c4097b29b8306f21e2), [#2726](https://github.com/railsadminteam/rails_admin/issues/2726), [08f50aa](https://github.com/railsadminteam/rails_admin/commit/08f50aabc1922aeb289ced4ccbe9f983bc1aaa89), [#3420](https://github.com/railsadminteam/rails_admin/issues/3420))\n- Add 'No objects found' placeholder in filtering-select as well ([7e3a1a6](https://github.com/railsadminteam/rails_admin/commit/7e3a1a632811a917f2cbd8dbe471861bc0a1ac85), [#3332](https://github.com/railsadminteam/rails_admin/issues/3332))\n- Add inline_edit to HasManyAssociation as well ([798ab1b](https://github.com/railsadminteam/rails_admin/commit/798ab1b6ae400f2b853441a9fa48f8e7ad24208d), [#1911](https://github.com/railsadminteam/rails_admin/issues/1911))\n- Add hover highlight to the list table for better visibility ([#3221](https://github.com/railsadminteam/rails_admin/pull/3221))\n- Add ability to show disabled actions, as well as completely hiding ([6c877ea](https://github.com/railsadminteam/rails_admin/commit/6c877eac1a052881b2d4950a44d41f7fd77b044f), [#1765](https://github.com/railsadminteam/rails_admin/issues/1765))\n- Add the message 'no records found' when a list is empty ([#3365](https://github.com/railsadminteam/rails_admin/pull/3365), [a5fe6f8](https://github.com/railsadminteam/rails_admin/commit/a5fe6f806498975a91ae11544ce21310592774a2), [#3329](https://github.com/railsadminteam/rails_admin/issues/3329))\n- Add a way to clear belongs_to selection using mouse ([ac3fe35](https://github.com/railsadminteam/rails_admin/commit/ac3fe35b65e858a3b528a523e1b6fbeafe1d359b), [#2090](https://github.com/railsadminteam/rails_admin/issues/2090))\n- Add HTML5 validation for float-like field types ([#3378](https://github.com/railsadminteam/rails_admin/pull/3378), [#3289](https://github.com/railsadminteam/rails_admin/issues/3289))\n\n### Changed\n\n- Remove horizontal pagination and always use sidescroll view for list action table ([d51e943](https://github.com/railsadminteam/rails_admin/commit/d51e94314de4b510df0767a695d5953bb7b3fad5))\n- Replace image assets with Font Awesome icons ([a0a568b](https://github.com/railsadminteam/rails_admin/commit/a0a568bc866158382b52ec24639699695146794c))\n- Switch templates from HAML to ERB ([#3425](https://github.com/railsadminteam/rails_admin/pull/3425), [#3439](https://github.com/railsadminteam/rails_admin/pull/3439), [#3173](https://github.com/railsadminteam/rails_admin/issues/3173))\n- Rewrite some JavaScript code not to use jQuery ([#3416](https://github.com/railsadminteam/rails_admin/pull/3416), [#3417](https://github.com/railsadminteam/rails_admin/pull/3417))\n- Upgrade FontAwesome to 5.15.4 ([cb1ac73](https://github.com/railsadminteam/rails_admin/commit/cb1ac732c4df85cc082c4e40f2c8a7d144ceb9f2))\n- Stop using AbstractObject and use raw model instances with extension ([af88091](https://github.com/railsadminteam/rails_admin/commit/af88091d11590dc95df4866c62fba0c49a7bb9a8), [#2847](https://github.com/railsadminteam/rails_admin/issues/2847))\n- Switch from jquery_ujs to rails-ujs ([#3390](https://github.com/railsadminteam/rails_admin/pull/3390), [dea63f4](https://github.com/railsadminteam/rails_admin/commit/dea63f49ee18644ee5e8dee1fb57e0c742d27a97))\n- Make colorpicker field use HTML5 native color picker ([#3387](https://github.com/railsadminteam/rails_admin/pull/3387))\n- Change to use ISO 8601 time format for browser-server communication, instead of localized value ([01e8d5f](https://github.com/railsadminteam/rails_admin/commit/01e8d5fc8ec94e68af6fdbd80759a751cd83f74a), [#3344](https://github.com/railsadminteam/rails_admin/issues/3344))\n\n### Removed\n\n- Remove dependency for builder and remotipart ([#3427](https://github.com/railsadminteam/rails_admin/pull/3427), [58b76d1](https://github.com/railsadminteam/rails_admin/commit/58b76d1e66ec06b752567da9c118f611105ff39f))\n- Remove capitalization helper, letting I18n to perform necessary transformation ([#3396](https://github.com/railsadminteam/rails_admin/pull/3396))\n- Remove jQuery Migrate ([#3389](https://github.com/railsadminteam/rails_admin/pull/3389), [b385d4d](https://github.com/railsadminteam/rails_admin/commit/b385d4d50f372de65d8c6c33a4b8256403894483))\n- Remove the legacy history adapter([#3374](https://github.com/railsadminteam/rails_admin/issues/3374), [b627580](https://github.com/railsadminteam/rails_admin/commit/b62758039308872e7abe91a51715e1608bfd0915))\n- Drop support for Ruby < 2.5 and Rails 5.x([decf428](https://github.com/railsadminteam/rails_admin/commit/decf4280183b8b6a453aa802942fc825524c2f13), [17e20b6](https://github.com/railsadminteam/rails_admin/commit/17e20b6daef1708598ab8cff5678501f8bac4709))\n\n### Fixed\n\n- Reduce object allocations when rendering main navigation menu ([#3412](https://github.com/railsadminteam/rails_admin/pull/3412))\n- Fix N+1 queries for ActiveStorage attachments ([e4d5b2f](https://github.com/railsadminteam/rails_admin/commit/e4d5b2f3bece0f5f3e5f588e20e52031ad33e124), [#3282](https://github.com/railsadminteam/rails_admin/issues/3282))\n- Fix to convert DateTime format for Moment.js as much as possible ([6d5c049](https://github.com/railsadminteam/rails_admin/commit/6d5c049124d0b390f4612e8e6524f00500afe52e), [#2736](https://github.com/railsadminteam/rails_admin/issues/2736), [#3009](https://github.com/railsadminteam/rails_admin/issues/3009))\n- Fix config.parent_controller to work after the class loading ([5bd9805](https://github.com/railsadminteam/rails_admin/commit/5bd980564a565906a6fda87d2ef31590d3e3b0a5), [#2790](https://github.com/railsadminteam/rails_admin/issues/2790))\n- Fix NoMethodError when Mongoid's raise_not_found_error is false ([973bd8e](https://github.com/railsadminteam/rails_admin/commit/973bd8e50591a538841575c33b6221706481dae3), [#2623](https://github.com/railsadminteam/rails_admin/issues/2623))\n- Fix NoMethodError \"undefined method 'has_one_attached'\" ([e4ae669](https://github.com/railsadminteam/rails_admin/commit/e4ae6698e52e56a1cefdf5c4097b29b8306f21e2), [#3025](https://github.com/railsadminteam/rails_admin/issues/3025))\n- Fix NoMethodError \"undefined method `label' for nil:NilClass\" on export ([f2104b5](https://github.com/railsadminteam/rails_admin/commit/f2104b595930491a18ede44c9e1a8c881a0316b8), [#1685](https://github.com/railsadminteam/rails_admin/issues/1685))\n- Fix Kaminari's custom param_name was not used in history_index and history_show ([#3227](https://github.com/railsadminteam/rails_admin/pull/3227), [#3400](https://github.com/railsadminteam/rails_admin/pull/3400))\n- Fix Gravater and email were not shown when the current user is not editable ([bd44929](https://github.com/railsadminteam/rails_admin/commit/bd449292088cb68aad22b282b6344778862187e5), [#3237](https://github.com/railsadminteam/rails_admin/issues/3237))\n- Fix RailsAdmin::Config.reset didn't clear the effect of previous included_models/excluded_models ([1190d51](https://github.com/railsadminteam/rails_admin/commit/1190d510ee73949af618bd279e4712f1be4550b6), [#3305](https://github.com/railsadminteam/rails_admin/issues/3305))\n- Fix duplication of filtering-multiselect on browser back ([3c10b09](https://github.com/railsadminteam/rails_admin/commit/3c10b0918b65e64624f06ebd5e402181f478cc64), [#3211](https://github.com/railsadminteam/rails_admin/issues/3211))\n- Fix no error message is shown on failure with dependent: :restrict_with_error ([bf353cc](https://github.com/railsadminteam/rails_admin/commit/bf353cc76d6e56d511e9c5a87d0ffbd83669e3f2), [#3323](https://github.com/railsadminteam/rails_admin/issues/3223))\n- Fix read-only associations are shown empty if it has no value ([7580f33](https://github.com/railsadminteam/rails_admin/commit/7580f3366a6e4a16b439de7fd64860fe26628ad7), [#2681](https://github.com/railsadminteam/rails_admin/issues/2681))\n- Fix hidden fields taking up some space ([5aaee51](https://github.com/railsadminteam/rails_admin/commit/5aaee5153441fd82854a998ac02ebbe303b82bf2), [#3380](https://github.com/railsadminteam/rails_admin/issues/3380))\n- Fix to show validation errors in modals ([f67defb](https://github.com/railsadminteam/rails_admin/commit/f67defb55ad9d1a1fe8428029c947bcd00b5ce8a), [#1735](https://github.com/railsadminteam/rails_admin/issues/1735))\n- Fix image file detection by using Mime::Type ([#3398](https://github.com/railsadminteam/rails_admin/pull/3398), [#3239](https://github.com/railsadminteam/rails_admin/issues/3239))\n- Fix 'no objects' message not showing up in filtering-multiselect widget ([aa5545c](https://github.com/railsadminteam/rails_admin/commit/aa5545c928ce0de80142966c19b64be76d88286f))\n- Fix 'Delete Image' translation does not work well in some languages ([#3382](https://github.com/railsadminteam/rails_admin/pull/3382), [#3260](https://github.com/railsadminteam/rails_admin/issues/3260))\n- Fix polymorphic associations don't work with namespaced classes ([#3377](https://github.com/railsadminteam/rails_admin/pull/3377), [#3376](https://github.com/railsadminteam/rails_admin/issues/3376))\n- Fix Boolean pretty_value to include default fallback ([#3379](https://github.com/railsadminteam/rails_admin/pull/3379))\n- Fix history#index not supporting models with custom version classes ([ed19f9e](https://github.com/railsadminteam/rails_admin/commit/ed19f9e793b91de1c2bc9133e026b0396e6ec777))\n- Fix models stored in eager_load_paths are not picked up by #viable_models ([#3373](https://github.com/railsadminteam/rails_admin/issues/3373), [238f18e](https://github.com/railsadminteam/rails_admin/commit/238f18ee2386f9858670b7995dcb628b8fe6bde9))\n- Fix polymorphic associations don't work with namespaced classes([#3376](https://github.com/railsadminteam/rails_admin/issues/3376))\n\n## [2.2.1](https://github.com/railsadminteam/rails_admin/tree/v2.2.0) - 2021-08-08\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v2.2.0...v2.2.1)\n\n### Fixed\n\n- Fix missing select options for single-select enum filters([#3372](https://github.com/railsadminteam/rails_admin/pull/3372))\n\n## [2.2.0](https://github.com/railsadminteam/rails_admin/tree/v2.2.0) - 2021-07-24\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v2.1.1...v2.2.0)\n\n### Added\n\n- Support for PaperTrail's alternative versions association name([#3354](https://github.com/railsadminteam/rails_admin/pull/3354))\n\n### Changed\n\n- Update jQuery to 3.x with introducing jQuery.migrate([#3348](https://github.com/railsadminteam/rails_admin/pull/3348), [973dee06](https://github.com/railsadminteam/rails_admin/commit/973dee065938a58d1aef4119a4bc90ac15792421), [#3370](https://github.com/railsadminteam/rails_admin/pull/3370))\n- Update Moment.js to 2.29.1([#3348](https://github.com/railsadminteam/rails_admin/pull/3348), [973dee06](https://github.com/railsadminteam/rails_admin/commit/973dee065938a58d1aef4119a4bc90ac15792421), [7962a194](https://github.com/railsadminteam/rails_admin/commit/7962a19469a709c00f481a50a6d1e7ddd1e37cc6))\n- Update Bootstrap to 3.4.1([#3348](https://github.com/railsadminteam/rails_admin/pull/3348), [973dee06](https://github.com/railsadminteam/rails_admin/commit/973dee065938a58d1aef4119a4bc90ac15792421))\n- Update Bootstrap Datetime Picker to 4.17.49([7962a194](https://github.com/railsadminteam/rails_admin/commit/7962a19469a709c00f481a50a6d1e7ddd1e37cc6))\n\n### Removed\n\n- Remove unnecessary devise patch([#3352](https://github.com/railsadminteam/rails_admin/pull/3352))\n\n### Fixed\n\n- Zeitwerk incompatibility([#3190](https://github.com/railsadminteam/rails_admin/issues/3328), [97ccc289](https://github.com/railsadminteam/rails_admin/commit/97ccc28940d65fee53b30c409c49032fbb0885db))\n\n## [2.1.1](https://github.com/railsadminteam/rails_admin/tree/v2.1.1) - 2021-03-14\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v2.1.0...v2.1.1)\n\n### Fixed\n\n- Fix AbstractObject's proxying was incompatible with keyword arguments in Ruby 3.0 ([#3342](https://github.com/railsadminteam/rails_admin/issues/3342))\n\n## [2.1.0](https://github.com/railsadminteam/rails_admin/tree/v2.1.0) - 2021-02-28\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v2.0.2...v2.1.0)\n\n### Added\n\n- Ability to set default filter operator for fields ([#3318](https://github.com/railsadminteam/rails_admin/pull/3318))\n- Shrine 3.x support ([#3257](https://github.com/railsadminteam/rails_admin/pull/3257))\n- Rails 6.1 compatibility ([f0c46f1e](https://github.com/railsadminteam/rails_admin/commit/f0c46f1e128b5d31d812ff3a80d15db8692c848b))\n\n### Fixed\n\n- Some translation entries of filtering-multiselect weren't localizable ([#3315](https://github.com/railsadminteam/rails_admin/pull/3315))\n- Thumbnail generation breaks when used with ActiveStorage 6.x and ruby-vips ([#3255](https://github.com/railsadminteam/rails_admin/pull/3255), [2dba791c](https://github.com/railsadminteam/rails_admin/commit/2dba791c9135b3202d662f90fac443d282869bd6))\n- Hide present/blank filter options for required fields ([#3340](https://github.com/railsadminteam/rails_admin/pull/3340))\n- Fix to show correct filename for multiple attachments ([#3295](https://github.com/railsadminteam/rails_admin/pull/3295))\n- Fix encoding detection was incompatible with DB connection proxies like active_record_host_pool gem ([#3313](https://github.com/railsadminteam/rails_admin/pull/3313))\n- Fix hidden fields breaking indentation ([#3278](https://github.com/railsadminteam/rails_admin/pull/3278), [#2487](https://github.com/railsadminteam/rails_admin/issues/2487))\n\n### Removed\n\n- Remove `yell_for_non_accessible_fields` option since it has no effect since 0.5.0 ([#3249](https://github.com/railsadminteam/rails_admin/pull/3249))\n\n## [2.0.2](https://github.com/railsadminteam/rails_admin/tree/v2.0.2) - 2020-03-17\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v2.0.1...v2.0.2)\n\n### Fixed\n\n- Fix to use I18n to translate the button 'Reset filters'([#3248](https://github.com/railsadminteam/rails_admin/pull/3248))\n\n### Security\n\n- Fix XSS vulnerability in nested forms([d72090ec](https://github.com/railsadminteam/rails_admin/commit/d72090ec6a07c3b9b7b48ab50f3d405f91ff4375))\n\n## [2.0.1](https://github.com/railsadminteam/rails_admin/tree/v2.0.1) - 2019-12-31\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v2.0.0...v2.0.1)\n\n### Fixed\n\n- Fix Zeitwerk incompatible behavior of autoloading constants during initialization([#3190](https://github.com/railsadminteam/rails_admin/issues/3190), [e275012b](https://github.com/railsadminteam/rails_admin/commit/e275012b630453cb1187e71a938382a3c5d3ef39))\n- Fix empty fields being hidden regardless of `compact_show_view`([#3213](https://github.com/railsadminteam/rails_admin/pull/3213))\n- Fix `filter_scope` not using `default_search_operator` as default([#3212](https://github.com/railsadminteam/rails_admin/pull/3212))\n- Fix PaperTrail integration returning `nil` as username instead of `whodunnit`([#3210](https://github.com/railsadminteam/rails_admin/pull/3210))\n- Fix Sprockets 4 incompatibility of vendorized Fontawesome([#3204](https://github.com/railsadminteam/rails_admin/issues/3204), [#3207](https://github.com/railsadminteam/rails_admin/pull/3207))\n\n### Security\n\n- Update moment.js to 2.24.0 to address security vulnerability([#3182](https://github.com/railsadminteam/rails_admin/issues/3182), [#3201](https://github.com/railsadminteam/rails_admin/pull/3201))\n\n## [2.0.0](https://github.com/railsadminteam/rails_admin/tree/v2.0.0) - 2019-08-18\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v2.0.0.rc...v2.0.0)\n\n### Fixed\n\n- Fix support for belongs_to with custom primary key was broken in 2.0.0.rc([#3184](https://github.com/railsadminteam/rails_admin/issues/3184), [0e92ca43](https://github.com/railsadminteam/rails_admin/commit/0e92ca43fe7782a8d62ae9285a8d3de7857c9853))\n- Fix missing translation `en.admin.misc.ago`([#3180](https://github.com/railsadminteam/rails_admin/pull/3180))\n\n## [2.0.0.rc](https://github.com/railsadminteam/rails_admin/tree/v2.0.0.rc) - 2019-08-04\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v2.0.0.beta...v2.0.0.rc)\n\n### Added\n\n- Add Support for CarrierWave 2.0 multiple file upload's keep, append and reorder feature([fb093e04](https://github.com/railsadminteam/rails_admin/commit/fb093e04502e7bff30594f5baf1227abb7199384))\n- Add ability to configure way how custom actions show up in root/top/sidebar navigation([#2844](https://github.com/railsadminteam/rails_admin/pull/2844))\n\n### Changed\n\n- [BREAKING CHANGE] Stop authorization adapters assigning attributes on create and update, just check for permission instead([#3120](https://github.com/railsadminteam/rails_admin/pull/3120), [c84d1703](https://github.com/railsadminteam/rails_admin/commit/c84d1703b47b396382d152471dac8fc8dc41aefd))\n- [BREAKING CHANGE] Do not show tableless models by default([#3157](https://github.com/railsadminteam/rails_admin/issues/3157), [87b38b33](https://github.com/railsadminteam/rails_admin/commit/87b38b336cc668a74803dec4628215e2e2941248))\n- [BREAKING CHANGE] Convert empty string into nil for nullable string-like fields to achieve uniqueness-index friendliness([#2099](https://github.com/railsadminteam/rails_admin/issues/2099), [#3172](https://github.com/railsadminteam/rails_admin/issues/3172), [3f9ab1cc](https://github.com/railsadminteam/rails_admin/commit/3f9ab1cc009caa8b466f34da692c3561da2235e4))\n- Extract head from application template for ease of customization([#3114](https://github.com/railsadminteam/rails_admin/pull/3114))\n- Rename `delete_key` to `delete_value`, used to identify which file to delete in multiple file upload([8b8c3a44](https://github.com/railsadminteam/rails_admin/commit/8b8c3a44177465823128e9b48b11467ccf7db001))\n- Get rid of CoffeeScript, use plain JavaScript instead([#3111](https://github.com/railsadminteam/rails_admin/issues/3111), [#3168](https://github.com/railsadminteam/rails_admin/pull/3168))\n- Replace sass-rails with sassc-rails([#3156](https://github.com/railsadminteam/rails_admin/pull/3156))\n\n### Removed\n\n- Drop support for CanCan, please use its successor CanCanCan([6b7495f1](https://github.com/railsadminteam/rails_admin/commit/6b7495f1454e30027a9d77b911206cc7703170a3))\n- Drop support for CanCanCan legacy `can :dashboard` style dashboard ability notation([5bebac24](https://github.com/railsadminteam/rails_admin/commit/5bebac2488906f3739717108efadedaa091ccaf5))\n- Drop Refile support due to maintenance inactivity([25ae06a9](https://github.com/railsadminteam/rails_admin/commit/25ae06a9a6eb534afa4a5f17e64ca346086bb3b8))\n\n### Fixed\n\n- Fix PaperTrail pagination breaks when Kaminari's `page_method_name` is set([#3170](https://github.com/railsadminteam/rails_admin/issues/3170), [136b943c](https://github.com/railsadminteam/rails_admin/commit/136b943ce842eba6b0a13dc2956ddc9ce20d006c))\n- Fix failing to pass config location to CKEditor([#3162](https://github.com/railsadminteam/rails_admin/issues/3162), [c38b76d7](https://github.com/railsadminteam/rails_admin/commit/c38b76d707f198be0ac8baa1ff02dde7bd02344f))\n- Fix CarrierWave multiple file uploader breaking when used with Fog([#3070](https://github.com/railsadminteam/rails_admin/issues/3070))\n- Fix placeholder being picked up as a selection in filtering-multiselect([#2807](https://github.com/railsadminteam/rails_admin/issues/2807), [15502601](https://github.com/railsadminteam/rails_admin/commit/15502601ccd0bbbaeb364a0ee605f360d65c5cbb))\n- Fix breaking with has_many and custom primary key([#1878](https://github.com/railsadminteam/rails_admin/issues/1878), [be7d2f4a](https://github.com/railsadminteam/rails_admin/commit/be7d2f4a3ad1fda788f92a0e0dd4a83b98f141f4))\n- Fix to choose right LIKE statement in per-model basis([#1676](https://github.com/railsadminteam/rails_admin/issues/1676), [4ea4575e](https://github.com/railsadminteam/rails_admin/commit/4ea4575e934e26cec4a5b214b9fe68cb96b40247))\n- Fix polymorphic associations not using STI base classes for polymorphic type([#2136](https://github.com/railsadminteam/rails_admin/pull/2136))\n\n### Security\n\n- Add `rel=\"noopener\"` to all `target=\"_blank\"` links to prevent Reverse tabnabbing([#2960](https://github.com/railsadminteam/rails_admin/issues/2960), [#3169](https://github.com/railsadminteam/rails_admin/pull/3169))\n\n## [2.0.0.beta](https://github.com/railsadminteam/rails_admin/tree/v2.0.0.beta) - 2019-06-08\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v1.4.2...v2.0.0.beta)\n\n### Added\n\n- Rails 6 support([#3122](https://github.com/railsadminteam/rails_admin/pull/3122))\n- ActionText support([#3144](https://github.com/railsadminteam/rails_admin/issues/3144), [Wiki](https://github.com/railsadminteam/rails_admin/wiki/ActionText))\n- sass-rails 6 support([#3129](https://github.com/railsadminteam/rails_admin/issues/3129))\n- Sidescroll feature([#3017](https://github.com/railsadminteam/rails_admin/pull/3017), [Wiki](https://github.com/railsadminteam/rails_admin/wiki/Horizontally-scrolling-table-with-frozen-columns-in-list-view))\n- Custom search feature([#343](https://github.com/railsadminteam/rails_admin/issues/343), [#3019](https://github.com/railsadminteam/rails_admin/pull/3019), [Wiki](https://github.com/railsadminteam/rails_admin/wiki/Custom-Search))\n- Filtering-select feature for polymorphic association([#2886](https://github.com/railsadminteam/rails_admin/pull/2886))\n- Shrine support([#3081](https://github.com/railsadminteam/rails_admin/pull/3081))\n- Flexibility for localication of _time_ ago([#3135](https://github.com/railsadminteam/rails_admin/pull/3135), [49add741](https://github.com/railsadminteam/rails_admin/commit/49add7413794e2a1423b86399ef476414d22970f))\n\n### Changed\n\n- Vendorize font-awesome to allow using different version in app([#3039](https://github.com/railsadminteam/rails_admin/issues/3039))\n- Stop inlining JavaScripts for CSP friendliness([#3087](https://github.com/railsadminteam/rails_admin/issues/3087))\n- Richtext editors now uses CDN-hosted assets([#3126](https://github.com/railsadminteam/rails_admin/issues/3126))\n\n### Removed\n\n- Remove deprecated DSL syntax for richtext editors([e0b390d9](https://github.com/railsadminteam/rails_admin/commit/e0b390d99eab64c99f1f3cccae2029649e90e11c))\n- Drop support for Ruby 2.1 and Rails 4.x([dd247804](https://github.com/railsadminteam/rails_admin/commit/dd24780445f4dd676ae033c69a5b64347b80c3bc))\n\n### Fixed\n\n- Fix Mongoid query and filter parsing value twice([#2755](https://github.com/railsadminteam/rails_admin/issues/2755))\n- Fix thread-safety issues([#2897](https://github.com/railsadminteam/rails_admin/issues/2897), [#2942](https://github.com/railsadminteam/rails_admin/issues/2942), [1d22bc66](https://github.com/railsadminteam/rails_admin/commit/1d22bc66168ac9ea478ea95b4b3b79f41263c0bd))\n- Fix compact_show_view not showing Boolean falses([#2416](https://github.com/railsadminteam/rails_admin/issues/2416))\n- Fix PaperTrail fail to fetch versions for STI subclasses([#2865](https://github.com/railsadminteam/rails_admin/pull/2865))\n- Fix Dragonfly factory breaks if a model not extending Dragonfly::Model is passed([#2720](https://github.com/railsadminteam/rails_admin/pull/2720))\n- Fix PaperTrail adapter not using Kaminari's `page_method_name` for pagination([#2712](https://github.com/railsadminteam/rails_admin/pull/2712))\n- Fix #bulk_menu was not using passed `abstract_model` ([#2782](https://github.com/railsadminteam/rails_admin/pull/2782))\n- Fix wrong styles when using multiple instances of CodeMirror([#3107](https://github.com/railsadminteam/rails_admin/pull/3107))\n- Fix password being cleared when used with Devise 4.6([72bc0373](https://github.com/railsadminteam/rails_admin/commit/72bc03736162ffef8e5b99f42ca605d17fe7e7d0))\n- ActiveStorage factory caused const missing for Mongoid([#3088](https://github.com/railsadminteam/rails_admin/pull/3088), [db927687](https://github.com/railsadminteam/rails_admin/commit/db9276879c8e8c5e8772261725ef0e0cdadd9cf1))\n- Fix exact matches were using LIKE, which was not index-friendly([#3000](https://github.com/railsadminteam/rails_admin/pull/3000))\n- Middleware check failed when using RedisStore([#3076](https://github.com/railsadminteam/rails_admin/issues/3076))\n- Fix field being reset to default after an error([#3066](https://github.com/railsadminteam/rails_admin/pull/3066))\n\n## [1.4.2](https://github.com/railsadminteam/rails_admin/tree/v1.4.2) - 2018-09-23\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v1.4.1...v1.4.2)\n\n### Fixed\n\n- Fix `can't modify frozen Array` error on startup([#3060](https://github.com/railsadminteam/rails_admin/issues/3060))\n- Fix deprecation warning with PaperTrail.whodunnit([#3059](https://github.com/railsadminteam/rails_admin/pull/3059))\n\n## [1.4.1](https://github.com/railsadminteam/rails_admin/tree/v1.4.1) - 2018-08-19\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v1.4.0...v1.4.1)\n\n### Fixed\n\n- Export crashes for models with JSON field([#3056](https://github.com/railsadminteam/rails_admin/pull/3056))\n- Middlewares being mangled by engine initializer, causing app's session store configuration to be overwritten([#3048](https://github.com/railsadminteam/rails_admin/issues/3048), [59478af9](https://github.com/railsadminteam/rails_admin/commit/59478af9a05c76bdfe35e94e63c60ba89c27a483))\n\n## [1.4.0](https://github.com/railsadminteam/rails_admin/tree/v1.4.0) - 2018-07-22\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v1.3.0...v1.4.0)\n\n### Added\n\n- Support for ActiveStorage([#2990](https://github.com/railsadminteam/rails_admin/issues/2990), [#3037](https://github.com/railsadminteam/rails_admin/pull/3037))\n- Support for multiple file upload for ActiveStorage and CarrierWave ([5bb2d375](https://github.com/railsadminteam/rails_admin/commit/5bb2d375a236268e51c7e8682c2d110d9e52970f))\n- Support for Mongoid 7.0([9ef623f6](https://github.com/railsadminteam/rails_admin/commit/9ef623f6cba73adbf86833d9eb07f1be3924a133), [#3013](https://github.com/railsadminteam/rails_admin/issues/3013))\n- Support for CanCanCan 2.0([a32d49e4](https://github.com/railsadminteam/rails_admin/commit/a32d49e4b96944905443588a1216b3362ee64c1a), [#2901](https://github.com/railsadminteam/rails_admin/issues/2901))\n- Support for Pundit 2.0([bc60c978](https://github.com/railsadminteam/rails_admin/commit/bc60c978adfebe09cdad2c199878d8ff966374f1))\n- Support for jquery-ui-rails 6.0([#2951](https://github.com/railsadminteam/rails_admin/issues/2951), [#3003](https://github.com/railsadminteam/rails_admin/issues/3003))\n\n### Fixed\n\n- Make code reloading work([#3041](https://github.com/railsadminteam/rails_admin/pull/3041))\n- Improved support for Rails API mode, requiring needed middlewares in engine's initializer([#2919](https://github.com/railsadminteam/rails_admin/issues/2919), [#3006](https://github.com/railsadminteam/rails_admin/pull/3006))\n- Make the link text to uploaded file shorter, instead of showing full url([#2983](https://github.com/railsadminteam/rails_admin/pull/2983))\n- Fix duplication of filters on browser back([#2998](https://github.com/railsadminteam/rails_admin/pull/2998))\n- Fix \"can't modify frozen array\" exception on code reload([#2999](https://github.com/railsadminteam/rails_admin/pull/2999))\n- Fix incorrectly comparing numeric columns with empty string when handling blank operator([#3007](https://github.com/railsadminteam/rails_admin/pull/3007))\n\n## [1.3.0](https://github.com/railsadminteam/rails_admin/tree/v1.3.0) - 2018-02-18\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v1.2.0...v1.3.0)\n\n### Added\n\n- Configurability for forgery protection setting([#2989](https://github.com/railsadminteam/rails_admin/pull/2989))\n- Configurability for the number of audit records displayed into dashboard([#2982](https://github.com/railsadminteam/rails_admin/pull/2982))\n- Add limited pagination mode, which doesn't require count query([#2968](https://github.com/railsadminteam/rails_admin/pull/2968))\n- Prettier output of JSON field value([#2937](https://github.com/railsadminteam/rails_admin/pull/2937), [#2973](https://github.com/railsadminteam/rails_admin/pull/2973), [#2980](https://github.com/railsadminteam/rails_admin/pull/2980))\n- Add markdown field support through SimpleMDE([#2949](https://github.com/railsadminteam/rails_admin/pull/2949))\n- Checkboxes for bulk actions in index page can be turned off now([#2917](https://github.com/railsadminteam/rails_admin/pull/2917))\n\n### Fixed\n\n- Parse JS translations as JSON([#2925](https://github.com/railsadminteam/rails_admin/pull/2925))\n- Re-selecting an item after unselecting has no effect in filtering-multiselect([#2912](https://github.com/railsadminteam/rails_admin/issues/2912))\n- Stop memoization of datetime parser to handle locale changes([#2824](https://github.com/railsadminteam/rails_admin/pull/2824))\n- Filters for ActiveRecord Enum field behaved incorrectly for enums whose labels are different from values([#2971](https://github.com/railsadminteam/rails_admin/pull/2971))\n- Client-side required validation was not enforced in filtering-select widget([#2905](https://github.com/railsadminteam/rails_admin/pull/2905))\n- Filter refresh button was broken([#2890](https://github.com/railsadminteam/rails_admin/pull/2890))\n\n### Security\n\n- Fix XSS vulnerability in filter and multi-select widget([#2985](https://github.com/railsadminteam/rails_admin/issues/2985), [44f09ed7](https://github.com/railsadminteam/rails_admin/commit/44f09ed72b5e0e917a5d61bd89c48d97c494b41c))\n\n## [1.2.0](https://github.com/railsadminteam/rails_admin/tree/v1.2.0) - 2017-05-31\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v1.1.1...v1.2.0)\n\n### Added\n\n- Add ILIKE support for PostgreSQL/PostGIS adapter, multibyte downcase for other adapters([#2766](https://github.com/railsadminteam/rails_admin/pull/2766))\n- Support for UUID query([#2766](https://github.com/railsadminteam/rails_admin/pull/2766))\n- Support for Haml 5([#2840](https://github.com/railsadminteam/rails_admin/pull/2840), [#2870](https://github.com/railsadminteam/rails_admin/pull/2870), [#2877](https://github.com/railsadminteam/rails_admin/pull/2877))\n- Add instance option to append a CSS class for rows([#2860](https://github.com/railsadminteam/rails_admin/pull/2860))\n\n### Fixed\n\n- Remove usage of alias_method_chain, deprecated in Rails 5.0([#2864](https://github.com/railsadminteam/rails_admin/pull/2864))\n- Load models from eager_load, not autoload_paths([#2771](https://github.com/railsadminteam/rails_admin/pull/2771))\n- jQuery 3.0 doesn't have size(), use length instead([#2841](https://github.com/railsadminteam/rails_admin/pull/2841))\n- Prepopulation of the new form didn't work with namespaced models([#2701](https://github.com/railsadminteam/rails_admin/pull/2701))\n\n## [1.1.1](https://github.com/railsadminteam/rails_admin/tree/v1.1.1) - 2016-12-25\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v1.1.0...v1.1.1)\n\n### Fixed\n\n- CSV export broke with empty tables([#2796](https://github.com/railsadminteam/rails_admin/issues/2796), [#2797](https://github.com/railsadminteam/rails_admin/pull/2797))\n- ActiveRecord adapter's #encoding did not work with Oracle enhanced adapter([#2789](https://github.com/railsadminteam/rails_admin/pull/2789))\n- ActiveRecord 5 belongs_to presence validators were unintentionally disabled due to initialization mishandling([#2785](https://github.com/railsadminteam/rails_admin/issues/2785), [#2786](https://github.com/railsadminteam/rails_admin/issues/2786))\n- Destroy failure caused subsequent index action to return 404, instead of 200([#2775](https://github.com/railsadminteam/rails_admin/issues/2775), [#2776](https://github.com/railsadminteam/rails_admin/pull/2776))\n- CSVConverter#to_csv now accepts string-keyed hashes([#2740](https://github.com/railsadminteam/rails_admin/issues/2740), [#2741](https://github.com/railsadminteam/rails_admin/pull/2741))\n\n### Security\n\n- Fix CSRF vulnerability([b13e879e](https://github.com/railsadminteam/rails_admin/commit/b13e879eb93b661204e9fb5e55f7afa4f397537a))\n\n## [1.1.0](https://github.com/railsadminteam/rails_admin/tree/v1.1.0) - 2016-10-30\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v1.0.0...v1.1.0)\n\n### Added\n\n- DSL for association eager-loading([#1325](https://github.com/railsadminteam/rails_admin/issues/1325), [#1342](https://github.com/railsadminteam/rails_admin/issues/1342))\n\n### Fixed\n\n- Fix nested has_many form failing to add items([#2737](https://github.com/railsadminteam/rails_admin/pull/2737))\n\n## [1.0.0](https://github.com/railsadminteam/rails_admin/tree/v1.0.0) - 2016-09-19\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v1.0.0.rc...v1.0.0)\n\n### Added\n\n- Introduce setup hook for authorization/auditing adapters([ba2088c6](https://github.com/railsadminteam/rails_admin/commit/ba2088c6ecabd354b4b67c50bb00fccdbd1e6240))\n- Add viewport meta tag for mobile layout adjustment([#2664](https://github.com/railsadminteam/rails_admin/pull/2664))\n- Support for ActiveRecord::Enum using string columns([#2680](https://github.com/railsadminteam/rails_admin/pull/2680))\n\n### Changed\n\n- Limit children for deletion notice([#2491](https://github.com/railsadminteam/rails_admin/pull/2491))\n- [BREAKING CHANGE] Change parent controller to ActionController::Base for out-of-box support of Rails 5 API mode([#2688](https://github.com/railsadminteam/rails_admin/issues/2688))\n  - To keep old behavior, add `config.parent_controller = '::ApplicationController'` in your RailsAdmin initializer.\n\n### Fixed\n\n- ActiveRecord Enum fields could not be updated correctly([#2659](https://github.com/railsadminteam/rails_admin/pull/2659), [#2713](https://github.com/railsadminteam/rails_admin/issues/2713))\n- Fix performance issue with filtering-multiselect widget([#2715](https://github.com/railsadminteam/rails_admin/pull/2715))\n- Restore back rails_admin_controller?([#2268](https://github.com/railsadminteam/rails_admin/issues/2268))\n- Duplication of autocomplete fields when using browser back/forward buttons([#2677](https://github.com/railsadminteam/rails_admin/issues/2677), [#2678](https://github.com/railsadminteam/rails_admin/pull/2678))\n- Filter refresh button was broken([#2705](https://github.com/railsadminteam/rails_admin/issues/2705), [#2706](https://github.com/railsadminteam/rails_admin/pull/2706))\n- Fix presence filtering on boolean columns([#1099](https://github.com/railsadminteam/rails_admin/issues/1099), [#2675](https://github.com/railsadminteam/rails_admin/pull/2675))\n- Pundit::AuthorizationNotPerformedError was raised when used with Pundit([#2683](https://github.com/railsadminteam/rails_admin/pull/2683))\n\n## [1.0.0.rc](https://github.com/railsadminteam/rails_admin/tree/v1.0.0.rc) - 2016-07-18\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v0.8.1...v1.0.0.rc)\n\n### Added\n\n- Rails 5 support\n- PaperTrail 5 support([9c42783a](https://github.com/railsadminteam/rails_admin/commit/9c42783aa65b704f4a5d467608c49b746c47b81b))\n- Support for multiple configuration blocks([#1781](https://github.com/railsadminteam/rails_admin/pull/1781), [#2670](https://github.com/railsadminteam/rails_admin/pull/2670))\n- Default association limit is now configurable([#2508](https://github.com/railsadminteam/rails_admin/pull/2058))\n\n### Changed\n\n- Prefix kaminari bootstrap views with `ra-` to avoid name conflict([#2283](https://github.com/railsadminteam/rails_admin/issues/2283), [#2651](https://github.com/railsadminteam/rails_admin/pull/2651))\n- Gravatar icon is now optional([#2570](https://github.com/railsadminteam/rails_admin/pull/2570))\n- Improve bootstrap-wysihtml5-rails support([#2650](https://github.com/railsadminteam/rails_admin/pull/2650))\n- Explicitly call the #t method on I18n([#2564](https://github.com/railsadminteam/rails_admin/pull/2564))\n- Improve dashboard performance by querying with id instead of updated_at([#2514](https://github.com/railsadminteam/rails_admin/issues/2514), [#2551](https://github.com/railsadminteam/rails_admin/pull/2551))\n- Improve encoding support in CSV converter([#2508](https://github.com/railsadminteam/rails_admin/pull/2508), [dca8911f](https://github.com/railsadminteam/rails_admin/commit/dca8911f240ea11ebb186c33573188aa9e1b031d))\n- Add SVG file extension to the image detection method([#2533](https://github.com/railsadminteam/rails_admin/pull/2533))\n- Update linear gradient syntax to make autoprefixer happy([#2531](https://github.com/railsadminteam/rails_admin/pull/2531))\n- Improve export layout ([#2505](https://github.com/railsadminteam/rails_admin/pull/2505))\n\n### Removed\n\n- Remove safe_yaml dependency([#2397](https://github.com/railsadminteam/rails_admin/pull/2397))\n- Drop support for Ruby < 2.1.0\n\n### Fixed\n\n- Pagination did not work when showing all history([#2553](https://github.com/railsadminteam/rails_admin/pull/2553))\n- Make filter-box label clickable([#2573](https://github.com/railsadminteam/rails_admin/pull/2573))\n- Colorpicker form did not have the default css class `form-control`([#2571](https://github.com/railsadminteam/rails_admin/pull/2571))\n- Stop assuming locale en is available([#2155](https://github.com/railsadminteam/rails_admin/issues/2155))\n- Fix undefined method error with nested polymorphics([#1338](https://github.com/railsadminteam/rails_admin/issues/1338), [#2110](https://github.com/railsadminteam/rails_admin/pull/2110))\n- Fix issue with nav does not check pjax config from an action([#2309](https://github.com/railsadminteam/rails_admin/pull/2309))\n- Model label should be pluralized with locale([#1983](https://github.com/railsadminteam/rails_admin/pull/1983))\n- Fix delocalize strftime_format for DateTime.strptime to support minus([#2547](https://github.com/railsadminteam/rails_admin/pull/2547))\n- Fix Syntax Error in removal of new nested entity([#2539](https://github.com/railsadminteam/rails_admin/pull/2539))\n- Fix momentjs translations for '%-d' format day of the month([#2540](https://github.com/railsadminteam/rails_admin/pull/2540))\n- Fix Mongoid BSON object field ([#2495](https://github.com/railsadminteam/rails_admin/issues/2495))\n- Make browser ignore validations of removed nested child models([#2443](https://github.com/railsadminteam/rails_admin/issues/2443), [#2490](https://github.com/railsadminteam/rails_admin/pull/2490))\n\n## [0.8.1](https://github.com/railsadminteam/rails_admin/tree/v0.8.1) - 2015-11-24\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v0.8.0...v0.8.1)\n\n### Fixed\n\n- `vendor/` directory was missing from gemspec([#2481](https://github.com/railsadminteam/rails_admin/issues/2481), [#2482](https://github.com/railsadminteam/rails_admin/pull/2482))\n\n## [0.8.0](https://github.com/railsadminteam/rails_admin/tree/v0.8.0) - 2015-11-23\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v0.7.0...v0.8.0)\n\n### Added\n\n- Feature to deactivate filtering-multiselect widget's remove buttons through `removable?` field option([#2446](https://github.com/railsadminteam/rails_admin/issues/2446))\n- Pundit integration([#2399](https://github.com/railsadminteam/rails_admin/pull/2399) by Team CodeBenders, RGSoC'15)\n- Refile support([#2385](https://github.com/railsadminteam/rails_admin/pull/2385))\n\n### Changed\n\n- Some UI improvements in export view([#2394](https://github.com/railsadminteam/rails_admin/pull/2394))\n- `rails_admin/custom/variables.scss` is now imported first to take advantage of Sass's `default!`([#2404](https://github.com/railsadminteam/rails_admin/pull/2404))\n- Proxy classes now inherit from BasicObject([#2434](https://github.com/railsadminteam/rails_admin/issues/2434))\n- Show sidebar scrollbar only on demand([#2419](https://github.com/railsadminteam/rails_admin/pull/2419))\n- RailsAdmin no longer gets excluded from NewRelic instrumentation by default([#2402](https://github.com/railsadminteam/rails_admin/pull/2402))\n- Improve efficiency of filter query in Postgres([#2401](https://github.com/railsadminteam/rails_admin/pull/2401))\n- Replace old jQueryUI datepicker with jQuery Bootstrap datetimepicker ([#2391](https://github.com/railsadminteam/rails_admin/pull/2391))\n- Turn Hash#symbolize into a helper to prevent namespace conflict([#2388](https://github.com/railsadminteam/rails_admin/pull/2388))\n\n### Removed\n\n- The L10n translation `admin.misc.filter_date_format` datepicker search filters, has been dropped in favor of field oriented configuration ([#2391](https://github.com/railsadminteam/rails_admin/pull/2391))\n\n### Fixed\n\n- AR#count broke when default-scoped with select([#2129](https://github.com/railsadminteam/rails_admin/pull/2129), [#2447](https://github.com/railsadminteam/rails_admin/issues/2447))\n- Datepicker could not handle Spanish date properly([#982](https://github.com/railsadminteam/rails_admin/issues/982), [#2451](https://github.com/railsadminteam/rails_admin/pull/2451))\n- Paperclip's `attachment_definitions` does not exist unless `has_attached_file`-ed([#1674](https://github.com/railsadminteam/rails_admin/issues/1674))\n- `.btn` class was used without a modifier([#2417](https://github.com/railsadminteam/rails_admin/pull/2417))\n- Filtering-multiselect widget ignored order([#2231](https://github.com/railsadminteam/rails_admin/issues/2231), [#2412](https://github.com/railsadminteam/rails_admin/pull/2412))\n- Add missing .alert-dismissible class to flash([#2411](https://github.com/railsadminteam/rails_admin/pull/2411))\n- Keep field order on changing the existing field's type([#2409](https://github.com/railsadminteam/rails_admin/pull/2409))\n- Add button for nested-many form in modal disappeared on click([#2372](https://github.com/railsadminteam/rails_admin/issues/2372), [#2383](https://github.com/railsadminteam/rails_admin/pull/2383))\n\n### Security\n\n- Fix XSS vulnerability in polymorphic select([#2479](https://github.com/railsadminteam/rails_admin/pull/2479))\n\n## [0.7.0](https://github.com/railsadminteam/rails_admin/tree/v0.7.0) - 2015-08-16\n\n[Full Changelog](https://github.com/railsadminteam/rails_admin/compare/v0.6.8...v0.7.0)\n\n### Added\n\n- Support for ActiveRecord::Enum ([#1993](https://github.com/railsadminteam/rails_admin/issues/1993))\n- Multiselect-widget shows user friendly message, instead of just being blank ([#1369](https://github.com/railsadminteam/rails_admin/issues/1369), [#2360](https://github.com/railsadminteam/rails_admin/pull/2360))\n- Configuration option to turn browser validation off ([#2339](https://github.com/railsadminteam/rails_admin/pull/2339), [#2373](https://github.com/railsadminteam/rails_admin/pull/2373))\n\n### Changed\n\n- Multiselect-widget inserts a new item to the bottom, instead of top ([#2167](https://github.com/railsadminteam/rails_admin/pull/2167))\n- Migrated Cerulean theme to Bootstrap3 ([#2352](https://github.com/railsadminteam/rails_admin/pull/2352))\n- Better html markup for input fields ([#2336](https://github.com/railsadminteam/rails_admin/pull/2336))\n- Update filter dropdown button to Bootstrap3 ([#2277](https://github.com/railsadminteam/rails_admin/pull/2277))\n- Improve navbar appearance ([#2310](https://github.com/railsadminteam/rails_admin/pull/2310))\n- Do not monkey patch the app's YAML ([#2331](https://github.com/railsadminteam/rails_admin/pull/2331))\n\n### Fixed\n\n- Browser validation prevented saving of persisted upload fields ([#2376](https://github.com/railsadminteam/rails_admin/issues/2376))\n- Fix inconsistent styling in static_navigation ([#2378](https://github.com/railsadminteam/rails_admin/pull/2378))\n- Fix css regression for has_one and has_many nested form ([#2337](https://github.com/railsadminteam/rails_admin/pull/2337))\n- HTML string inputs should not have a size attribute valorized with 0 ([#2335](https://github.com/railsadminteam/rails_admin/pull/2335))\n\n### Security\n\n- Fix XSS vulnerability in filtering-select widget\n- Fix XSS vulnerability in association fields ([#2343](https://github.com/railsadminteam/rails_admin/issues/2343))\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## Contributing\n\nIn the spirit of [free software][free-sw], **everyone** is encouraged to help\nimprove this project.\n\n[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html\n\nHere are some ways _you_ can contribute:\n\n- by using alpha, beta, and prerelease versions\n- by triaging bug reports\n- by writing or editing documentation\n- by writing specifications\n- by writing code (**no patch is too small**: fix typos, add comments, clean up\n  inconsistent whitespace)\n- by refactoring code\n- by fixing [issues][]\n- by reviewing patches\n- by suggesting new features\n- [financially][gittip]\n\n[issues]: https://github.com/railsadminteam/rails_admin/issues\n[gittip]: https://www.gittip.com/sferik/\n\n## Development\n\n### Running tests locally\n\nTo run the test suite, you need Google Chrome and ImageMagick (or GraphicsMagick).\n\nExample installation on macOS using Homebrew:\n\n```bash\n# install imagemagick:\nbrew install imagemagick\n# install google chrome with cask:\nbrew install brew-cask\nbrew install google-chrome --cask\n# install mysql\nbrew install mysql\n# install openssl\nbrew install openssl@3\n```\n\nExample installation on Ubuntu:\n\n```bash\n# install imagemagick:\nsudo apt update -y && sudo apt install imagemagick -y\n# install google chrome:\nsudo apt update -y && wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && sudo apt install ./google-chrome-stable_current_amd64.deb -y\n```\n\nThen you need to do this one-time setup:\n\n```bash\n# On Mac, you may run into problems with the mysql2 gem that require flags to be set in bundle config\n# See: https://github.com/brianmario/mysql2/issues/1345\nbundle config build.mysql2 '-- --with-cflags=\"-Wno-error=implicit-function-declaration\" --with-ldflags=-L/opt/homebrew/opt/zstd/lib'\n\nbundle install\nyarn install\n# install dependencies for each appraisal:\nbundle exec appraisal install\n# precompile assets in the dummy app:\ncd spec/dummy_app && yarn install && yarn build && yarn build:css && cd -\n```\n\nThen you will be able to run the specs:\n\n```bash\nbundle exec appraisal rails-7.0 rspec\n```\n\n### Tests run against multiple versions of Rails\n\nIn CI, we use [appraisal] to run tests against multiple versions of Rails. The\n[gemfiles/ directory] contains the Gemfiles used to create the CI build matrix.\nSee the [GitHub Actions configuration] for more details on what Ruby versions\nrun what Rails versions.\n\n[appraisal]: https://github.com/thoughtbot/appraisal\n[gemfiles/ directory]: ./gemfiles\n[github actions configuration]: ./.github/workflows/test.yml\n\n## Getting Help\n\nWe use a [mailing list][list] for user support. If you've got a \"how do\nI do this?\" or \"this doesn't seem to work the way I expect\" type of\nissue or just want some help, please post a message to the [mailing\nlist][list].\n\n## Submitting an Issue\n\nIf you're confident that you've found a bug in\nrails_admin, please [open an issue][issues], but check to make sure it hasn't\nalready been submitted. When submitting a bug report, please include a\n[Gist][] that includes a stack trace and any details that may be\nnecessary to reproduce the bug, including your gem version, Ruby\nversion, and operating system. Ideally, a bug report should include a\npull request with failing specs.\n\n[gist]: https://gist.github.com/\n[list]: http://groups.google.com/group/rails_admin\n\n## Submitting a Pull Request\n\n1. [Fork the repository.][fork]\n2. Create a branch.\n3. Add specs for your unimplemented feature or bug fix.\n4. Run `bundle exec rake spec`. If your specs pass, return to step 3.\n5. Implement your feature or bug fix.\n6. Run `bundle exec rake default`. If your specs fail, return to step 5.\n7. Run `open coverage/index.html`. If your changes are not completely covered\n   by your tests, return to step 3.\n8. Add, commit, and push your changes.\n9. [Submit a pull request.][pr]\n\n[fork]: http://help.github.com/fork-a-repo/\n[pr]: http://help.github.com/send-pull-requests/\n"
  },
  {
    "path": "Gemfile",
    "content": "# frozen_string_literal: true\n\nsource 'https://rubygems.org'\n\ngem 'appraisal', '>= 2.0'\ngem 'devise', '~> 4.7'\ngem 'net-smtp', require: false\ngem 'rails'\ngem 'sassc-rails', '~> 2.1'\ngem 'turbo-rails'\ngem 'vite_rails', require: false\ngem 'webpacker', require: false\ngem 'webrick'\n\ngroup :development, :test do\n  gem 'pry', '>= 0.9'\nend\n\ngroup :test do\n  gem 'cancancan', '~> 3.0'\n  gem 'carrierwave', ['>= 2.0.0.rc', '< 3']\n  gem 'cuprite', '!= 0.15.1'\n  gem 'database_cleaner-active_record', '>= 2.0', require: false\n  gem 'dragonfly', '~> 1.0'\n  gem 'factory_bot', '>= 4.2', '!= 6.4.5'\n  gem 'generator_spec', '>= 0.8'\n  gem 'kt-paperclip'\n  gem 'launchy', '>= 2.2'\n  gem 'mini_magick', '>= 3.4'\n  gem 'pundit'\n  gem 'rack-cache', require: 'rack/cache'\n  gem 'rspec-expectations', '!= 3.8.3'\n  gem 'rspec-rails', '>= 4.0.0.beta2'\n  gem 'rspec-retry'\n  gem 'rubocop', ['~> 1.20', '!= 1.22.2'], require: false\n  gem 'rubocop-performance', require: false\n  gem 'shrine', '~> 3.0'\n  gem 'simplecov', '>= 0.9', require: false\n  gem 'simplecov-lcov', require: false\n  gem 'timecop', '>= 0.5'\n\n  # Windows does not include zoneinfo files, so bundle the tzinfo-data gem\n  gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]\nend\n\ngroup :active_record do\n  gem 'paper_trail', '>= 12.0'\n\n  platforms :ruby, :mswin, :mingw, :x64_mingw do\n    gem 'mysql2', '>= 0.3.14'\n    gem 'pg', '>= 1.0.0'\n    gem 'sqlite3', '>= 1.3.0'\n  end\nend\n\ngemspec\n"
  },
  {
    "path": "LICENSE.md",
    "content": "Copyright (c) 2010-2016 Erik Michaels-Ober\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Procfile.teatro",
    "content": "web: cd spec/dummy_app && bundle exec rails server\n"
  },
  {
    "path": "README.md",
    "content": "# RailsAdmin\n\n[![Gem Version](https://img.shields.io/gem/v/rails_admin.svg)][gem]\n[![Build Status](https://github.com/railsadminteam/rails_admin/actions/workflows/test.yml/badge.svg)][ghactions]\n[![Coverage Status](https://img.shields.io/coveralls/railsadminteam/rails_admin.svg)][coveralls]\n[![Code Climate](https://codeclimate.com/github/railsadminteam/rails_admin.svg)][codeclimate]\n[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=rails_admin&package-manager=bundler&version-scheme=semver)][semver]\n\n[gem]: https://rubygems.org/gems/rails_admin\n[ghactions]: https://github.com/railsadminteam/rails_admin/actions/workflows/test.yml\n[coveralls]: https://coveralls.io/r/railsadminteam/rails_admin\n[codeclimate]: https://codeclimate.com/github/railsadminteam/rails_admin\n[semver]: https://dependabot.com/compatibility-score.html?dependency-name=rails_admin&package-manager=bundler&version-scheme=semver\n\nRailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.\n\n## Getting started\n\n- Check out [the docs][docs].\n- Try the [live demo][demo]. ([Source code][dummy_app])\n\n[demo]: https://rails-admin.fly.dev/admin/\n[dummy_app]: https://github.com/railsadminteam/rails_admin/tree/master/spec/dummy_app\n[docs]: https://github.com/railsadminteam/rails_admin/wiki\n\n## Features\n\n- CRUD any data with ease\n- Custom actions\n- Automatic form validation\n- Search and filtering\n- Export data to CSV/JSON/XML\n- Authentication (via [Devise](https://github.com/plataformatec/devise) or other)\n- Authorization (via [CanCanCan](https://github.com/CanCanCommunity/cancancan) or [Pundit](https://github.com/elabs/pundit))\n- User action history (via [PaperTrail](https://github.com/airblade/paper_trail))\n- Supported ORMs\n  - ActiveRecord\n  - Mongoid\n\n## Installation\n\n1. On your gemfile: `gem 'rails_admin', '~> 3.0'`\n2. Run `bundle install`\n3. Run `rails g rails_admin:install`\n4. Provide a namespace for the routes when asked\n5. Start a server `rails s` and administer your data at [/admin](http://localhost:3000/admin). (if you chose default namespace: /admin)\n\n## Upgrading from 2.x\n\nDue to introduction of Webpack/Webpacker support, some additional dependency and configuration will be needed.\nRunning `rails g rails_admin:install` will suggest you some required changes, based on current setup of your app.\n\n## Configuration\n\n### Global\n\nIn `config/initializers/rails_admin.rb`:\n\n[Details](https://github.com/railsadminteam/rails_admin/wiki/Base-configuration)\n\nTo begin with, you may be interested in setting up [Devise](https://github.com/railsadminteam/rails_admin/wiki/Devise), [CanCanCan](https://github.com/railsadminteam/rails_admin/wiki/Cancancan) or [Papertrail](https://github.com/railsadminteam/rails_admin/wiki/Papertrail)!\n\n### Per model\n\n```ruby\nclass Ball < ActiveRecord::Base\n  validates :name, presence: true\n  belongs_to :player\n\n  rails_admin do\n    configure :player do\n      label 'Owner of this ball: '\n    end\n  end\nend\n```\n\nDetails: [Models](https://github.com/railsadminteam/rails_admin/wiki/Models), [Groups](https://github.com/railsadminteam/rails_admin/wiki/Groups), [Fields](https://github.com/railsadminteam/rails_admin/wiki/Fields)\n\n## Support\n\nIf you have a question, please check this README, the wiki, and the [list of\nknown issues][troubleshoot].\n\n[troubleshoot]: https://github.com/railsadminteam/rails_admin/wiki/Troubleshoot\n\nIf you still have a question, you can ask the [official RailsAdmin mailing\nlist][list].\n\n[list]: http://groups.google.com/group/rails_admin\n\nIf you think you found a bug in RailsAdmin, you can [submit an issue](https://github.com/railsadminteam/rails_admin/issues/new).\n\n## Supported Ruby Versions\n\nThis library aims to support and is [tested against][ghactions] the following Ruby implementations:\n\n- Ruby 2.6\n- Ruby 2.7\n- Ruby 3.0\n- Ruby 3.1\n- Ruby 3.2\n- [JRuby][]\n\n[jruby]: http://jruby.org/\n"
  },
  {
    "path": "Rakefile",
    "content": "# frozen_string_literal: true\n\n# Add your own tasks in files placed in lib/tasks ending in .rake,\n# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.\n\nDir['lib/tasks/*.rake'].each { |rake| load rake }\n\nrequire 'bundler'\nBundler::GemHelper.install_tasks\n\nrequire 'rspec/core/rake_task'\nRSpec::Core::RakeTask.new(:spec)\n\ntask test: :spec\n\nbegin\n  require 'rubocop/rake_task'\n  RuboCop::RakeTask.new\nrescue LoadError\n  desc 'Run RuboCop'\n  task :rubocop do\n    warn 'Rubocop is disabled'\n  end\nend\n\ntask default: %i[spec rubocop]\n\nnamespace :vendorize do\n  desc 'Tasks for vendorizing assets'\n\n  task :flatpickr do\n    Dir.chdir(__dir__)\n    flatpickr = File.read('node_modules/flatpickr/dist/flatpickr.js')\n    locales = Dir.glob('node_modules/flatpickr/dist/l10n/*.js').map { |f| File.read(f) }\n    File.write('vendor/assets/javascripts/rails_admin/flatpickr-with-locales.js', ([flatpickr] + locales).join(\"\\n\"))\n  end\nend\n"
  },
  {
    "path": "app/assets/javascripts/rails_admin/application.js.erb",
    "content": "//=  require 'rails-ujs'\n//=  require 'turbo'\n//=  require 'rails_admin/jquery3'\n//=  require 'jquery_nested_form'\n//=  require 'rails_admin/jquery-ui/effect'\n//=  require 'rails_admin/jquery-ui/widgets/sortable'\n//=  require 'rails_admin/jquery-ui/widgets/autocomplete'\n//=  require 'rails_admin/flatpickr-with-locales'\n//=  require 'rails_admin/popper'\n//=  require 'rails_admin/bootstrap'\n\n//=  require 'rails_admin/abstract-select'\n//=  require 'rails_admin/filter-box'\n//=  require 'rails_admin/filtering-multiselect'\n//=  require 'rails_admin/filtering-select'\n//=  require 'rails_admin/remote-form'\n//=  require 'rails_admin/nested-form-hooks'\n//=  require 'rails_admin/i18n'\n//=  require 'rails_admin/widgets'\n//=  require 'rails_admin/sidescroll'\n//=  require 'rails_admin/ui'\n//=  require 'rails_admin/custom/ui'\n\n<% if defined?(ActiveStorage::Engine) %>\n//= require activestorage\n<% end %>\n<% if defined?(ActionText::Engine) && Rails.gem_version >= Gem::Version.new('7.0') %>\n//= require trix\n//= require actiontext\n<% end %>\n"
  },
  {
    "path": "app/assets/javascripts/rails_admin/custom/ui.js",
    "content": "// override this file in your application to add custom behaviour\n"
  },
  {
    "path": "app/assets/stylesheets/rails_admin/application.scss.erb",
    "content": "@charset \"UTF-8\";\n\n/***  Variables  ***/\n\n@import \"rails_admin/custom/variables\";\n@import \"rails_admin/styles/base/variables\";\n\n/***  Mixins  ***/\n\n@import \"rails_admin/styles/base/mixins\";\n@import \"rails_admin/custom/mixins\";\n\n/***  Bootstrap ***/\n\n@import \"rails_admin/bootstrap/bootstrap\";\n\n/***  Libraries  ***/\n\n@import \"rails_admin/flatpickr\";\n@import \"rails_admin/styles/filtering-select\";\n@import \"rails_admin/styles/filtering-multiselect\";\n@import \"rails_admin/styles/widgets\";\n\n/*** Font-awesome ***/\n\n@import \"rails_admin/font-awesome\";\n\n/***  RailsAdmin Theming  ***/\n\n@import \"rails_admin/styles/base/theming\";\n@import \"rails_admin/custom/theming\";\n\n<% if defined?(ActionText::Engine) && Rails.gem_version >= Gem::Version.new('7.0') %>\n@import \"trix\";\n<% end %>\n"
  },
  {
    "path": "app/assets/stylesheets/rails_admin/custom/mixins.scss",
    "content": "/*\n  Customize Sass mixins from Twitter-Bootstrap/RailsAdmin theme or add new ones for your own use.\n  Copy this file to your app/assets/rails_admin/custom/mixins.scss, leave this one untouched\n  Don't require it in your application.rb\n\n  Available mixins to use/override:\n\n  https://github.com/twbs/bootstrap-sass/tree/master/assets/stylesheets/bootstrap/mixins\n  https://github.com/railsadminteam/rails_admin/blob/master/src/rails_admin/styles/base/mixins.scss\n  Plus the ones from your theme.\n*/\n"
  },
  {
    "path": "app/assets/stylesheets/rails_admin/custom/theming.scss",
    "content": "/*\n  Customize RailsAdmin theme here.\n  Copy this file to your app/assets/stylesheets/rails_admin/custom/theming.scss, leave this one untouched\n  Don't require it in your application.rb\n\n  Look at the markup in RailsAdmin and go there to get inspiration from:\n\n  http://getbootstrap.com\n\n  Test me: (actual color should be the one defined in variables.scss if you did)\n\n  body { background-color: $link-color; }\n*/\n"
  },
  {
    "path": "app/assets/stylesheets/rails_admin/custom/variables.scss",
    "content": "/*\n  Customize Sass variables from Twitter-Bootstrap/RailsAdmin theme or add new ones for your own use.\n  Copy this file to your app/assets/rails_admin/custom/variables.scss, leave this one untouched\n  Don't require it in your application.rb\n\n  Available variables to use/override:\n\n  https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/_variables.scss\n  https://github.com/railsadminteam/rails_admin/blob/master/src/rails_admin/styles/base/variables.scss\n  Plus the ones from your themes.\n\n  Test me: pink links\n\n  $link-color: #F0F;\n*/\n"
  },
  {
    "path": "app/controllers/rails_admin/application_controller.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/abstract_model'\n\nmodule RailsAdmin\n  class ModelNotFound < ::StandardError\n  end\n\n  class ObjectNotFound < ::StandardError\n  end\n\n  class ActionNotAllowed < ::StandardError\n  end\n\n  class ApplicationController < Config.parent_controller.constantize\n    include RailsAdmin::Extensions::ControllerExtension\n\n    protect_from_forgery(Config.forgery_protection_settings)\n\n    before_action :_authenticate!\n    before_action :_authorize!\n    before_action :_audit!\n\n    helper_method :_current_user, :_get_plugin_name\n\n    attr_reader :object, :model_config, :abstract_model, :authorization_adapter\n\n    def get_model\n      @model_name = to_model_name(params[:model_name])\n      raise RailsAdmin::ModelNotFound unless (@abstract_model = RailsAdmin::AbstractModel.new(@model_name))\n      raise RailsAdmin::ModelNotFound if (@model_config = @abstract_model.config).excluded?\n\n      @properties = @abstract_model.properties\n    end\n\n    def get_object\n      raise RailsAdmin::ObjectNotFound unless (@object = @abstract_model.get(params[:id], @model_config.scope))\n    end\n\n    def to_model_name(param)\n      param.split('~').collect(&:camelize).join('::')\n    end\n\n    def _current_user\n      instance_eval(&RailsAdmin::Config.current_user_method)\n    end\n\n  private\n\n    def _get_plugin_name\n      @plugin_name_array ||= [RailsAdmin.config.main_app_name.is_a?(Proc) ? instance_eval(&RailsAdmin.config.main_app_name) : RailsAdmin.config.main_app_name].flatten\n    end\n\n    def _authenticate!\n      instance_eval(&RailsAdmin::Config.authenticate_with)\n    end\n\n    def _authorize!\n      instance_eval(&RailsAdmin::Config.authorize_with)\n    end\n\n    def _audit!\n      instance_eval(&RailsAdmin::Config.audit_with)\n    end\n\n    def rails_admin_controller?\n      true\n    end\n\n    rescue_from RailsAdmin::ObjectNotFound do\n      flash[:error] = I18n.t('admin.flash.object_not_found', model: @model_name, id: params[:id])\n      params[:action] = 'index'\n      @status_code = :not_found\n      index\n    end\n\n    rescue_from RailsAdmin::ModelNotFound do\n      flash[:error] = I18n.t('admin.flash.model_not_found', model: @model_name)\n      params[:action] = 'dashboard'\n      @status_code = :not_found\n      dashboard\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/rails_admin/main_controller.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  class MainController < RailsAdmin::ApplicationController\n    include ActionView::Helpers::TextHelper\n    include RailsAdmin::MainHelper\n    include RailsAdmin::ApplicationHelper\n\n    before_action :check_for_cancel\n\n    def bulk_action\n      get_model\n      process(params[:bulk_action]) if params[:bulk_action].in?(RailsAdmin::Config::Actions.all(:bulkable, controller: self, abstract_model: @abstract_model).collect(&:route_fragment))\n    end\n\n    def list_entries(model_config = @model_config, auth_scope_key = :index, additional_scope = get_association_scope_from_params, pagination = !(params[:associated_collection] || params[:all] || params[:bulk_ids]))\n      scope = model_config.scope\n      auth_scope = @authorization_adapter&.query(auth_scope_key, model_config.abstract_model)\n      scope = scope.merge(auth_scope) if auth_scope\n      scope = scope.instance_eval(&additional_scope) if additional_scope\n      get_collection(model_config, scope, pagination)\n    end\n\n  private\n\n    def action_missing(name, *_args)\n      action = RailsAdmin::Config::Actions.find(name.to_sym)\n      raise AbstractController::ActionNotFound.new(\"The action '#{name}' could not be found for #{self.class.name}\") unless action\n\n      get_model unless action.root?\n      get_object if action.member?\n      @authorization_adapter.try(:authorize, action.authorization_key, @abstract_model, @object)\n      @action = action.with({controller: self, abstract_model: @abstract_model, object: @object})\n      raise(ActionNotAllowed) unless @action.enabled?\n\n      @page_name = wording_for(:title)\n\n      instance_eval(&@action.controller)\n    end\n\n    def method_missing(name, *args, &block)\n      action = RailsAdmin::Config::Actions.find(name.to_sym)\n      if action\n        action_missing name, *args, &block\n      else\n        super\n      end\n    end\n\n    def respond_to_missing?(sym, include_private)\n      if RailsAdmin::Config::Actions.find(sym)\n        true\n      else\n        super\n      end\n    end\n\n    def back_or_index\n      allowed_return_to?(params[:return_to].to_s) ? params[:return_to] : index_path\n    end\n\n    def allowed_return_to?(url)\n      url != request.fullpath && url.start_with?(request.base_url, '/') && !url.start_with?('//')\n    end\n\n    def get_sort_hash(model_config)\n      field = model_config.list.fields.detect { |f| f.name.to_s == params[:sort] }\n      # If no sort param, default to the `sort_by` specified in the list config\n      field ||= model_config.list.possible_fields.detect { |f| f.name == model_config.list.sort_by.try(:to_sym) }\n\n      column =\n        if field.nil? || field.sortable == false # use default sort, asked field does not exist or is not sortable\n          model_config.list.sort_by\n        else\n          field.sort_column\n        end\n\n      params[:sort_reverse] ||= 'false'\n      {sort: column, sort_reverse: (params[:sort_reverse] == (field&.sort_reverse&.to_s || 'true'))}\n    end\n\n    def redirect_to_on_success\n      notice = I18n.t('admin.flash.successful', name: @model_config.label, action: I18n.t(\"admin.actions.#{@action.key}.done\"))\n      if params[:_add_another]\n        redirect_to new_path(return_to: params[:return_to]), flash: {success: notice}\n      elsif params[:_add_edit]\n        redirect_to edit_path(id: @object.id, return_to: params[:return_to]), flash: {success: notice}\n      else\n        redirect_to back_or_index, flash: {success: notice}\n      end\n    end\n\n    def visible_fields(action, model_config = @model_config)\n      model_config.send(action).with(controller: self, view: view_context, object: @object).visible_fields\n    end\n\n    def sanitize_params_for!(action, model_config = @model_config, target_params = params[@abstract_model.param_key])\n      return unless target_params.present?\n\n      fields = visible_fields(action, model_config)\n      allowed_methods = fields.collect(&:allowed_methods).flatten.uniq.collect(&:to_s) << 'id' << '_destroy'\n      fields.each { |field| field.parse_input(target_params) }\n      target_params.slice!(*allowed_methods)\n      target_params.permit! if target_params.respond_to?(:permit!)\n      fields.select(&:nested_form).each do |association|\n        children_params = association.multiple? ? target_params[association.method_name].try(:values) : [target_params[association.method_name]].compact\n        (children_params || []).each do |children_param|\n          sanitize_params_for!(:nested, association.associated_model_config, children_param)\n        end\n      end\n    end\n\n    def handle_save_error(whereto = :new)\n      flash.now[:error] = I18n.t('admin.flash.error', name: @model_config.label, action: I18n.t(\"admin.actions.#{@action.key}.done\").html_safe).html_safe\n      flash.now[:error] += %(<br>- #{@object.errors.full_messages.join('<br>- ')}).html_safe\n\n      respond_to do |format|\n        format.html { render whereto, status: :not_acceptable }\n        format.js   { render whereto, layout: 'rails_admin/modal', status: :not_acceptable, content_type: Mime[:html].to_s }\n      end\n    end\n\n    def check_for_cancel\n      return unless params[:_continue] || (params[:bulk_action] && !params[:bulk_ids])\n\n      redirect_to(back_or_index, notice: I18n.t('admin.flash.noaction'))\n    end\n\n    def get_collection(model_config, scope, pagination)\n      section = @action.key == :export ? model_config.export : model_config.list\n      eager_loads = section.fields.flat_map(&:eager_load_values)\n      options = {}\n      options = options.merge(page: (params[Kaminari.config.param_name] || 1).to_i, per: (params[:per] || model_config.list.items_per_page)) if pagination\n      options = options.merge(include: eager_loads) unless eager_loads.blank?\n      options = options.merge(get_sort_hash(model_config))\n      options = options.merge(query: params[:query]) if params[:query].present?\n      options = options.merge(filters: params[:f]) if params[:f].present?\n      options = options.merge(bulk_ids: params[:bulk_ids]) if params[:bulk_ids]\n      model_config.abstract_model.all(options, scope)\n    end\n\n    def get_association_scope_from_params\n      return nil unless params[:associated_collection].present?\n\n      source_abstract_model = RailsAdmin::AbstractModel.new(to_model_name(params[:source_abstract_model]))\n      source_model_config = source_abstract_model.config\n      source_object = source_abstract_model.get(params[:source_object_id])\n      action = params[:current_action].in?(%w[create update]) ? params[:current_action] : 'edit'\n      @association = source_model_config.send(action).fields.detect { |f| f.name == params[:associated_collection].to_sym }.with(controller: self, object: source_object)\n      @association.associated_collection_scope\n    end\n  end\nend\n"
  },
  {
    "path": "app/helpers/rails_admin/application_helper.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module ApplicationHelper\n    def authorized?(action_name, abstract_model = nil, object = nil)\n      object = nil if object.try :new_record?\n      action(action_name, abstract_model, object).try(:authorized?)\n    end\n\n    def current_action\n      params[:action].in?(%w[create new]) ? 'create' : 'update'\n    end\n\n    def current_action?(action, abstract_model = @abstract_model, object = @object)\n      @action.custom_key == action.custom_key &&\n        abstract_model.try(:to_param) == @abstract_model.try(:to_param) &&\n        (@object.try(:persisted?) ? @object.id == object.try(:id) : !object.try(:persisted?))\n    end\n\n    def action(key, abstract_model = nil, object = nil)\n      RailsAdmin::Config::Actions.find(key, controller: controller, abstract_model: abstract_model, object: object)\n    end\n\n    def actions(scope = :all, abstract_model = nil, object = nil)\n      RailsAdmin::Config::Actions.all(scope, controller: controller, abstract_model: abstract_model, object: object)\n    end\n\n    def edit_user_link\n      return nil unless _current_user.try(:email).present?\n      return nil unless (abstract_model = RailsAdmin.config(_current_user.class).abstract_model)\n\n      edit_action = action(:edit, abstract_model, _current_user)\n      authorized = edit_action.try(:authorized?)\n      content = edit_user_link_label\n\n      if authorized\n        edit_url = rails_admin.url_for(\n          action: edit_action.action_name,\n          model_name: abstract_model.to_param,\n          controller: 'rails_admin/main',\n          id: _current_user.id,\n        )\n\n        link_to content, edit_url, class: 'nav-link'\n      else\n        content_tag :span, content, class: 'nav-link'\n      end\n    end\n\n    def logout_path\n      if defined?(Devise)\n        scope = Devise::Mapping.find_scope!(_current_user)\n        begin\n          main_app.send(\"destroy_#{scope}_session_path\")\n        rescue StandardError\n          false\n        end\n      elsif main_app.respond_to?(:logout_path)\n        main_app.logout_path\n      end\n    end\n\n    def logout_method\n      return [Devise.sign_out_via].flatten.first if defined?(Devise)\n\n      :delete\n    end\n\n    def wording_for(label, action = @action, abstract_model = @abstract_model, object = @object)\n      model_config = abstract_model.try(:config)\n      object = nil unless abstract_model && object.is_a?(abstract_model.model)\n      action = RailsAdmin::Config::Actions.find(action.to_sym) if action.is_a?(Symbol) || action.is_a?(String)\n\n      I18n.t(\n        \"admin.actions.#{action.i18n_key}.#{label}\",\n        model_label: model_config&.label,\n        model_label_plural: model_config&.label_plural,\n        object_label: model_config && object.try(model_config.object_label_method),\n      )\n    end\n\n    def main_navigation\n      nodes_stack = RailsAdmin::Config.visible_models(controller: controller)\n      node_model_names = nodes_stack.collect { |c| c.abstract_model.model_name }\n      parent_groups = nodes_stack.group_by { |n| n.parent&.to_s }\n\n      nodes_stack.group_by(&:navigation_label).collect do |navigation_label, nodes|\n        nodes = nodes.select { |n| n.parent.nil? || !n.parent.to_s.in?(node_model_names) }\n        li_stack = navigation parent_groups, nodes\n\n        label = navigation_label || t('admin.misc.navigation')\n\n        collapsible_stack(label, 'main', li_stack)\n      end.join.html_safe\n    end\n\n    def root_navigation\n      actions(:root).select(&:show_in_sidebar).group_by(&:sidebar_label).collect do |label, nodes|\n        li_stack = nodes.map do |node|\n          url = rails_admin.url_for(action: node.action_name, controller: 'rails_admin/main')\n          nav_icon = node.link_icon ? %(<i class=\"#{node.link_icon}\"></i>).html_safe : ''\n          content_tag :li do\n            link_to nav_icon + \" \" + wording_for(:menu, node), url, class: \"nav-link\"\n          end\n        end.join.html_safe\n        label ||= t('admin.misc.root_navigation')\n\n        collapsible_stack(label, 'action', li_stack)\n      end.join.html_safe\n    end\n\n    def static_navigation\n      li_stack = RailsAdmin::Config.navigation_static_links.collect do |title, url|\n        content_tag(:li, link_to(title.to_s, url, target: '_blank', rel: 'noopener noreferrer', class: 'nav-link'))\n      end.join.html_safe\n\n      label = RailsAdmin::Config.navigation_static_label || t('admin.misc.navigation_static_label')\n      collapsible_stack(label, 'static', li_stack) || ''\n    end\n\n    def navigation(parent_groups, nodes, level = 0)\n      nodes.collect do |node|\n        abstract_model = node.abstract_model\n        model_param = abstract_model.to_param\n        url         = rails_admin.url_for(action: :index, controller: 'rails_admin/main', model_name: model_param)\n        nav_icon = node.navigation_icon ? %(<i class=\"#{node.navigation_icon}\"></i>).html_safe : ''\n        css_classes = ['nav-link']\n        css_classes.push(\"nav-level-#{level}\") if level > 0\n        css_classes.push('active') if @action && current_action?(@action, model_param)\n        li = content_tag :li, data: {model: model_param} do\n          link_to nav_icon + \" \" + node.label_plural, url, class: css_classes.join(' ')\n        end\n        child_nodes = parent_groups[abstract_model.model_name]\n        child_nodes ? li + navigation(parent_groups, child_nodes, level + 1) : li\n      end.join.html_safe\n    end\n\n    def breadcrumb(action = @action, _acc = [])\n      begin\n        (parent_actions ||= []) << action\n      end while action.breadcrumb_parent && (action = action(*action.breadcrumb_parent)) # rubocop:disable Lint/Loop\n\n      content_tag(:ol, class: 'breadcrumb') do\n        parent_actions.collect do |a|\n          am = a.send(:eval, 'bindings[:abstract_model]')\n          o = a.send(:eval, 'bindings[:object]')\n          content_tag(:li, class: ['breadcrumb-item', current_action?(a, am, o) && 'active']) do\n            if current_action?(a, am, o)\n              wording_for(:breadcrumb, a, am, o)\n            elsif a.http_methods.include?(:get)\n              link_to rails_admin.url_for(action: a.action_name, controller: 'rails_admin/main', model_name: am.try(:to_param), id: (o.try(:persisted?) && o.try(:id) || nil)) do\n                wording_for(:breadcrumb, a, am, o)\n              end\n            else\n              content_tag(:span, wording_for(:breadcrumb, a, am, o))\n            end\n          end\n        end.reverse.join.html_safe\n      end\n    end\n\n    # parent => :root, :collection, :member\n    # perf matters here (no action view trickery)\n    def menu_for(parent, abstract_model = nil, object = nil, only_icon = false)\n      actions = actions(parent, abstract_model, object).select { |a| a.http_methods.include?(:get) && a.show_in_menu }\n      actions.collect do |action|\n        wording = wording_for(:menu, action)\n        li_class = ['nav-item', 'icon', \"#{action.key}_#{parent}_link\"].\n                   concat(action.enabled? ? [] : ['disabled'])\n        content_tag(:li, {class: li_class}.merge(only_icon ? {title: wording, rel: 'tooltip'} : {})) do\n          label = content_tag(:i, '', {class: action.link_icon}) + ' ' + content_tag(:span, wording, (only_icon ? {style: 'display:none'} : {}))\n          if action.enabled? || !only_icon\n            href =\n              if action.enabled?\n                rails_admin.url_for(action: action.action_name, controller: 'rails_admin/main', model_name: abstract_model.try(:to_param), id: (object.try(:persisted?) && object.try(:id) || nil))\n              else\n                'javascript:void(0)'\n              end\n            content_tag(:a, label, {href: href, target: action.link_target, class: ['nav-link', current_action?(action) && 'active', !action.enabled? && 'disabled'].compact}.merge(action.turbo? ? {} : {data: {turbo: 'false'}}))\n          else\n            content_tag(:span, label)\n          end\n        end\n      end.join(' ').html_safe\n    end\n\n    def bulk_menu(abstract_model = @abstract_model)\n      actions = actions(:bulkable, abstract_model)\n      return '' if actions.empty?\n\n      content_tag :li, class: 'nav-item dropdown dropdown-menu-end' do\n        content_tag(:a, class: 'nav-link dropdown-toggle', data: {'bs-toggle': 'dropdown'}, href: '#') { t('admin.misc.bulk_menu_title').html_safe + ' ' + '<b class=\"caret\"></b>'.html_safe } +\n          content_tag(:ul, class: 'dropdown-menu', style: 'left:auto; right:0;') do\n            actions.collect do |action|\n              content_tag :li do\n                link_to wording_for(:bulk_link, action, abstract_model), '#', class: 'dropdown-item bulk-link', data: {action: action.action_name}\n              end\n            end.join.html_safe\n          end\n      end.html_safe\n    end\n\n    def flash_alert_class(flash_key)\n      case flash_key.to_s\n      when 'error'  then 'alert-danger'\n      when 'alert'  then 'alert-warning'\n      when 'notice' then 'alert-info'\n      else \"alert-#{flash_key}\"\n      end\n    end\n\n    def handle_asset_dependency_error\n      yield\n    rescue LoadError => e\n      if /sassc/.match?(e.message)\n        e = e.exception <<~MSG\n          #{e.message}\n          RailsAdmin requires the gem sassc-rails, make sure to put `gem 'sassc-rails'` to Gemfile.\n        MSG\n      end\n      raise e\n    end\n\n    # Workaround for https://github.com/rails/rails/issues/31325\n    def image_tag(source, options = {})\n      if %w[ActiveStorage::Variant ActiveStorage::VariantWithRecord ActiveStorage::Preview].include? source.class.to_s\n        super main_app.route_for(ActiveStorage.resolve_model_to_route, source), options\n      else\n        super\n      end\n    end\n\n  private\n\n    def edit_user_link_label\n      [\n        RailsAdmin::Config.show_gravatar &&\n          image_tag(gravatar_url(_current_user.email), alt: ''),\n\n        content_tag(:span, _current_user.email),\n      ].filter(&:present?).join.html_safe\n    end\n\n    def gravatar_url(email)\n      \"https://secure.gravatar.com/avatar/#{Digest::MD5.hexdigest email}?s=30\"\n    end\n\n    def collapsible_stack(label, class_prefix, li_stack)\n      return nil unless li_stack.present?\n\n      collapse_classname = \"#{class_prefix}-#{Digest::MD5.hexdigest(label)[0..7]}\"\n      content_tag(:li, class: 'mb-1') do\n        content_tag(:button, 'aria-expanded': true, class: 'btn btn-toggle align-items-center rounded', data: {bs_toggle: \"collapse\", bs_target: \".sidebar .#{collapse_classname}\"}) do\n          content_tag(:i, '', class: 'fas fa-chevron-down') + html_escape(' ' + label)\n        end +\n          content_tag(:div, class: \"collapse show #{collapse_classname}\") do\n            content_tag(:ul, class: 'btn-toggle-nav list-unstyled fw-normal pb-1') do\n              li_stack\n            end\n          end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/helpers/rails_admin/form_builder.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'nested_form/builder_mixin'\n\nmodule RailsAdmin\n  class FormBuilder < ::ActionView::Helpers::FormBuilder\n    include ::NestedForm::BuilderMixin\n    include ::RailsAdmin::ApplicationHelper\n\n    def generate(options = {})\n      without_field_error_proc_added_div do\n        options.reverse_merge!(\n          action: @template.controller.params[:action],\n          model_config: @template.instance_variable_get(:@model_config),\n          nested_in: false,\n        )\n\n        object_infos +\n          visible_groups(options[:model_config], generator_action(options[:action], options[:nested_in])).collect do |fieldset|\n            fieldset_for fieldset, options[:nested_in]\n          end.join.html_safe +\n          (options[:nested_in] ? '' : @template.render(partial: 'rails_admin/main/submit_buttons'))\n      end\n    end\n\n    def fieldset_for(fieldset, nested_in)\n      fields = fieldset.with(\n        form: self,\n        object: @object,\n        view: @template,\n        controller: @template.controller,\n      ).visible_fields\n      return if fields.empty?\n\n      @template.content_tag :fieldset do\n        contents = []\n        contents << @template.content_tag(:legend, %(<i class=\"fas fa-chevron-#{fieldset.active? ? 'down' : 'right'}\"></i> #{fieldset.label}).html_safe, style: fieldset.name == :default ? 'display:none' : '')\n        contents << @template.content_tag(:p, fieldset.help) if fieldset.help.present?\n        contents << fields.collect { |field| field_wrapper_for(field, nested_in) }.join\n        contents.join.html_safe\n      end\n    end\n\n    def field_wrapper_for(field, nested_in)\n      # do not show nested field if the target is the origin\n      return if nested_field_association?(field, nested_in)\n\n      @template.content_tag(:div, class: \"control-group row mb-3 #{field.type_css_class} #{field.css_class} #{'error' if field.errors.present?}\", id: \"#{dom_id(field)}_field\") do\n        if field.label\n          label(field.method_name, field.label, class: 'col-sm-2 col-form-label text-md-end') +\n            (field.nested_form ? field_for(field) : input_for(field))\n        else\n          field.nested_form ? field_for(field) : input_for(field)\n        end\n      end\n    end\n\n    def input_for(field)\n      css = 'col-sm-10 controls'\n      css += ' has-error' if field.errors.present?\n      @template.content_tag(:div, class: css) do\n        field_for(field) +\n          errors_for(field) +\n          help_for(field)\n      end\n    end\n\n    def errors_for(field)\n      field.errors.present? ? @template.content_tag(:span, field.errors.to_sentence, class: 'help-inline text-danger') : ''.html_safe\n    end\n\n    def help_for(field)\n      field.help.present? ? @template.content_tag(:div, field.help, class: 'form-text') : ''.html_safe\n    end\n\n    def field_for(field)\n      field.read_only? ? @template.content_tag(:div, field.pretty_value, class: 'form-control-static') : field.render\n    end\n\n    def object_infos\n      model_config = RailsAdmin.config(object)\n      model_label = model_config.label\n      object_label =\n        if object.new_record?\n          I18n.t('admin.form.new_model', name: model_label)\n        else\n          object.send(model_config.object_label_method).presence || \"#{model_config.label} ##{object.id}\"\n        end\n\n      %(<span style=\"display:none\" class=\"object-infos\" data-model-label=\"#{model_label}\" data-object-label=\"#{CGI.escapeHTML(object_label.to_s)}\"></span>).html_safe\n    end\n\n    def jquery_namespace(field)\n      %(#{'#modal ' if @template.controller.params[:modal]}##{dom_id(field)}_field)\n    end\n\n    def dom_id(field)\n      (@dom_id ||= {})[field.name] ||=\n        [\n          @object_name.to_s.gsub(/\\]\\[|[^-a-zA-Z0-9:.]/, '_').sub(/_$/, ''),\n          options[:index],\n          field.method_name,\n        ].reject(&:blank?).join('_')\n    end\n\n    def dom_name(field)\n      (@dom_name ||= {})[field.name] ||= %(#{@object_name}#{options[:index] && \"[#{options[:index]}]\"}[#{field.method_name}]#{field.is_a?(Config::Fields::Association) && field.multiple? ? '[]' : ''})\n    end\n\n    def hidden_field(method, options = {})\n      if method == :id && object.id.is_a?(Array)\n        super method, {value: RailsAdmin.config.composite_keys_serializer.serialize(object.id)}\n      else\n        super\n      end\n    end\n\n  protected\n\n    def generator_action(action, nested)\n      if nested\n        action = :nested\n      elsif @template.request.format == 'text/javascript'\n        action = :modal\n      end\n\n      action\n    end\n\n    def visible_groups(model_config, action)\n      model_config.send(action).with(\n        form: self,\n        object: @object,\n        view: @template,\n        controller: @template.controller,\n      ).visible_groups\n    end\n\n    def without_field_error_proc_added_div\n      default_field_error_proc = ::ActionView::Base.field_error_proc\n      begin\n        ::ActionView::Base.field_error_proc = proc { |html_tag, _instance| html_tag }\n        yield\n      ensure\n        ::ActionView::Base.field_error_proc = default_field_error_proc\n      end\n    end\n\n  private\n\n    def nested_field_association?(field, nested_in)\n      field.inverse_of.presence && nested_in.presence && field.inverse_of == nested_in.name &&\n        (@template.instance_variable_get(:@model_config).abstract_model == field.abstract_model ||\n         field.name == nested_in.inverse_of)\n    end\n  end\nend\n"
  },
  {
    "path": "app/helpers/rails_admin/main_helper.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module MainHelper\n    def rails_admin_form_for(*args, &block)\n      options = args.extract_options!.reverse_merge(builder: RailsAdmin::FormBuilder)\n      (options[:html] ||= {})[:novalidate] ||= !RailsAdmin::Config.browser_validations\n\n      form_for(*(args << options), &block) << after_nested_form_callbacks\n    end\n\n    def get_indicator(percent)\n      return '' if percent < 0          # none\n      return 'info' if percent < 34     # < 1/100 of max\n      return 'success' if percent < 67  # < 1/10 of max\n      return 'warning' if percent < 84  # < 1/3 of max\n\n      'danger'                          # > 1/3 of max\n    end\n\n    def filterable_fields\n      @filterable_fields ||= @model_config.list.fields.select(&:filterable?)\n    end\n\n    def ordered_filters\n      return @ordered_filters if @ordered_filters.present?\n\n      @index = 0\n      @ordered_filters = (params[:f].try(:permit!).try(:to_h) || @model_config.list.filters).inject({}) do |memo, filter|\n        field_name = filter.is_a?(Array) ? filter.first : filter\n        (filter.is_a?(Array) ? filter.last : {(@index += 1) => {'v' => ''}}).each do |index, filter_hash|\n          if filter_hash['disabled'].blank?\n            memo[index] = {field_name => filter_hash}\n          else\n            params[:f].delete(field_name)\n          end\n        end\n        memo\n      end.to_a.sort_by(&:first)\n    end\n\n    def ordered_filter_options\n      if ordered_filters\n        @ordered_filter_options ||= ordered_filters.map do |duplet|\n          filter_for_field = duplet[1]\n          filter_name = filter_for_field.keys.first\n          filter_hash = filter_for_field.values.first\n          unless (field = filterable_fields.find { |f| f.name == filter_name.to_sym }&.with({view: self}))\n            raise \"#{filter_name} is not currently filterable; filterable fields are #{filterable_fields.map(&:name).join(', ')}\"\n          end\n\n          field.filter_options.merge(\n            index: duplet[0],\n            operator: filter_hash['o'] || field.default_filter_operator,\n            value: filter_hash['v'],\n          )\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/views/kaminari/ra-twitter-bootstrap/_gap.html.erb",
    "content": "<li class=\"page-item disabled\">\n  <a href=\"#\" class=\"page-link\">\n    <%= raw(t 'admin.pagination.truncate') %>\n  </a>\n</li>\n"
  },
  {
    "path": "app/views/kaminari/ra-twitter-bootstrap/_next_page.html.erb",
    "content": "<% if current_page.last? %>\n  <li class=\"page-item next disabled\">\n    <%= link_to raw(t 'admin.pagination.next'), '#', class: 'page-link' %>\n  </li>\n<% else %>\n  <li class=\"page-item next\">\n    <%= link_to raw(t 'admin.pagination.next'), url, class: 'page-link' %>\n  </li>\n<% end %>\n"
  },
  {
    "path": "app/views/kaminari/ra-twitter-bootstrap/_page.html.erb",
    "content": "<% if page.current? %>\n  <li class=\"page-item active\">\n    <%= link_to page, url, class: 'page-link' %>\n  </li>\n<% else %>\n  <li class=\"page-item\">\n    <%= link_to page, url, class: 'page-link' %>\n  </li>\n<% end %>\n"
  },
  {
    "path": "app/views/kaminari/ra-twitter-bootstrap/_paginator.html.erb",
    "content": "<%= paginator.render do %>\n  <nav aria-label=\"Page navigation\">\n    <ul class=\"pagination\">\n      <%= prev_page_tag %>\n      <% each_page do |page| %>\n        <% if page.left_outer? or page.right_outer? or page.inside_window? %>\n          <%= page_tag page %>\n        <% elsif !page.was_truncated? %>\n          <%= gap_tag %>\n        <% end %>\n      <% end %>\n      <%= next_page_tag %>\n    </ul>\n  </nav>\n<% end %>\n"
  },
  {
    "path": "app/views/kaminari/ra-twitter-bootstrap/_prev_page.html.erb",
    "content": "<% if current_page.first? %>\n  <li class=\"page-item prev disabled\">\n    <%= link_to raw(t 'admin.pagination.previous'), '#', class: 'page-link' %>\n  </li>\n<% else %>\n  <li class=\"page-item prev\">\n    <%= link_to raw(t 'admin.pagination.previous'), url, class: 'page-link' %>\n  </li>\n<% end %>\n"
  },
  {
    "path": "app/views/kaminari/ra-twitter-bootstrap/without_count/_next_page.html.erb",
    "content": "<% if current_page.last? %>\n  <li class=\"page-item next disabled\">\n    <%= link_to raw(t 'admin.pagination.next'), '#', class: 'page-link' %>\n  </li>\n<% else %>\n  <li class=\"page-item next\">\n    <%= link_to raw(t 'admin.pagination.next'), url, class: 'page-link' %>\n  </li>\n<% end %>\n"
  },
  {
    "path": "app/views/kaminari/ra-twitter-bootstrap/without_count/_paginator.html.erb",
    "content": "<%= paginator.render do %>\n  <nav aria-label=\"Page navigation\">\n    <ul class=\"pagination\">\n      <%= prev_page_tag if !current_page.first? %>\n      <%= next_page_tag %>\n    </ul>\n  </nav>\n<% end %>\n"
  },
  {
    "path": "app/views/kaminari/ra-twitter-bootstrap/without_count/_prev_page.html.erb",
    "content": "<% if current_page.first? %>\n  <li class=\"page-item prev disabled\">\n    <%= link_to raw(t 'admin.pagination.previous'), '#', class: 'page-link' %>\n  </li>\n<% else %>\n  <li class=\"page-item prev\">\n    <%= link_to raw(t 'admin.pagination.previous'), url, class: 'page-link' %>\n  </li>\n<% end %>\n"
  },
  {
    "path": "app/views/layouts/rails_admin/_head.html.erb",
    "content": "<meta content=\"IE=edge\" http-equiv=\"X-UA-Compatible\">\n<meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n<meta content=\"width=device-width, initial-scale=1\" name=\"viewport; charset=utf-8\">\n<meta content=\"NONE,NOARCHIVE\" name=\"robots\">\n<meta content=\"false\" name=\"turbo-prefetch\">\n<%= csrf_meta_tag %>\n<% case RailsAdmin::config.asset_source\n   when :webpacker %>\n  <%= stylesheet_pack_tag \"rails_admin\", data: {'turbo-track': 'reload'} %>\n  <%= javascript_pack_tag \"rails_admin\", defer: true, data: {'turbo-track': 'reload'} %>\n<% when :sprockets %>\n  <% handle_asset_dependency_error do %>\n    <%= stylesheet_link_tag \"rails_admin/application.css\", media: :all, data: {'turbo-track': 'reload'} %>\n    <%= javascript_include_tag \"rails_admin/application.js\", defer: true, data: {'turbo-track': 'reload'} %>\n  <% end %>\n<% when :vite %>\n  <%= vite_javascript_tag \"rails_admin\", defer: true, data: {'turbo-track': 'reload'} %>\n<% when :webpack %>\n  <%= stylesheet_link_tag \"rails_admin.css\", media: :all, data: {'turbo-track': 'reload'} %>\n  <%= javascript_include_tag \"rails_admin.js\", defer: true, data: {'turbo-track': 'reload'} %>\n<% when :importmap %>\n  <%= stylesheet_link_tag \"rails_admin.css\", media: :all, data: {'turbo-track': 'reload'} %>\n  <%= javascript_inline_importmap_tag(RailsAdmin::Engine.importmap.to_json(resolver: self)) %>\n  <%= javascript_importmap_module_preload_tags(RailsAdmin::Engine.importmap) %>\n  <%= javascript_importmap_shim_nonce_configuration_tag if respond_to? :javascript_importmap_shim_nonce_configuration_tag %>\n  <%= javascript_importmap_shim_tag if respond_to? :javascript_importmap_shim_tag %>\n  <%= # Preload jQuery and make it global, unless jQuery UI fails to initialize\n      tag.script \"import jQuery from 'jquery'; window.jQuery = jQuery;\".html_safe, type: \"module\" %>\n  <%= javascript_import_module_tag 'rails_admin' %>\n<% else\n     raise \"Unknown asset_source: #{RailsAdmin::config.asset_source}\"\n   end %>\n"
  },
  {
    "path": "app/views/layouts/rails_admin/_navigation.html.erb",
    "content": "<div class=\"container-fluid\">\n  <a class=\"navbar-brand\" href=\"<%= dashboard_path %>\">\n    <%= _get_plugin_name[0] || 'Rails' %>\n    <small>\n      <%= _get_plugin_name[1] || 'Admin' %>\n    </small>\n  </a>\n  <button class=\"navbar-toggler\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#secondary-navigation\">\n    <span class=\"sr-only\">\n      <%= t('admin.toggle_navigation') %>\n    </span>\n    <span class=\"navbar-toggler-icon\"></span>\n  </button>\n  <div class=\"collapse navbar-collapse\" id=\"secondary-navigation\">\n    <%= render partial: 'layouts/rails_admin/secondary_navigation' %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/layouts/rails_admin/_secondary_navigation.html.erb",
    "content": "<ul class=\"navbar-nav ms-auto root_links\">\n  <% actions(:root).select(&:show_in_navigation).each do |action| %>\n    <li class=\"nav-item <%= action.action_name %>_root_link\">\n      <%= link_to wording_for(:menu, action), { action: action.action_name, controller: 'rails_admin/main' }, {class: ['nav-link']}.merge(action.turbo? ? {} : {data: {turbo: 'false'}}) %>\n    </li>\n  <% end %>\n  <% if main_app_root_path = (main_app.root_path rescue false) %>\n    <li class=\"nav-item\">\n      <%= link_to t('admin.home.name'), main_app_root_path, class: 'nav-link' %>\n    </li>\n  <% end %>\n  <% if _current_user %>\n    <% if user_link = edit_user_link %>\n      <li class=\"nav-item edit_user_root_link\">\n        <%= user_link %>\n      </li>\n    <% end %>\n    <% if logout_path.present? %>\n      <li class=\"nav-item\">\n        <%= link_to logout_path, method: logout_method, class: 'nav-link', data: {turbo: 'false'} do %>\n          <span class=\"badge bg-danger\"><%= t('admin.misc.log_out') %></span>\n        <% end %>\n      </li>\n    <% end %>\n  <% end %>\n</ul>\n"
  },
  {
    "path": "app/views/layouts/rails_admin/_sidebar_navigation.html.erb",
    "content": "<ul class=\"sidebar col-sm-3 col-md-2 nav btn-toggle-nav flex-column flex-nowrap bg-light\">\n  <%= main_navigation %>\n  <%= root_navigation %>\n  <%= static_navigation %>\n</ul>\n"
  },
  {
    "path": "app/views/layouts/rails_admin/application.html.erb",
    "content": "<!DOCTYPE html>\n<html lang=\"<%= I18n.locale %>\">\n  <head>\n    <%= render \"layouts/rails_admin/head\" %>\n  </head>\n  <body class=\"rails_admin\">\n    <div data-i18n-options=\"<%= I18n.t(\"admin.js\").to_json %>\" id=\"admin-js\"></div>\n    <div class=\"badge bg-warning\" id=\"loading\" style=\"display:none; position:fixed; right:20px; bottom:20px; z-index:100000\">\n      <%= t('admin.loading') %>\n    </div>\n    <nav class=\"navbar navbar-expand-md fixed-top <%= RailsAdmin::Config.navbar_css_classes.join(' ') %>\">\n      <%= render \"layouts/rails_admin/navigation\" %>\n    </nav>\n    <div class=\"container-fluid\">\n      <div class=\"row\">\n        <div class=\"col-sm-3 col-md-2 flex-wrap p-0\">\n          <%= render \"layouts/rails_admin/sidebar_navigation\" %>\n        </div>\n        <div class=\"col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2\">\n          <div class=\"container-fluid\">\n            <%= render template: 'layouts/rails_admin/content' %>\n          </div>\n        </div>\n      </div>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "app/views/layouts/rails_admin/content.html.erb",
    "content": "<title>\n  <%= \"#{@abstract_model.try(:pretty_name) || @page_name} | #{[_get_plugin_name[0] || 'Rails', _get_plugin_name[1] || 'Admin'].join(' ')}\" %>\n</title>\n<header class=\"py-2 m-2 border-bottom\" data-model=\"<%= @abstract_model.to_param %>\">\n  <h1>\n    <%= @page_name %>\n  </h1>\n</header>\n<% flash && flash.each do |key, value| %>\n  <div class=\"<%= flash_alert_class(key) %> alert alert-dismissible\">\n    <%= value %>\n    <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\" aria-label=\"Close\"></button>\n  </div>\n<% end %>\n<nav aria-label=\"breadcrumb\">\n  <%= breadcrumb %>\n</nav>\n<ul class=\"nav nav-tabs mb-3\">\n  <%= menu_for((@abstract_model ? (@object.try(:persisted?) ? :member : :collection) : :root), @abstract_model, @object) %>\n  <%= content_for :contextual_tabs %>\n</ul>\n<%= yield %>\n"
  },
  {
    "path": "app/views/layouts/rails_admin/modal.js.erb",
    "content": "<% flash && flash.each do |key, value| %>\n  <div class=\"<%= flash_alert_class(key) %> alert alert-dismissible\">\n    <%= value %>\n    <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\" aria-label=\"Close\"></button>\n  </div>\n<% end %>\n<%= yield %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_dashboard_history.html.erb",
    "content": "<table class=\"table table-condensed table-striped table-hover\">\n  <thead>\n    <tr>\n      <th class=\"shrink user\">\n        <%= t(\"admin.table_headers.username\") %>\n      </th>\n      <th class=\"shrink items\">\n        <%= t(\"admin.table_headers.item\") %>\n      </th>\n      <th class=\"changes\">\n        <%= t(\"admin.table_headers.changes\") %>\n      </th>\n    </tr>\n  </thead>\n  <tbody class=\"table-group-divider\">\n    <% @history.each do |t| %>\n      <% abstract_model = RailsAdmin.config(t.table).abstract_model %>\n      <tr>\n        <td>\n          <%= t.try :username %>\n        </td>\n        <% if o = abstract_model.try(:get, t.item) %>\n          <% label = o.send(abstract_model.config.object_label_method) %>\n          <% if show_action = action(:show, abstract_model, o) %>\n            <td>\n              <%= link_to(label, url_for(action: show_action.action_name, model_name: abstract_model.to_param, id: o.id)) %>\n            </td>\n          <% else %>\n            <td>\n              <%= label %>\n            </td>\n          <% end %>\n        <% else %>\n          <% label = Object.const_defined?(t.table) ? t.table.constantize.model_name.human : t.table %>\n          <td>\n            <%= \"#{label} ##{t.item}\" %>\n          </td>\n        <% end %>\n        <td>\n          <%= t.message %>\n        </td>\n      </tr>\n    <% end %>\n  </tbody>\n</table>\n"
  },
  {
    "path": "app/views/rails_admin/main/_delete_notice.html.erb",
    "content": "<% object = delete_notice %>\n<li style=\"display:block; margin-top:10px\">\n  <span class=\"label label-default\">\n    <%= @abstract_model.pretty_name %>\n  </span>\n  <% wording = object.send(@model_config.object_label_method) %>\n  <% if show_action = action(:show, @abstract_model, object) %>\n    <%= link_to(wording, url_for(action: show_action.action_name, model_name: @abstract_model.to_param, id: object.id)) %>\n  <% else %>\n    <%= wording %>\n  <% end %>\n  <ul>\n    <% @abstract_model.each_associated_children(object) do |association, children| %>\n      <% humanized_association = @abstract_model.model.human_attribute_name association.name %>\n      <% limit = children.count > 12 ? 10 : children.count %>\n      <% children.first(limit).each do |child| %>\n        <%= content_tag :li, class: dom_class(child) do %>\n          <% child_config = RailsAdmin.config(child) %>\n          <%= humanized_association.singularize %>\n          <% wording = child.send(child_config.object_label_method) %>\n          <% if child.id && (show_action = action(:show, child_config.abstract_model, child)) %>\n            <%= link_to(wording, url_for(action: show_action.action_name, model_name: child_config.abstract_model.to_param, id: child.id)) %>\n          <% else %>\n            <%= wording %>\n          <% end %>\n        <% end %>\n      <% end %>\n      <% if children.count > limit %>\n        <li>\n          <%= t('admin.misc.more', count: children.count - limit, models_name: humanized_association) %>\n        </li>\n      <% end %>\n    <% end %>\n  </ul>\n</li>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_action_text.html.erb",
    "content": "<%\n  js_data = {\n    csspath: field.css_location,\n    jspath: field.js_location,\n    warn_dynamic_load: field.warn_dynamic_load\n  }\n%>\n<%= form.rich_text_area field.method_name, field.html_attributes.reverse_merge(data: { options: js_data.to_json }) %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_boolean.html.erb",
    "content": "<% if field.nullable? %>\n  <div class=\"btn-group\" role=\"group\">\n    <% {'1': [true, 'btn-outline-success'], '0': [false, 'btn-outline-danger'], '': [nil, 'btn-outline-secondary']}.each do |text, (value, btn_class)| %>\n      <%= form.radio_button field.method_name, text, field.html_attributes.reverse_merge({ checked: field.form_value == value, required: field.required, class: 'btn-check' }) %>\n      <%= form.label \"#{field.method_name}_#{text}\", class: \"#{field.css_classes[value]} btn #{btn_class}\" do %>\n        <%= field.labels[value].html_safe %>\n      <% end %>\n    <% end %>\n  </div>\n<% else %>\n  <div class=\"col-form-label\">\n    <%= form.send field.view_helper, field.method_name, field.html_attributes.reverse_merge({ value: field.form_value, checked: field.form_value.in?([true, '1']), required: field.required, class: 'form-check-input' }) %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_ck_editor.html.erb",
    "content": "<%\n  js_data = {\n    jspath: field.location ? field.location : field.base_location + \"ckeditor.js\",\n    base_location: field.base_location,\n    options: {\n      customConfig: field.config_js ? field.config_js : field.base_location + \"config.js\"\n    }\n  }\n%>\n<%= form.text_area field.method_name, field.html_attributes.reverse_merge(data: { richtext: 'ckeditor', options: js_data.to_json }).reverse_merge({ value: field.form_value }) %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_code_mirror.html.erb",
    "content": "<%\n  js_data = {\n    csspath: field.css_location,\n    jspath: field.js_location,\n    options: field.config,\n    locations: field.assets\n  }\n%>\n<%= form.text_area field.method_name, field.html_attributes.reverse_merge(data: { richtext: 'codemirror', options: js_data.to_json }).reverse_merge({ value: field.form_value }) %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_colorpicker.html.erb",
    "content": "<div class=\"row\">\n  <div class=\"col-sm-2\">\n    <%= form.send field.view_helper, field.method_name, field.html_attributes.reverse_merge({class: 'form-control', value: field.form_value}) %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_datetime.html.erb",
    "content": "<div class=\"row\">\n  <div class=\"col-sm-4\">\n    <div class=\"input-group\">\n      <%= form.text_field field.method_name, field.html_attributes.reverse_merge({autocomplete: 'off', class: 'form-control', data: {datetimepicker: true, options: field.datepicker_options.to_json}, value: field.form_value}) %>\n      <%= form.label(field.method_name, class: 'input-group-text') do %>\n        <i class=\"fa fa-fw fa-calendar\"></i>\n      <% end %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_enumeration.html.erb",
    "content": "<% unless field.multiple? %>\n  <div class=\"row\">\n    <div class=\"col-sm-4\">\n      <%= form.select field.method_name, field.enum, { include_blank: true }.reverse_merge({ selected: field.form_value }), field.html_attributes.reverse_merge({ data: { enumeration: true }, placeholder: t('admin.misc.search') }) %>\n    </div>\n  </div>\n<% else %>\n  <%\n    js_data = {\n      xhr: false,\n      sortable: false,\n      cacheAll: true,\n      regional: {\n        add: t(\"admin.misc.add_new\"),\n        chooseAll: t(\"admin.misc.chose_all\"),\n        clearAll: t(\"admin.misc.clear_all\"),\n        down: t(\"admin.misc.down\"),\n        remove: t(\"admin.misc.remove\"),\n        search: t(\"admin.misc.search\"),\n        up: t(\"admin.misc.up\")\n      }\n    }\n  %>\n  <%= form.select field.method_name, field.enum, { selected: field.form_value, object: form.object }, field.html_attributes.reverse_merge({data: { filteringmultiselect: true, options: js_data.to_json }, multiple: true}) %>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_field.html.erb",
    "content": "<%= form.send field.view_helper, field.method_name, field.html_attributes.reverse_merge({ value: field.form_value, class: 'form-control', required: field.required}) %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_file_upload.html.erb",
    "content": "<% file = field.value %>\n<% if field.cache_method %>\n  <%= form.hidden_field(field.cache_method, value: field.cache_value) %>\n<% end %>\n<div class=\"toggle mb-2\" style=\"<%= ('display:none;' if file && field.delete_method && form.object.send(field.delete_method) == '1') %>\">\n  <% if value = field.pretty_value %>\n    <%= value %>\n  <% end %>\n  <%= form.file_field(field.name, {data: {fileupload: true}}.deep_merge(field.html_attributes)) %>\n</div>\n<% if field.optional? && field.errors.blank? && file && field.delete_method %>\n  <a class=\"btn btn-info btn-remove-image\" data-toggle=\"button\" href=\"#\" role=\"button\">\n    <i class=\"fas fa-trash\"></i>\n    <%= I18n.t('admin.actions.delete.link', object_label: field.label) %>\n  </a>\n  <%= form.check_box(field.delete_method, style: 'display:none;') %>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_filtering_multiselect.html.erb",
    "content": "<%\n  config = field.associated_model_config\n%>\n\n<div class=\"row\">\n  <div class=\"col-auto\">\n    <input name=\"<%= form.dom_name(field) %>\" type=\"hidden\" />\n    <%=\n      form.select field.method_name, field.collection, { selected: field.form_value, object: form.object },\n                  field.html_attributes.reverse_merge({data: { filteringmultiselect: true, options: field.widget_options.to_json }, multiple: true})\n    %>\n  </div>\n  <% if authorized?(:new, config.abstract_model) && field.inline_add %>\n    <div class=\"col-sm-4 modal-actions\">\n      <% path_hash = { model_name: config.abstract_model.to_param, modal: true }.merge!(field.associated_prepopulate_params) %>\n      <%= link_to \"<i class=\\\"fas fa-plus\\\"></i> \".html_safe + wording_for(:link, :new, config.abstract_model), '#', data: { link: new_path(path_hash) }, class: \"create btn btn-info\", style: 'margin-left:10px' %>\n    </div>\n  <% end %>\n</div>"
  },
  {
    "path": "app/views/rails_admin/main/_form_filtering_select.html.erb",
    "content": "<%\n  config = field.associated_model_config\n%>\n\n<div class=\"row\">\n  <div class=\"col-sm-4\">\n    <%=\n      form.select field.method_name, field.collection, { selected: field.form_value, include_blank: true },\n                  field.html_attributes.reverse_merge({ data: { filteringselect: true, options: field.widget_options.to_json }, placeholder: t('admin.misc.search') })\n    %>\n  </div>\n  <div class=\"col-sm-8 mt-2 mt-md-0 modal-actions\">\n    <% if authorized?(:new, config.abstract_model) && field.inline_add %>\n      <% path_hash = { model_name: config.abstract_model.to_param, modal: true }.merge!(field.associated_prepopulate_params) %>\n      <%= link_to \"<i class=\\\"fas fa-plus\\\"></i> \".html_safe + wording_for(:link, :new, config.abstract_model), '#', data: { link: new_path(path_hash) }, class: \"btn btn-info create\" %>\n    <% end %>\n    <% if authorized?(:edit, config.abstract_model) && field.inline_edit %>\n      <%= link_to \"<i class=\\\"fas fa-pencil-alt\\\"></i> \".html_safe + wording_for(:link, :edit, config.abstract_model), '#', data: { link: edit_path(model_name: config.abstract_model.to_param, modal: true, id: '__ID__') }, class: \"btn btn-info update ms-2#{' disabled' if field.value.nil?}\" %>\n    <% end %>\n  </div>\n</div>"
  },
  {
    "path": "app/views/rails_admin/main/_form_froala.html.erb",
    "content": "<%\n  js_data = {\n    csspath: field.css_location,\n    jspath: field.js_location,\n    config_options: field.config_options.to_json\n  }\n%>\n<%= form.text_area field.method_name, field.html_attributes.reverse_merge(data: { richtext: 'froala-wysiwyg', options: js_data.to_json }).reverse_merge({ value: field.form_value }) %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_multiple_file_upload.html.erb",
    "content": "<% field.attachments.each_with_index do |attachment, i| %>\n  <div class=\"<%= field.reorderable? ? 'sortables' : '' %> toggle mb-2\">\n    <%= attachment.pretty_value %>\n    <% if field.delete_method || field.keep_method %>\n      <a class=\"btn btn-info btn-remove-image\" data-toggle=\"button\" href=\"#\" role=\"button\">\n        <i class=\"fas fa-trash\"></i>\n        <%= I18n.t('admin.form.delete_file', field_label: field.label, number: i + 1) %>\n      </a>\n      <% if field.keep_method %>\n        <%= form.check_box(field.keep_method, {multiple:true, checked: true, style: 'display:none;'}, attachment.keep_value, nil) %>\n      <% elsif field.delete_method %>\n        <%= form.check_box(field.delete_method, {multiple:true, style: 'display:none;'}, attachment.delete_value, nil) %>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n<%= form.file_field(field.name, { data: { :\"multiple-fileupload\" => true }, multiple: true }.deep_merge(field.html_attributes)) %>\n<% if field.cache_method %>\n  <%= form.hidden_field(field.cache_method) %>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_nested_many.html.erb",
    "content": "<div class=\"controls col-sm-10\" data-nestedmany=\"true\">\n  <div class=\"btn-group\">\n    <a class=\"<%= (field.active? ? 'active' : '') %> btn btn-info toggler\" data-bs-target=\"<%= form.jquery_namespace(field) %> .collapse\" data-bs-toggle=\"collapse\" role=\"button\">\n      <i class=\"fas\"></i>\n    </a>\n    <% if field.inline_add %>\n      <%= form.link_to_add \"<i class=\\\"fas fa-plus\\\"></i> #{wording_for(:link, :new, field.associated_model_config.abstract_model)}\".html_safe, field.name, { class: 'btn btn-info' } %>\n    <% end %>\n  </div>\n  <%= form.errors_for(field) %>\n  <%= form.help_for(field) %>\n  <ul class=\"nav nav-tabs collapse\"></ul>\n</div>\n<div class=\"tab-content collapse\">\n  <%= form.fields_for field.name do |nested_form| %>\n    <% if field.nested_form[:allow_destroy] || nested_form.options[:child_index] == \"new_#{field.name}\" %>\n      <%= nested_form.link_to_remove '<span class=\"btn btn-danger\"><i class=\"fas fa-trash\"></i></span>'.html_safe %>\n    <% end %>\n    <%= nested_form.generate({action: :nested, model_config: field.associated_model_config, nested_in: field }) %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_nested_one.html.erb",
    "content": "<div class=\"controls col-sm-10\" data-nestedone=\"true\">\n  <ul class=\"nav collapse\"></ul>\n  <div class=\"btn-group\">\n    <a class=\"<%= (field.active? ? 'active' : '') %> btn btn-info toggler\" data-bs-target=\"<%= form.jquery_namespace(field) %> .collapse\" data-bs-toggle=\"collapse\" role=\"button\">\n      <i class=\"fas\"></i>\n    </a>\n    <% if field.inline_add %>\n      <%= form.link_to_add \"<i class=\\\"fas fa-plus\\\"></i> #{wording_for(:link, :new, field.associated_model_config.abstract_model)}\".html_safe, field.name, { class: 'btn btn-info', :'data-add-label' => \"<i class=\\\"fas fa-plus\\\"></i> #{wording_for(:link, :new, field.associated_model_config.abstract_model)}\".gsub(\"\\n\", \"\") } %>\n    <% end %>\n  </div>\n  <%= form.errors_for(field) %>\n  <%= form.help_for(field) %>\n</div>\n<div class=\"tab-content collapse\">\n  <%= form.fields_for field.name do |nested_form| %>\n    <% if field.nested_form[:allow_destroy] %>\n      <%= nested_form.link_to_remove '<span class=\"btn btn-danger\"><i class=\"fas fa-trash\"></i></span>'.html_safe %>\n    <% end %>\n    <%= nested_form.generate({action: :nested, model_config: field.associated_model_config, nested_in: field }) %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_polymorphic_association.html.erb",
    "content": "<%\n  column_type_dom_id = form.dom_id(field).sub(field.method_name.to_s, field.type_column)\n%>\n\n<div class=\"row\">\n  <div class=\"col-sm-3\">\n    <% field.widget_options_for_types.each do |model, value| %>\n      <div data-options=\"<%= value.to_json %>\" id=\"<%= model %>-js-options\"></div>\n    <% end %>\n    <%=\n      form.select field.type_column, field.type_collection, {include_blank: true, selected: field.selected_type},\n                  class: \"form-select\", id: column_type_dom_id, data: { polymorphic: true, urls: field.type_urls.to_json },\n                  style: \"float: left; margin-right: 10px;\"\n    %>\n  </div>\n  <div class=\"col-sm-4\">\n    <%=\n      form.select field.method_name, field.collection, {include_blank: true, selected: field.selected_id},\n                  class: \"form-control\", data: { filteringselect: true, options: field.widget_options },\n                  placeholder: 'Search'\n    %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_simple_mde.html.erb",
    "content": "<%\n  js_data = {\n    js_location: field.js_location,\n    css_location: field.css_location,\n    instance_config: field.instance_config\n  }\n%>\n<%= form.text_area field.method_name, field.html_attributes.reverse_merge(data: { richtext: 'simplemde', options: js_data.to_json }).reverse_merge({ value: field.form_value }) %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_text.html.erb",
    "content": "<%= form.text_area field.method_name, field.html_attributes.reverse_merge(data: { richtext: false, options: {}.to_json }).reverse_merge({ value: field.form_value, class: 'form-control', required: field.required }) %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_form_wysihtml5.html.erb",
    "content": "<%\n  js_data = {\n    csspath: field.css_location,\n    jspath: field.js_location,\n    config_options: field.config_options.to_json\n  }\n%>\n<%= form.text_area field.method_name, field.html_attributes.reverse_merge(data: { richtext: 'bootstrap-wysihtml5', options: js_data.to_json }).reverse_merge({ value: field.form_value }) %>\n"
  },
  {
    "path": "app/views/rails_admin/main/_submit_buttons.html.erb",
    "content": "<div class=\"form-actions row justify-content-end my-3\">\n  <div class=\"col-sm-10\">\n    <input name=\"return_to\" type=\"<%= :hidden %>\" value=\"<%= (params[:return_to].presence || request.referer) %>\" />\n    <button class=\"btn btn-primary\" data-disable-with=\"<%= t(\"admin.form.save\") %>\" name=\"_save\" type=\"submit\"<%= ' disabled' unless @action.enabled? %>>\n      <i class=\"fas fa-check\"></i>\n      <%= t(\"admin.form.save\") %>\n    </button>\n    <span class=\"extra_buttons\">\n      <% if @action.enabled? && authorized?(:new, @abstract_model) %>\n        <button class=\"btn btn-info\" data-disable-with=\"<%= t(\"admin.form.save_and_add_another\") %>\" name=\"_add_another\" type=\"submit\">\n          <%= t(\"admin.form.save_and_add_another\") %>\n        </button>\n      <% end %>\n      <% if @action.enabled? && authorized?(:edit, @abstract_model) %>\n        <button class=\"btn btn-info\" data-disable-with=\"<%= t(\"admin.form.save_and_edit\") %>\" name=\"_add_edit\" type=\"submit\"<%= ' disabled' unless @action.enabled? %>>\n          <%= t(\"admin.form.save_and_edit\") %>\n        </button>\n      <% end %>\n      <button class=\"btn btn-light\" data-disable-with=\"<%= t(\"admin.form.cancel\") %>\" formnovalidate=\"<%= true %>\" name=\"_continue\" type=\"submit\">\n        <i class=\"fas fa-times\"></i>\n        <%= t(\"admin.form.cancel\") %>\n      </button>\n    </span>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/rails_admin/main/bulk_delete.html.erb",
    "content": "<h4>\n  <%= I18n.t('admin.form.bulk_delete') %>\n</h4>\n<ul>\n  <%= render partial: \"delete_notice\", collection: @objects %>\n</ul>\n<%= form_tag bulk_delete_path(model_name: @abstract_model.to_param, bulk_ids: @objects.map(&:id)), method: :delete do %>\n  <div class=\"form-actions\">\n    <input name=\"return_to\" type=\"<%= :hidden %>\" value=\"<%= (params[:return_to].presence || request.referer) %>\" />\n    <button class=\"btn btn-danger\" data-disable-with=\"<%= t(\"admin.form.confirmation\") %>\" type=\"submit\">\n      <i class=\"fas fa-check\"></i>\n      <%= t(\"admin.form.confirmation\") %>\n    </button>\n    <button class=\"btn\" data-disable-with=\"<%= t(\"admin.form.cancel\") %>\" name=\"_continue\" type=\"submit\">\n      <i class=\"fas fa-times\"></i>\n      <%= t(\"admin.form.cancel\") %>\n    </button>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/dashboard.html.erb",
    "content": "<% if @abstract_models %>\n  <table class=\"table table-condensed table-striped table-hover\">\n    <thead>\n      <tr>\n        <th class=\"shrink model-name\">\n          <%= t \"admin.table_headers.model_name\" %>\n        </th>\n        <th class=\"shrink last-created\">\n          <%= t \"admin.table_headers.last_created\" %>\n        </th>\n        <th class=\"records\">\n          <%= t \"admin.table_headers.records\" %>\n        </th>\n        <th class=\"shrink controls\"></th>\n      </tr>\n    </thead>\n    <tbody class=\"table-group-divider\">\n      <% @abstract_models.each do |abstract_model| %>\n        <% if authorized? :index, abstract_model %>\n          <% index_path = index_path(model_name: abstract_model.to_param) %>\n          <% row_class = \"#{cycle(\"odd\", \"even\")}#{\" link\" if index_path} #{abstract_model.param_key}_links\" %>\n          <tr class=\"<%= row_class %>\" data-link=\"<%= index_path %>\">\n            <% last_created = @most_recent_created[abstract_model.model.name] %>\n            <% active = last_created.try(:today?) %>\n            <td>\n              <span class=\"show\">\n                <%= link_to abstract_model.config.label_plural, index_path %>\n              </span>\n            </td>\n            <td>\n              <% if last_created %>\n                <%= t \"admin.misc.time_ago\", time: time_ago_in_words(last_created), default: \"#{time_ago_in_words(last_created)} #{t(\"admin.misc.ago\")}\" %>\n              <% end %>\n            </td>\n            <td>\n              <% count = @count[abstract_model.model.name] %>\n              <% percent = count > 0 ? (@max <= 1 ? count : ((Math.log(count+1) * 100.0) / Math.log(@max+1)).to_i) : -1 %>\n              <div class=\"<%= active ? 'active progress-bar-striped ' : '' %>progress\" style=\"margin-bottom:0px\">\n                <div class=\"bg-<%= get_indicator(percent) %> progress-bar animate-width-to\" data-animate-length=\"<%= ([1.0, percent].max.to_i * 20) %>\" data-animate-width-to=\"<%= [2.0, percent].max.to_i %>%\" style=\"width:2%\">\n                  <%= @count[abstract_model.model.name] %>\n                </div>\n              </div>\n            </td>\n            <td class=\"links\">\n              <ul class=\"nav d-inline list-inline\">\n                <%= menu_for :collection, abstract_model, nil, true %>\n              </ul>\n            </td>\n          </tr>\n        <% end %>\n      <% end %>\n    </tbody>\n  </table>\n<% end %>\n<% if @history && authorized?(:history_index) %>\n  <div class=\"block\" id=\"block-tables\">\n    <div class=\"content\">\n      <h2>\n        <%= t(\"admin.actions.history_index.menu\") %>\n      </h2>\n      <%= render partial: 'rails_admin/main/dashboard_history' %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/delete.html.erb",
    "content": "<h4>\n  <%= t(\"admin.form.are_you_sure_you_want_to_delete_the_object\", model_name: @abstract_model.pretty_name.downcase) %>\n  <q><strong><%= @model_config.with(object: @object).object_label %></strong></q>\n  <%= t(\"admin.form.all_of_the_following_related_items_will_be_deleted\") %>\n</h4>\n<ul>\n  <%= render partial: \"delete_notice\", object: @object %>\n</ul>\n<%= form_for(@object, url: delete_path(model_name: @abstract_model.to_param, id: @object.id), html: {method: \"delete\"}) do %>\n  <input name=\"return_to\" type=\"<%= :hidden %>\" value=\"<%= (params[:return_to].presence || request.referer) %>\" />\n  <div class=\"form-actions\">\n    <button class=\"btn btn-danger\" data-disable-with=\"<%= t(\"admin.form.confirmation\") %>\" type=\"submit\">\n      <i class=\"fas fa-check\"></i>\n      <%= t(\"admin.form.confirmation\") %>\n    </button>\n    <button class=\"btn\" data-disable-with=\"<%= t(\"admin.form.cancel\") %>\" name=\"_continue\" type=\"submit\">\n      <i class=\"fas fa-times\"></i>\n      <%= t(\"admin.form.cancel\") %>\n    </button>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/edit.html.erb",
    "content": "<%= rails_admin_form_for @object, url: edit_path(@abstract_model, @object.id), as: @abstract_model.param_key, html: { method: \"put\", multipart: true, class: \"main\", data: { title: @page_name } } do |form| %>\n  <%= form.generate action: :update %>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/export.html.erb",
    "content": "<% params = request.params.except(:action, :controller, :utf8, :page, :per_page, :format, :authenticity_token) %>\n<% visible_fields = @model_config.export.with(view: self, object: @abstract_model.model.new, controller: self.controller).visible_fields %>\n<%= form_tag export_path(params.merge(all: true)), method: 'post', class: \"main\", data: {turbo: false} do %>\n  <input name=\"send_data\" type=\"hidden\" value=\"true\" />\n  <fieldset id=\"fields_to_export\" class=\"mb-3\">\n    <legend>\n      <i class=\"fas fa-chevron-down\"></i>\n      <%= t('admin.export.select') %>\n    </legend>\n    <div class=\"form-group control-group\">\n      <div class=\"col-sm-12\">\n        <div class=\"checkbox\">\n          <label for=\"check_all\">\n            <%= check_box_tag 'all', 'all', true, { id: 'check_all' } %>\n            <b>\n              <%= t('admin.export.select_all_fields') %>\n            </b>\n          </label>\n        </div>\n      </div>\n    </div>\n    <div class=\"control-group row\">\n      <div class=\"col-sm-12\">\n        <div class=\"card bg-light my-2 reverse-selection\" rel=\"tooltip\" role=\"button\" title=\"<%= t('admin.export.click_to_reverse_selection') %>\">\n          <div class=\"card-body p-2\">\n            <b><%= t('admin.export.fields_from', name: @model_config.label_plural.downcase) %></b>\n          </div>\n        </div>\n        <div class=\"controls\">\n          <div class=\"row\">\n            <% visible_fields.select{ |f| !f.association? || f.association.polymorphic? }.each do |field| %>\n              <% list = field.virtual? ? 'methods' : 'only' %>\n              <div class=\"checkbox col-sm-3 my-1\">\n                <% if field.association? && field.association.polymorphic? %>\n                  <label for=\"schema_<%= list %>_<%= field.method_name %>\">\n                    <%= check_box_tag \"schema[#{list}][]\", field.method_name, true, { id: \"schema_#{list}_#{field.method_name}\" } %>\n                    <%= field.label + \" [id]\" %>\n                  </label>\n                  <% polymorphic_type_column_name = @abstract_model.properties.detect {|p| field.association.foreign_type == p.name }.name %>\n                  <label for=\"schema_<%= list %>_<%= polymorphic_type_column_name %>\">\n                    <%= check_box_tag \"schema[#{list}][]\", polymorphic_type_column_name, true, { id: \"schema_#{list}_#{polymorphic_type_column_name}\" } %>\n                    <%= field.label + \" [type]\" %>\n                  </label>\n                <% else %>\n                  <label for=\"schema_<%= list %>_<%= field.name %>\">\n                    <%= check_box_tag \"schema[#{list}][]\", field.name, true, { id: \"schema_#{list}_#{field.name}\" } %>\n                    <%= field.label %>\n                  </label>\n                <% end %>\n              </div>\n            <% end %>\n          </div>\n        </div>\n      </div>\n    </div>\n    <% visible_fields.select{ |f| f.association? && !f.association.polymorphic? }.each do |field| %>\n      <% fields = field.associated_model_config.export.with(controller: self.controller, view: self, object: (associated_model = field.associated_model_config.abstract_model.model).new).visible_fields.select{ |f| !f.association? } %>\n      <div class=\"control-group row\">\n        <div class=\"col-sm-12\">\n          <div class=\"card bg-light my-2 reverse-selection\" rel=\"tooltip\" role=\"button\" title=\"<%= t('admin.export.click_to_reverse_selection') %>\">\n            <div class=\"card-body p-2\">\n              <b><%= t('admin.export.fields_from_associated', name: field.label.downcase) %></b>\n            </div>\n          </div>\n          <div class=\"controls\">\n            <div class=\"row\">\n              <% fields.each do |associated_model_field| %>\n                <% list = associated_model_field.virtual? ? 'methods' : 'only' %>\n                <div class=\"checkbox col-sm-3 my-1\">\n                  <label for=\"schema_include_<%= field.name %>_<%= list %>_<%= associated_model_field.name %>\">\n                    <%= check_box_tag \"schema[include][#{field.name}][#{list}][]\", associated_model_field.name, true, { id: \"schema_include_#{field.name}_#{list}_#{associated_model_field.name}\" } %>\n                    <%= associated_model_field.label %>\n                  </label>\n                </div>\n              <% end %>\n            </div>\n          </div>\n        </div>\n      </div>\n    <% end %>\n  </fieldset>\n  <fieldset>\n    <legend>\n      <i class=\"fas fa-chevron-down\"></i>\n      <%= t('admin.export.options_for', name: 'csv') %>\n    </legend>\n    <div class=\"control-group row\">\n      <% guessed_encoding = @abstract_model.encoding %>\n      <label class=\"col-sm-2 col-form-label text-md-end\" for=\"csv_options_encoding_to\">\n        <%= t('admin.export.csv.encoding_to') %>\n      </label>\n      <div class=\"col-sm-10 controls\">\n        <div class=\"w-50\">\n          <%= select_tag 'csv_options[encoding_to]', options_for_select(Encoding.name_list.sort), include_blank: true, placeholder: t('admin.misc.search'), :'data-enumeration' => true %>\n        </div>\n        <p class=\"form-text\">\n          <%= t('admin.export.csv.encoding_to_help', name: guessed_encoding) %>\n        </p>\n      </div>\n    </div>\n    <div class=\"control-group row\">\n      <label class=\"col-sm-2 col-form-label text-md-end\" for=\"csv_options_skip_header\">\n        <%= t('admin.export.csv.skip_header') %>\n      </label>\n      <div class=\"col-sm-10 controls\">\n        <div class=\"col-form-label\">\n          <label>\n            <%= check_box_tag 'csv_options[skip_header]', 'true' %>\n          </label>\n        </div>\n        <p class=\"form-text\">\n          <%= t('admin.export.csv.skip_header_help') %>\n        </p>\n      </div>\n    </div>\n    <div class=\"control-group row\">\n      <label class=\"col-sm-2 col-form-label text-md-end\" for=\"csv_options_generator_col_sep\">\n        <%= t('admin.export.csv.col_sep') %>\n      </label>\n      <div class=\"col-sm-10 controls\">\n        <div class=\"w-50\">\n          <%= select_tag 'csv_options[generator][col_sep]', options_for_select({ '' => t('admin.export.csv.default_col_sep'), \"<comma> ','\" => ',', \"<semicolon> ';'\" => ';', '<tabs>' => \"'\\t'\" }), placeholder: t('admin.misc.search'), :'data-enumeration' => true %>\n        </div>\n        <p class=\"form-text\">\n          <%= t('admin.export.csv.col_sep_help', value: t('admin.export.csv.default_col_sep')) %>\n        </p>\n      </div>\n    </div>\n  </fieldset>\n  <div class=\"form-actions row justify-content-end mb-3\">\n    <div class=\"col-sm-offset-2 col-sm-10\">\n      <input name=\"return_to\" type=\"<%= :hidden %>\" value=\"<%= (params[:return_to].presence || request.referer) %>\" />\n      <button class=\"btn btn-primary\" name=\"csv\" type=\"submit\">\n        <i class=\"fas fa-check\"></i>\n        <%= t(\"admin.export.confirmation\", name: 'csv') %>\n      </button>\n      <button class=\"btn btn-info\" name=\"json\" type=\"submit\">\n        <%= t(\"admin.export.confirmation\", name: 'json') %>\n      </button>\n      <button class=\"btn btn-info\" name=\"xml\" type=\"submit\">\n        <%= t(\"admin.export.confirmation\", name: 'xml') %>\n      </button>\n      <button class=\"btn btn-light\" name=\"_continue\" type=\"submit\">\n        <i class=\"fas fa-times\"></i>\n        <%= t(\"admin.form.cancel\") %>\n      </button>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/history.html.erb",
    "content": "<% params = request.params.except(:action, :controller, :model_name) %>\n<% query = params[:query] %>\n<% filter = params[:filter] %>\n<% sort = params[:sort] %>\n<% sort_reverse = params[:sort_reverse] %>\n<% path_method = params[:id] ? \"history_show_path\" : \"history_index_path\" %>\n<%= form_tag(\"\", method: \"get\", class: \"search form-inline\") do %>\n  <div class=\"card mb-3 p-3 bg-light\">\n    <div class=\"row\">\n      <div class=\"col-sm-6\">\n        <div class=\"input-group\">\n          <input class=\"form-control\" name=\"query\" placeholder=\"<%= t(\"admin.misc.filter\") %>\" type=\"search\" value=\"<%= query %>\" />\n          <button class=\"btn btn-primary\" data-disable-with=\"<%= '<i class=\"fas fa-sync\"></i> ' + t('admin.misc.refresh') %>\" type=\"submit\">\n            <i class=\"fas fa-sync\"></i>\n            <%= t(\"admin.misc.refresh\") %>\n          </button>\n        </div>\n      </div>\n    </div>\n  </div>\n<% end %>\n<table class=\"table table-condensed table-striped table-hover\" id=\"history\">\n  <thead>\n    <tr>\n      <% columns = [] %>\n      <% columns << { property_name: \"created_at\", css_class: \"created_at\",link_text: t('admin.table_headers.created_at') } %>\n      <% columns << { property_name: \"username\",   css_class: \"username\",  link_text: t('admin.table_headers.username')   } %>\n      <% columns << { property_name: \"item\",       css_class: \"item\",      link_text: t('admin.table_headers.item')       } if @general %>\n      <% columns << { property_name: \"message\",    css_class: \"message\",   link_text: t('admin.table_headers.message')    } %>\n      <% columns.each do |column| %>\n        <% property_name = column[:property_name] %>\n        <% selected = (sort == property_name) %>\n        <% sort_direction = (sort_reverse ? \"headerSortUp\" : \"headerSortDown\" if selected) %>\n        <% sort_location = send(path_method, params.except(\"sort_reverse\").merge(model_name: @abstract_model.to_param, sort: property_name).merge(selected && sort_reverse != \"true\" ? {sort_reverse: \"true\"} : {})) %>\n        <th class=\"header <%= column[:css_class] %> <%= sort_direction if selected %>\" data-href=\"<%= sort_location %>\">\n          <%= column[:link_text] %>\n        </th>\n      <% end %>\n    </tr>\n  </thead>\n  <tbody class=\"table-group-divider\">\n    <% @history.each_with_index do |object, index| %>\n      <tr>\n        <% unless object.created_at.nil? %>\n          <td>\n            <%= l(object.created_at, format: :long, default: l(object.created_at, format: :long)) %>\n          </td>\n        <% end %>\n        <td>\n          <%= object.username %>\n        </td>\n        <% if @general %>\n          <% if o = @abstract_model.get(object.item) %>\n            <% label = o.send(@abstract_model.config.object_label_method) %>\n            <% if show_action = action(:show, @abstract_model, o) %>\n              <td>\n                <%= link_to(label, url_for(action: show_action.action_name, model_name: @abstract_model.to_param, id: o.id)) %>\n              </td>\n            <% else %>\n              <td>\n                <%= label %>\n              </td>\n            <% end %>\n          <% else %>\n            <td>\n              <%= \"#{@abstract_model.config.label} ##{object.item}\" %>\n            </td>\n          <% end %>\n        <% end %>\n        <td>\n          <%= object.message.in?(['delete', 'new']) ? t(\"admin.actions.#{object.message}.done\").capitalize : object.message %>\n        </td>\n      </tr>\n    <% end %>\n  </tbody>\n</table>\n<% unless params[:all] || !@history.respond_to?(:current_page) %>\n  <%= paginate(@history, theme: 'ra-twitter-bootstrap') %>\n  <%= link_to(t(\"admin.misc.show_all\"), send(path_method, params.merge(all: true)), class: \"show-all btn btn-light\") unless (tc = @history.total_count) <= @history.size || tc > 100 %>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/index.html.erb",
    "content": "<%\n  query = params[:query]\n  params = request.params.except(:authenticity_token, :action, :controller, :utf8, :bulk_export)\n  params.delete(:query) if params[:query].blank?\n  params.delete(:sort_reverse) unless params[:sort_reverse] == 'true'\n  sort_reverse = params[:sort_reverse]\n  sort = params[:sort]\n  params.delete(:sort) if params[:sort] == @model_config.list.sort_by.to_s\n  export_action = RailsAdmin::Config::Actions.find(:export, { controller: self.controller, abstract_model: @abstract_model })\n  export_action = nil unless export_action && authorized?(export_action.authorization_key, @abstract_model)\n  description = RailsAdmin.config(@abstract_model.model_name).description\n  properties = @model_config.list.with(controller: self.controller, view: self, object: @abstract_model.model.new).fields_for_table\n  checkboxes = @model_config.list.checkboxes?\n  table_table_header_count = begin\n    count = checkboxes ? 1 : 0\n    count = count + properties.count\n  end\n%>\n\n<% content_for :contextual_tabs do %>\n  <% if filterable_fields.present? %>\n    <li class=\"nav-item dropdown\">\n      <a class=\"nav-link dropdown-toggle\" data-bs-toggle=\"dropdown\" href=\"#\">\n        <%= t('admin.misc.add_filter') %>\n        <b class=\"caret\"></b>\n      </a>\n      <ul class=\"dropdown-menu dropdown-menu-end\" id=\"filters\">\n        <% filterable_fields.each do |field| %>\n          <li>\n            <a\n              href=\"#\"\n              class=\"dropdown-item\"\n              data-options=\"<%= field.with(view: self).filter_options.to_json %>\"\n            >\n              <%= field.label %>\n            </a>\n          </li>\n        <% end %>\n      </ul>\n    </li>\n  <% end %>\n  <% if checkboxes %>\n    <%= bulk_menu %>\n  <% end %>\n<% end %>\n\n<style>\n  <% properties.select{ |p| p.column_width.present? }.each do |property| %>\n    <%= \"#list th.#{property.css_class} { width: #{property.column_width}px; min-width: #{property.column_width}px; }\" %>\n    <%= \"#list td.#{property.css_class} { max-width: #{property.column_width}px;}\" %>\n  <% end %>\n</style>\n\n<div id=\"list\">\n  <%= form_tag(index_path(params.except(*%w[page f query])), method: :get) do %>\n    <div class=\"card mb-3 p-3 bg-light\">\n      <div class=\"row\" data-options=\"<%= ordered_filter_options.to_json %>\" id=\"filters_box\"></div>\n      <hr class=\"filters_box\" style=\"display:<%= ordered_filters.empty? ? 'none' : 'block' %>\"/>\n      <div class=\"row\">\n        <div class=\"col-sm-6\">\n          <div class=\"input-group\">\n            <input class=\"form-control\" name=\"query\" placeholder=\"<%= t(\"admin.misc.filter\") %>\" type=\"search\" value=\"<%= query %>\" />\n            <button class=\"btn btn-primary\" data-disable-with=\"<%= '<i class=\"fas fa-sync\"></i>' + t('admin.misc.refresh') %>\" type=\"submit\">\n              <i class=\"fas fa-sync\"></i>\n              <%= t('admin.misc.refresh') %>\n            </button>\n            <button class=\"btn btn-info\" id=\"remove_filter\" title=\"<%= t('admin.misc.reset_filters') %>\">\n              <i class=\"fas fa-times\"></i>\n            </button>\n          </div>\n          <% if @model_config.list.search_help.present? %>\n            <div class=\"form-text\"><%= @model_config.list.search_help %></div>\n          <% end %>\n        </div>\n        <div class=\"col-sm-6 text-end\">\n          <% if export_action %>\n            <%= link_to wording_for(:link, export_action), export_path(params.except('page')), class: 'btn btn-info' %>\n          <% end %>\n        </div>\n      </div>\n    </div>\n  <% end %>\n  <% unless @model_config.list.scopes.empty? %>\n    <ul class=\"nav nav-tabs\" id=\"scope_selector\">\n      <% @model_config.list.scopes.each_with_index do |scope, index| %>\n        <% scope = '_all' if scope.nil? %>\n        <li class=\"nav-item\">\n          <a href=\"<%= index_path(params.merge(scope: scope, page: nil)) %>\" class=\"nav-link <%= 'active' if scope.to_s == params[:scope] || (params[:scope].blank? && index == 0) %>\">\n            <%= I18n.t(\"admin.scopes.#{@abstract_model.to_param}.#{scope}\", default: I18n.t(\"admin.scopes.#{scope}\", default: scope.to_s.titleize)) %>\n          </a>\n        </li>\n      <% end %>\n    </ul>\n  <% end %>\n  <%= form_tag bulk_action_path(model_name: @abstract_model.to_param), method: :post, id: \"bulk_form\", class: [\"form\", \"mb-3\"] do %>\n    <%= hidden_field_tag :bulk_action %>\n    <% if description.present? %>\n      <p>\n        <strong>\n          <%= description %>\n        </strong>\n      </p>\n    <% end %>\n    <div id=\"sidescroll\">\n      <table class=\"table table-condensed table-striped table-hover\">\n        <thead>\n          <tr>\n            <% if checkboxes %>\n              <th class=\"shrink sticky\">\n                <input class=\"toggle\" type=\"checkbox\" />\n              </th>\n            <% end %>\n            <% properties.each do |property| %>\n              <% selected = (sort == property.name.to_s) %>\n              <% if property.sortable %>\n                <% sort_location = index_path params.except('sort_reverse').except('page').merge(sort: property.name).merge(selected && sort_reverse != \"true\" ? {sort_reverse: \"true\"} : {}) %>\n                <% sort_direction = (sort_reverse == 'true' ? \"headerSortUp\" : \"headerSortDown\" if selected) %>\n              <% end %>\n              <th class=\"<%= [property.sortable && \"header\", property.sortable && sort_direction, property.sticky? && 'sticky', property.css_class, property.type_css_class].select(&:present?).join(' ') %>\" data-href=\"<%= property.sortable && sort_location %>\" rel=\"tooltip\" title=\"<%= property.hint %>\">\n                <%= property.label %>\n              </th>\n            <% end %>\n            <th class=\"last shrink\"></th>\n          </tr>\n        </thead>\n        <tbody class=\"table-group-divider\">\n          <% @objects.each do |object| %>\n            <tr class=\"<%= @abstract_model.param_key %>_row <%= @model_config.list.with(object: object).row_css_class %>\">\n              <% if checkboxes %>\n                <td class=\"sticky\">\n                  <%= check_box_tag \"bulk_ids[]\", object.id.to_s, false %>\n                </td>\n              <% end %>\n              <% properties.map{ |property| property.bind(:object, object) }.each do |property| %>\n                <% value = property.pretty_value %>\n                <%= content_tag(:td, class: [property.sticky? && 'sticky', property.css_class, property.type_css_class].select(&:present?), title: strip_tags(value.to_s)) do %>\n                  <%= value %>\n                <% end %>\n              <% end %>\n              <td class=\"last links ra-sidescroll-frozen\">\n                <ul class=\"nav d-inline list-inline\">\n                  <%= menu_for :member, @abstract_model, object, true %>\n                </ul>\n              </td>\n            </tr>\n          <% end %>\n          <% if @objects.empty? %>\n            <tr class=\"empty_row\">\n              <td colspan=\"<%= table_table_header_count %>\">\n                <%= I18n.t('admin.actions.index.no_records') %>\n              </td>\n            </tr>\n          <% end %>\n        </tbody>\n      </table>\n    </div>\n    <% if @model_config.list.limited_pagination %>\n      <div class=\"row\">\n        <div class=\"col-md-6\">\n          <%= paginate(@objects, theme: 'ra-twitter-bootstrap/without_count', total_pages: Float::INFINITY) %>\n        </div>\n      </div>\n    <% elsif @objects.respond_to?(:total_count) %>\n      <% total_count = @objects.total_count.to_i %>\n      <div class=\"row\">\n        <div class=\"col-md-6\">\n          <%= paginate(@objects, theme: 'ra-twitter-bootstrap') %>\n        </div>\n      </div>\n      <div class=\"row\">\n        <div class=\"col-md-6\">\n          <%= link_to(t(\"admin.misc.show_all\"), index_path(params.merge(all: true)), class: \"show-all btn btn-light clearfix\") unless total_count > 100 || total_count <= @objects.to_a.size %>\n        </div>\n      </div>\n      <div class=\"clearfix total-count\">\n        <%= \"#{total_count} #{@model_config.pluralize(total_count).downcase}\" %>\n      </div>\n    <% else %>\n      <div class=\"clearfix total-count\">\n        <%= \"#{@objects.size} #{@model_config.pluralize(@objects.size).downcase}\" %>\n      </div>\n    <% end %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/rails_admin/main/new.html.erb",
    "content": "<%= rails_admin_form_for @object, url: new_path(model_name: @abstract_model.to_param), as: @abstract_model.param_key, html: { multipart: true, class: \"main\", data: { title: @page_name } } do |form| %>\n  <%= form.generate action: :create %>\n<% end %>\n"
  },
  {
    "path": "app/views/rails_admin/main/show.html.erb",
    "content": "<% @model_config.show.with(object: @object, view: self, controller: self.controller).visible_groups.each do |fieldset| %>\n  <% unless (fields = fieldset.with(object: @object, view: self, controller: self.controller).visible_fields).empty? %>\n    <% unless (fields = fields.reject{ |f| RailsAdmin::config.compact_show_view && (f.formatted_value.nil? || f.formatted_value == '') }).empty? %>\n      <div class=\"fieldset\">\n        <h4>\n          <%= fieldset.label %>\n        </h4>\n        <% if fieldset.help %>\n          <p>\n            <%= fieldset.help %>\n          </p>\n        <% end %>\n        <div class=\"list-group\">\n          <% fields.each_with_index do |field, index| %>\n            <div class=\"list-group-item border-0 <%= field.type_css_class %> <%= field.css_class %>\">\n              <div class=\"card\">\n                <h5 class=\"card-header bg-light\">\n                  <%= field.label %>\n                </h5>\n                <div class=\"card-body\">\n                  <%= field.pretty_value %>\n                </div>\n              </div>\n            </div>\n          <% end %>\n        </dl>\n      </div>\n    <% end %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "config/initializers/active_record_extensions.rb",
    "content": "# frozen_string_literal: true\n\nActiveSupport.on_load(:active_record) do\n  module ActiveRecord\n    class Base\n      def self.rails_admin(&block)\n        RailsAdmin.config(self, &block)\n      end\n\n      def rails_admin_default_object_label_method\n        new_record? ? \"new #{self.class}\" : \"#{self.class} ##{id}\"\n      end\n\n      def safe_send(value)\n        if has_attribute?(value)\n          read_attribute(value)\n        else\n          send(value)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "config/initializers/mongoid_extensions.rb",
    "content": "# frozen_string_literal: true\n\nif defined?(::Mongoid::Document)\n  require 'rails_admin/adapters/mongoid/extension'\n  Mongoid::Document.include RailsAdmin::Adapters::Mongoid::Extension\nend\n"
  },
  {
    "path": "config/locales/rails_admin.en.yml",
    "content": "en:\n  admin:\n    js:\n      true: \"True\"\n      false: \"False\"\n      is_present: Is present\n      is_blank: Is blank\n      date: Date ...\n      between_and_: Between ... and ...\n      today: Today\n      yesterday: Yesterday\n      this_week: This week\n      last_week: Last week\n      time: Time ...\n      number: Number ...\n      contains: Contains\n      does_not_contain: Does not contain\n      is_exactly: Is exactly\n      starts_with: Starts with\n      ends_with: Ends with\n      too_many_objects: \"Too many objects, use search box above\"\n      no_objects: \"No objects found\"\n      clear: Clear\n    loading: \"Loading...\"\n    toggle_navigation: Toggle navigation\n    home:\n      name: \"Home\"\n    pagination:\n      previous: \"&laquo; Prev\"\n      next: \"Next &raquo;\"\n      truncate: \"…\"\n    misc:\n      search: \"Search\"\n      filter: \"Filter\"\n      reset_filters: \"Reset filters\"\n      refresh: \"Refresh\"\n      show_all: \"Show all\"\n      add_filter: \"Add filter\"\n      bulk_menu_title: \"Selected items\"\n      remove: \"Remove\"\n      add_new: \"Add new\"\n      chose_all: \"Choose all\"\n      clear_all: \"Clear all\"\n      up: \"Up\"\n      down: \"Down\"\n      navigation: \"Navigation\"\n      root_navigation: \"Actions\"\n      navigation_static_label: \"Links\"\n      log_out: \"Log out\"\n      time_ago: \"%{time} ago\"\n      ago: \"ago\"\n      more: \"Plus %{count} more %{models_name}\"\n    flash:\n      successful: \"%{name} successfully %{action}\"\n      error: \"%{name} failed to be %{action}\"\n      noaction: \"No actions were taken\"\n      model_not_found: \"Model '%{model}' could not be found\"\n      object_not_found: \"%{model} with id '%{id}' could not be found\"\n    table_headers:\n      model_name: \"Model name\"\n      last_created: \"Last created\"\n      records: \"Records\"\n      username: \"User\"\n      changes: \"Changes\"\n      created_at: \"Date/Time\"\n      item: \"Item\"\n      message: \"Message\"\n    actions:\n      dashboard:\n        title: \"Site Administration\"\n        menu: \"Dashboard\"\n        breadcrumb: \"Dashboard\"\n      index:\n        title: \"List of %{model_label_plural}\"\n        menu: \"List\"\n        breadcrumb: \"%{model_label_plural}\"\n        no_records: \"No records found\"\n      show:\n        title: \"Details for %{model_label} '%{object_label}'\"\n        menu: \"Show\"\n        breadcrumb: \"%{object_label}\"\n      show_in_app:\n        menu: \"Show in app\"\n      new:\n        title: \"New %{model_label}\"\n        menu: \"Add new\"\n        breadcrumb: \"New\"\n        link: \"Add a new %{model_label}\"\n        done: \"created\"\n      edit:\n        title: \"Edit %{model_label} '%{object_label}'\"\n        menu: \"Edit\"\n        breadcrumb: \"Edit\"\n        link: \"Edit this %{model_label}\"\n        done: \"updated\"\n      delete:\n        title: \"Delete %{model_label} '%{object_label}'\"\n        menu: \"Delete\"\n        breadcrumb: \"Delete\"\n        link: \"Delete '%{object_label}'\"\n        done: \"deleted\"\n      bulk_delete:\n        title: \"Delete %{model_label_plural}\"\n        menu: \"Multiple delete\"\n        breadcrumb: \"Multiple delete\"\n        bulk_link: \"Delete selected %{model_label_plural}\"\n      export:\n        title: \"Export %{model_label_plural}\"\n        menu: \"Export\"\n        breadcrumb: \"Export\"\n        link: \"Export found %{model_label_plural}\"\n        bulk_link: \"Export selected %{model_label_plural}\"\n        done: \"exported\"\n      history_index:\n        title: \"History for %{model_label_plural}\"\n        menu: \"History\"\n        breadcrumb: \"History\"\n      history_show:\n        title: \"History for %{model_label} '%{object_label}'\"\n        menu: \"History\"\n        breadcrumb: \"History\"\n    form:\n      cancel: \"Cancel\"\n      basic_info: \"Basic info\"\n      required: \"Required\"\n      optional: \"Optional\"\n      one_char: \"character\"\n      char_length_up_to: \"length up to\"\n      char_length_of: \"length of\"\n      save: \"Save\"\n      save_and_add_another: \"Save and add another\"\n      save_and_edit: \"Save and edit\"\n      delete_file: \"Delete '%{field_label}' #%{number}\"\n      all_of_the_following_related_items_will_be_deleted: \"? The following related items may be deleted or orphaned:\"\n      are_you_sure_you_want_to_delete_the_object: \"Are you sure you want to delete this %{model_name}\"\n      confirmation: \"Yes, I'm sure\"\n      bulk_delete: \"The following objects will be deleted, which may delete or orphan some of their related dependencies:\"\n      new_model: \"%{name} (new)\"\n    export:\n      confirmation: \"Export to %{name}\"\n      select: \"Select fields to export\"\n      select_all_fields: \"Select All Fields\"\n      fields_from: \"Fields from %{name}\"\n      fields_from_associated: \"Fields from associated %{name}\"\n      display: \"Display %{name}: %{type}\"\n      options_for: \"Options for %{name}\"\n      empty_value_for_associated_objects: \"<empty>\"\n      click_to_reverse_selection: \"Click to reverse selection\"\n      csv:\n        header_for_root_methods: \"%{name}\" # 'model' is available\n        header_for_association_methods: \"%{name} [%{association}]\"\n        encoding_to: \"Encode to\"\n        encoding_to_help: \"Choose output encoding. Leave empty to let current input encoding untouched: (%{name})\"\n        skip_header: \"No header\"\n        skip_header_help: \"Do not output a header (no fields description)\"\n        default_col_sep: \",\"\n        col_sep: \"Column separator\"\n        col_sep_help: \"Leave blank for default ('%{value}')\" # value is default_col_sep\n"
  },
  {
    "path": "config/routes.rb",
    "content": "# frozen_string_literal: true\n\nRailsAdmin::Engine.routes.draw do\n  controller 'main' do\n    RailsAdmin::Config::Actions.all(:root).each { |action| match \"/#{action.route_fragment}\", action: action.action_name, as: action.action_name, via: action.http_methods }\n    scope ':model_name' do\n      RailsAdmin::Config::Actions.all(:collection).each { |action| match \"/#{action.route_fragment}\", action: action.action_name, as: action.action_name, via: action.http_methods }\n      post '/bulk_action', action: :bulk_action, as: 'bulk_action'\n      scope ':id' do\n        RailsAdmin::Config::Actions.all(:member).each { |action| match \"/#{action.route_fragment}\", action: action.action_name, as: action.action_name, via: action.http_methods }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "gemfiles/composite_primary_keys.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"appraisal\", \">= 2.0\"\ngem \"devise\", \"~> 4.7\"\ngem \"net-smtp\", require: false\ngem \"rails\", \"~> 7.0.0\", \"7.0.8.6\"\ngem \"sassc-rails\", \"~> 2.1\"\ngem \"turbo-rails\"\ngem \"vite_rails\", require: false\ngem \"webpacker\", require: false\ngem \"webrick\"\ngem \"concurrent-ruby\", \"1.3.4\"\n\ngroup :development, :test do\n  gem \"pry\", \">= 0.9\"\nend\n\ngroup :test do\n  gem \"cancancan\", \"~> 3.0\"\n  gem \"carrierwave\", [\">= 2.0.0.rc\", \"< 3\"]\n  gem \"cuprite\", \"!= 0.15.1\"\n  gem \"database_cleaner-active_record\", \">= 2.0\", require: false\n  gem \"dragonfly\", \"~> 1.0\"\n  gem \"factory_bot\", \">= 4.2\", \"!= 6.4.5\"\n  gem \"generator_spec\", \">= 0.8\"\n  gem \"kt-paperclip\"\n  gem \"launchy\", \">= 2.2\"\n  gem \"mini_magick\", \">= 3.4\"\n  gem \"pundit\"\n  gem \"rack-cache\", require: \"rack/cache\"\n  gem \"rspec-expectations\", \"!= 3.8.3\"\n  gem \"rspec-rails\", \">= 4.0.0.beta2\"\n  gem \"rspec-retry\"\n  gem \"rubocop\", [\"~> 1.20\", \"!= 1.22.2\"], require: false\n  gem \"rubocop-performance\", require: false\n  gem \"shrine\", \"~> 3.0\"\n  gem \"simplecov\", \">= 0.9\", require: false\n  gem \"simplecov-lcov\", require: false\n  gem \"timecop\", \">= 0.5\"\n  gem \"tzinfo-data\", platforms: [:mingw, :mswin, :x64_mingw, :jruby]\nend\n\ngroup :active_record do\n  gem \"paper_trail\", \">= 12.0\"\n  gem \"composite_primary_keys\"\n\n  platforms :ruby, :mswin, :mingw, :x64_mingw do\n    gem \"mysql2\", \">= 0.3.14\"\n    gem \"pg\", \">= 1.0.0\"\n    gem \"sqlite3\", \"~> 1.3\"\n  end\nend\n\ngemspec path: \"../\"\n"
  },
  {
    "path": "gemfiles/rails_6.0.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"appraisal\", \">= 2.0\"\ngem \"devise\", \"~> 4.7\"\ngem \"net-smtp\", require: false\ngem \"rails\", \"~> 6.0.0\"\ngem \"sassc-rails\", \"~> 2.1\"\ngem \"turbo-rails\", \"< 2.0.8\"\ngem \"vite_rails\", require: false\ngem \"webpacker\", require: false\ngem \"webrick\"\ngem \"concurrent-ruby\", \"1.3.4\"\ngem \"psych\", \"~> 3.3\"\n\ngroup :development, :test do\n  gem \"pry\", \">= 0.9\"\nend\n\ngroup :test do\n  gem \"cancancan\", [\"~> 3.0\", \"< 3.6\"]\n  gem \"carrierwave\", [\">= 2.0.0.rc\", \"< 3\"]\n  gem \"cuprite\", \"!= 0.15.1\"\n  gem \"database_cleaner-active_record\", \">= 2.0\", require: false\n  gem \"dragonfly\", \"~> 1.0\"\n  gem \"factory_bot\", \">= 4.2\", \"!= 6.4.5\"\n  gem \"generator_spec\", \">= 0.8\"\n  gem \"kt-paperclip\"\n  gem \"launchy\", \">= 2.2\"\n  gem \"mini_magick\", \">= 3.4\"\n  gem \"pundit\", \"~> 2.1.0\"\n  gem \"rack-cache\", require: \"rack/cache\"\n  gem \"rspec-expectations\", \"!= 3.8.3\"\n  gem \"rspec-rails\", \">= 4.0.0.beta2\"\n  gem \"rspec-retry\"\n  gem \"rubocop\", [\"~> 1.20\", \"!= 1.22.2\"], require: false\n  gem \"rubocop-performance\", require: false\n  gem \"shrine\", \"~> 3.0\"\n  gem \"simplecov\", \">= 0.9\", require: false\n  gem \"simplecov-lcov\", require: false\n  gem \"timecop\", \">= 0.5\"\n  gem \"tzinfo-data\", platforms: [:mingw, :mswin, :x64_mingw, :jruby]\nend\n\ngroup :active_record do\n  gem \"paper_trail\", \">= 12.0\"\n\n  platforms :ruby, :mswin, :mingw, :x64_mingw do\n    gem \"mysql2\", \">= 0.3.14\"\n    gem \"pg\", \">= 1.0.0\"\n    gem \"sqlite3\", \">= 1.3.0\"\n  end\n\n  platforms :jruby do\n    gem \"activerecord-jdbcmysql-adapter\", \"~> 60.0\"\n    gem \"activerecord-jdbcpostgresql-adapter\", \"~> 60.0\"\n    gem \"activerecord-jdbcsqlite3-adapter\", \"~> 60.0\"\n  end\nend\n\ngroup :mongoid do\n  gem \"cancancan-mongoid\"\n  gem \"carrierwave-mongoid\", \">= 0.6.3\", require: \"carrierwave/mongoid\"\n  gem \"database_cleaner-mongoid\", \">= 2.0\", require: false\n  gem \"kaminari-mongoid\"\n  gem \"mongoid\", \"~> 7.0\"\n  gem \"mongoid-paperclip\", \">= 0.0.8\", require: \"mongoid_paperclip\"\n  gem \"shrine-mongoid\", \"~> 1.0\"\nend\n\ngemspec path: \"../\"\n"
  },
  {
    "path": "gemfiles/rails_6.1.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"appraisal\", \">= 2.0\"\ngem \"devise\", \"~> 4.7\"\ngem \"net-smtp\", require: false\ngem \"rails\", \"~> 6.1.0\"\ngem \"sassc-rails\", \"~> 2.1\"\ngem \"turbo-rails\"\ngem \"vite_rails\", require: false\ngem \"webpacker\", require: false\ngem \"webrick\"\ngem \"concurrent-ruby\", \"1.3.4\"\n\ngroup :development, :test do\n  gem \"pry\", \">= 0.9\"\nend\n\ngroup :test do\n  gem \"cancancan\", \"~> 3.0\"\n  gem \"carrierwave\", [\">= 2.0.0.rc\", \"< 3\"]\n  gem \"cuprite\", \"!= 0.15.1\"\n  gem \"database_cleaner-active_record\", \">= 2.0\", require: false\n  gem \"dragonfly\", \"~> 1.0\"\n  gem \"factory_bot\", \">= 4.2\", \"!= 6.4.5\"\n  gem \"generator_spec\", \">= 0.8\"\n  gem \"kt-paperclip\"\n  gem \"launchy\", \">= 2.2\"\n  gem \"mini_magick\", \">= 3.4\"\n  gem \"pundit\"\n  gem \"rack-cache\", require: \"rack/cache\"\n  gem \"rspec-expectations\", \"!= 3.8.3\"\n  gem \"rspec-rails\", \">= 4.0.0.beta2\"\n  gem \"rspec-retry\"\n  gem \"rubocop\", [\"~> 1.20\", \"!= 1.22.2\"], require: false\n  gem \"rubocop-performance\", require: false\n  gem \"shrine\", \"~> 3.0\"\n  gem \"simplecov\", \">= 0.9\", require: false\n  gem \"simplecov-lcov\", require: false\n  gem \"timecop\", \">= 0.5\"\n  gem \"tzinfo-data\", platforms: [:mingw, :mswin, :x64_mingw, :jruby]\nend\n\ngroup :active_record do\n  gem \"paper_trail\", \">= 12.0\"\n\n  platforms :ruby, :mswin, :mingw, :x64_mingw do\n    gem \"mysql2\", \">= 0.3.14\"\n    gem \"pg\", \">= 1.0.0\"\n    gem \"sqlite3\", \">= 1.3.0\"\n  end\n\n  platforms :jruby do\n    gem \"activerecord-jdbcmysql-adapter\", \"~> 61.0\"\n    gem \"activerecord-jdbcpostgresql-adapter\", \"~> 61.0\"\n    gem \"activerecord-jdbcsqlite3-adapter\", \"~> 61.0\"\n  end\nend\n\ngroup :mongoid do\n  gem \"cancancan-mongoid\"\n  gem \"carrierwave-mongoid\", \">= 0.6.3\", require: \"carrierwave/mongoid\"\n  gem \"database_cleaner-mongoid\", \">= 2.0\", require: false\n  gem \"kaminari-mongoid\"\n  gem \"mongoid\", \"~> 7.0\"\n  gem \"mongoid-paperclip\", \">= 0.0.8\", require: \"mongoid_paperclip\"\n  gem \"shrine-mongoid\", \"~> 1.0\"\nend\n\ngemspec path: \"../\"\n"
  },
  {
    "path": "gemfiles/rails_7.0.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"appraisal\", \">= 2.0\"\ngem \"devise\", \"~> 4.7\"\ngem \"net-smtp\", require: false\ngem \"rails\", \"~> 7.0.0\", \"7.0.8.6\"\ngem \"sassc-rails\", \"~> 2.1\"\ngem \"turbo-rails\"\ngem \"vite_rails\", require: false\ngem \"webpacker\", require: false\ngem \"webrick\"\ngem \"concurrent-ruby\", \"1.3.4\"\ngem \"importmap-rails\", require: false\ngem \"nokogiri\", \"~> 1.16.0\", platform: :jruby\n\ngroup :development, :test do\n  gem \"pry\", \">= 0.9\"\nend\n\ngroup :test do\n  gem \"cancancan\", \"~> 3.0\"\n  gem \"carrierwave\", [\">= 2.0.0.rc\", \"< 3\"]\n  gem \"cuprite\", \"!= 0.15.1\"\n  gem \"database_cleaner-active_record\", \">= 2.0\", require: false\n  gem \"dragonfly\", \"~> 1.0\"\n  gem \"factory_bot\", \">= 4.2\", \"!= 6.4.5\"\n  gem \"generator_spec\", \">= 0.8\"\n  gem \"kt-paperclip\"\n  gem \"launchy\", \">= 2.2\"\n  gem \"mini_magick\", \">= 3.4\"\n  gem \"pundit\"\n  gem \"rack-cache\", require: \"rack/cache\"\n  gem \"rspec-expectations\", \"!= 3.8.3\"\n  gem \"rspec-rails\", \">= 4.0.0.beta2\"\n  gem \"rspec-retry\"\n  gem \"rubocop\", [\"~> 1.20\", \"!= 1.22.2\"], require: false\n  gem \"rubocop-performance\", require: false\n  gem \"shrine\", \"~> 3.0\"\n  gem \"simplecov\", \">= 0.9\", require: false\n  gem \"simplecov-lcov\", require: false\n  gem \"timecop\", \">= 0.5\"\n  gem \"tzinfo-data\", platforms: [:mingw, :mswin, :x64_mingw, :jruby]\nend\n\ngroup :active_record do\n  gem \"paper_trail\", \">= 12.0\"\n\n  platforms :ruby, :mswin, :mingw, :x64_mingw do\n    gem \"mysql2\", \">= 0.3.14\"\n    gem \"pg\", \">= 1.0.0\"\n    gem \"sqlite3\", \"~> 1.3\"\n  end\n\n  platforms :jruby do\n    gem \"activerecord-jdbcmysql-adapter\", \"~> 70.0\"\n    gem \"activerecord-jdbcpostgresql-adapter\", \"~> 70.0\"\n    gem \"activerecord-jdbcsqlite3-adapter\", \"~> 70.0\"\n  end\nend\n\ngroup :mongoid do\n  gem \"cancancan-mongoid\"\n  gem \"carrierwave-mongoid\", \">= 0.6.3\", require: \"carrierwave/mongoid\"\n  gem \"database_cleaner-mongoid\", \">= 2.0\", require: false\n  gem \"kaminari-mongoid\"\n  gem \"mongoid\", \"~> 8.0\"\n  gem \"mongoid-paperclip\", \">= 0.0.8\", require: \"mongoid_paperclip\"\n  gem \"shrine-mongoid\", \"~> 1.0\"\nend\n\ngemspec path: \"../\"\n"
  },
  {
    "path": "gemfiles/rails_7.1.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"appraisal\", \">= 2.0\"\ngem \"devise\", \"~> 4.7\"\ngem \"net-smtp\", require: false\ngem \"rails\", \"~> 7.1.0\"\ngem \"sassc-rails\", \"~> 2.1\"\ngem \"turbo-rails\"\ngem \"vite_rails\", require: false\ngem \"webpacker\", require: false\ngem \"webrick\"\ngem \"importmap-rails\", require: false\n\ngroup :development, :test do\n  gem \"pry\", \">= 0.9\"\nend\n\ngroup :test do\n  gem \"cancancan\", \"~> 3.0\"\n  gem \"carrierwave\", [\">= 2.0.0.rc\", \"< 3\"]\n  gem \"cuprite\", \"!= 0.15.1\"\n  gem \"database_cleaner-active_record\", \">= 2.0\", require: false\n  gem \"dragonfly\", \"~> 1.0\"\n  gem \"factory_bot\", \">= 4.2\", \"!= 6.4.5\"\n  gem \"generator_spec\", \">= 0.8\"\n  gem \"kt-paperclip\"\n  gem \"launchy\", \">= 2.2\"\n  gem \"mini_magick\", \">= 3.4\"\n  gem \"pundit\"\n  gem \"rack-cache\", require: \"rack/cache\"\n  gem \"rspec-expectations\", \"!= 3.8.3\"\n  gem \"rspec-rails\", \">= 4.0.0.beta2\"\n  gem \"rspec-retry\"\n  gem \"rubocop\", [\"~> 1.20\", \"!= 1.22.2\"], require: false\n  gem \"rubocop-performance\", require: false\n  gem \"shrine\", \"~> 3.0\"\n  gem \"simplecov\", \">= 0.9\", require: false\n  gem \"simplecov-lcov\", require: false\n  gem \"timecop\", \">= 0.5\"\n  gem \"tzinfo-data\", platforms: [:mingw, :mswin, :x64_mingw, :jruby]\nend\n\ngroup :active_record do\n  gem \"paper_trail\", \">= 12.0\"\n\n  platforms :ruby, :mswin, :mingw, :x64_mingw do\n    gem \"mysql2\", \">= 0.3.14\"\n    gem \"pg\", \">= 1.0.0\"\n    gem \"sqlite3\", \"~> 1.3\"\n  end\n\n  platforms :jruby do\n    gem \"activerecord-jdbcmysql-adapter\", \"~> 71.0\"\n    gem \"activerecord-jdbcpostgresql-adapter\", \"~> 71.0\"\n    gem \"activerecord-jdbcsqlite3-adapter\", \"~> 71.0\"\n  end\nend\n\ngroup :mongoid do\n  gem \"cancancan-mongoid\"\n  gem \"carrierwave-mongoid\", \">= 0.6.3\", require: \"carrierwave/mongoid\"\n  gem \"database_cleaner-mongoid\", \">= 2.0\", require: false\n  gem \"kaminari-mongoid\"\n  gem \"mongoid\", \"~> 8.0\"\n  gem \"mongoid-paperclip\", \">= 0.0.8\", require: \"mongoid_paperclip\"\n  gem \"shrine-mongoid\", \"~> 1.0\"\nend\n\ngemspec path: \"../\"\n"
  },
  {
    "path": "gemfiles/rails_7.2.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"appraisal\", \">= 2.0\"\ngem \"devise\", \"~> 4.7\"\ngem \"net-smtp\", require: false\ngem \"rails\", \"~> 7.2.0\"\ngem \"sassc-rails\", \"~> 2.1\"\ngem \"turbo-rails\"\ngem \"vite_rails\", require: false\ngem \"webpacker\", require: false\ngem \"webrick\"\ngem \"importmap-rails\", require: false\n\ngroup :development, :test do\n  gem \"pry\", \">= 0.9\"\nend\n\ngroup :test do\n  gem \"cancancan\", \"~> 3.0\"\n  gem \"carrierwave\", [\">= 2.0.0.rc\", \"< 3\"]\n  gem \"cuprite\", \"!= 0.15.1\"\n  gem \"database_cleaner-active_record\", \">= 2.0\", require: false\n  gem \"dragonfly\", \"~> 1.0\"\n  gem \"factory_bot\", \">= 4.2\", \"!= 6.4.5\"\n  gem \"generator_spec\", \">= 0.8\"\n  gem \"kt-paperclip\"\n  gem \"launchy\", \">= 2.2\"\n  gem \"mini_magick\", \">= 3.4\"\n  gem \"pundit\"\n  gem \"rack-cache\", require: \"rack/cache\"\n  gem \"rspec-expectations\", \"!= 3.8.3\"\n  gem \"rspec-rails\", \">= 4.0.0.beta2\"\n  gem \"rspec-retry\"\n  gem \"rubocop\", [\"~> 1.20\", \"!= 1.22.2\"], require: false\n  gem \"rubocop-performance\", require: false\n  gem \"shrine\", \"~> 3.0\"\n  gem \"simplecov\", \">= 0.9\", require: false\n  gem \"simplecov-lcov\", require: false\n  gem \"timecop\", \">= 0.5\"\n  gem \"tzinfo-data\", platforms: [:mingw, :mswin, :x64_mingw, :jruby]\nend\n\ngroup :active_record do\n  gem \"paper_trail\", \">= 12.0\"\n\n  platforms :ruby, :mswin, :mingw, :x64_mingw do\n    gem \"mysql2\", \">= 0.3.14\"\n    gem \"pg\", \">= 1.0.0\"\n    gem \"sqlite3\", \">= 1.3.0\"\n  end\nend\n\ngroup :mongoid do\n  gem \"cancancan-mongoid\"\n  gem \"carrierwave-mongoid\", \">= 0.6.3\", require: \"carrierwave/mongoid\"\n  gem \"database_cleaner-mongoid\", \">= 2.0\", require: false\n  gem \"kaminari-mongoid\"\n  gem \"mongoid\", \"~> 8.0\"\n  gem \"mongoid-paperclip\", \">= 0.0.8\", require: \"mongoid_paperclip\"\n  gem \"shrine-mongoid\", \"~> 1.0\"\nend\n\ngemspec path: \"../\"\n"
  },
  {
    "path": "gemfiles/rails_8.0.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"appraisal\", \">= 2.0\"\ngem \"devise\", \"~> 4.7\"\ngem \"net-smtp\", require: false\ngem \"rails\", \"~> 8.0.0\"\ngem \"sassc-rails\", \"~> 2.1\"\ngem \"turbo-rails\"\ngem \"vite_rails\", require: false\ngem \"webpacker\", require: false\ngem \"webrick\"\ngem \"importmap-rails\", require: false\n\ngroup :development, :test do\n  gem \"pry\", \">= 0.9\"\nend\n\ngroup :test do\n  gem \"cancancan\", \"~> 3.0\"\n  gem \"carrierwave\", [\">= 2.0.0.rc\", \"< 3\"]\n  gem \"cuprite\", \"!= 0.15.1\"\n  gem \"database_cleaner-active_record\", \">= 2.0\", require: false\n  gem \"dragonfly\", \"~> 1.0\"\n  gem \"factory_bot\", \">= 4.2\", \"!= 6.4.5\"\n  gem \"generator_spec\", \">= 0.8\"\n  gem \"kt-paperclip\"\n  gem \"launchy\", \">= 2.2\"\n  gem \"mini_magick\", \">= 3.4\"\n  gem \"pundit\"\n  gem \"rack-cache\", require: \"rack/cache\"\n  gem \"rspec-expectations\", \"!= 3.8.3\"\n  gem \"rspec-rails\", \">= 4.0.0.beta2\"\n  gem \"rspec-retry\"\n  gem \"rubocop\", [\"~> 1.20\", \"!= 1.22.2\"], require: false\n  gem \"rubocop-performance\", require: false\n  gem \"shrine\", \"~> 3.0\"\n  gem \"simplecov\", \">= 0.9\", require: false\n  gem \"simplecov-lcov\", require: false\n  gem \"timecop\", \">= 0.5\"\n  gem \"tzinfo-data\", platforms: [:mingw, :mswin, :x64_mingw, :jruby]\nend\n\ngroup :active_record do\n  gem \"paper_trail\", \">= 12.0\"\n\n  platforms :ruby, :mswin, :mingw, :x64_mingw do\n    gem \"mysql2\", \">= 0.3.14\"\n    gem \"pg\", \">= 1.0.0\"\n    gem \"sqlite3\", \">= 1.3.0\"\n  end\nend\n\ngroup :mongoid do\n  gem \"cancancan-mongoid\"\n  gem \"carrierwave-mongoid\", \">= 0.6.3\", require: \"carrierwave/mongoid\"\n  gem \"database_cleaner-mongoid\", \">= 2.0\", require: false\n  gem \"kaminari-mongoid\"\n  gem \"mongoid\", \"~> 9.0\"\n  gem \"mongoid-paperclip\", \">= 0.0.8\", require: \"mongoid_paperclip\"\n  gem \"shrine-mongoid\", \"~> 1.0\"\nend\n\ngemspec path: \"../\"\n"
  },
  {
    "path": "lib/generators/rails_admin/importmap_formatter.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'importmap/packager'\n\nmodule RailsAdmin\n  class ImportmapFormatter\n    attr_reader :packager\n\n    def initialize(path = 'config/importmap.rails_admin.rb')\n      @packager = Importmap::Packager.new(path)\n    end\n\n    def format\n      imports = packager.import(\"rails_admin@#{RailsAdmin::Version.js}\", from: 'jspm.io')\n      imports = imports[:imports] if imports.key?(:imports)\n\n      # Use ESM compatible version to work around https://github.com/cljsjs/packages/issues/1579\n      imports['@popperjs/core'].gsub!('lib/index.js', 'dist/esm/popper.js')\n\n      # Tidy up jQuery UI dependencies\n      jquery_uis = imports.keys.filter { |key, _| key =~ /jquery-ui/ }\n      imports['jquery-ui/'] = imports[jquery_uis.first].gsub(%r{(@[^/@]+)/[^@]+$}, '\\1/')\n      imports.reject! { |key, _| jquery_uis.include? key }\n\n      pins = ['pin \"rails_admin\", preload: true', packager.pin_for('rails_admin/src/rails_admin/base', imports.delete('rails_admin'))]\n      (pins + imports.map { |package, url| packager.pin_for(package, url) }).join(\"\\n\")\n    end\n  end\nend\n"
  },
  {
    "path": "lib/generators/rails_admin/install_generator.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails/generators'\nrequire 'rails_admin/version'\nrequire File.expand_path('utils', __dir__)\n\nmodule RailsAdmin\n  class InstallGenerator < Rails::Generators::Base\n    source_root File.expand_path('templates', __dir__)\n    include Generators::Utils::InstanceMethods\n\n    argument :_namespace, type: :string, required: false, desc: 'RailsAdmin url namespace'\n    class_option :asset, type: :string, required: false, default: nil, desc: 'Asset delivery method [options: webpacker, webpack, sprockets, importmap, vite]'\n    desc 'RailsAdmin installation generator'\n\n    def install\n      if File.read(File.join(destination_root, 'config/routes.rb')).include?('mount RailsAdmin::Engine')\n        display \"Skipped route addition, since it's already there\"\n      else\n        namespace = ask_for('Where do you want to mount rails_admin?', 'admin', _namespace)\n        route(\"mount RailsAdmin::Engine => '/#{namespace}', as: 'rails_admin'\")\n      end\n      if File.exist? File.join(destination_root, 'config/initializers/rails_admin.rb')\n        insert_into_file 'config/initializers/rails_admin.rb', \"  config.asset_source = :#{asset}\\n\", after: \"RailsAdmin.config do |config|\\n\"\n      else\n        template 'initializer.erb', 'config/initializers/rails_admin.rb'\n      end\n      display \"Using [#{asset}] for asset delivery method\"\n      case asset\n      when 'webpack'\n        configure_for_webpack\n      when 'importmap'\n        configure_for_importmap\n      when 'webpacker'\n        configure_for_webpacker5\n      when 'vite'\n        configure_for_vite\n      when 'sprockets'\n        configure_for_sprockets\n      else\n        raise \"Unknown asset source: #{asset}\"\n      end\n    end\n\n  private\n\n    def asset\n      return options['asset'] if options['asset']\n\n      if defined?(Webpacker)\n        'webpacker'\n      elsif Rails.root.join('webpack.config.js').exist?\n        'webpack'\n      elsif Rails.root.join('config/importmap.rb').exist?\n        'importmap'\n      elsif defined?(ViteRuby)\n        'vite'\n      else\n        'sprockets'\n      end\n    end\n\n    def configure_for_sprockets\n      gem 'sassc-rails'\n    end\n\n    def configure_for_webpacker5\n      run \"yarn add rails_admin@#{RailsAdmin::Version.js}\"\n      template 'rails_admin.webpacker.js', 'app/javascript/packs/rails_admin.js'\n      template 'rails_admin.scss.erb', 'app/javascript/stylesheets/rails_admin.scss'\n      # To work around https://github.com/railsadminteam/rails_admin/issues/3565\n      add_package_json_field('resolutions', {'rails_admin/@fortawesome/fontawesome-free' => '^5.15.0'})\n    end\n\n    def configure_for_vite\n      vite_source_code_dir = ViteRuby.config.source_code_dir\n      run \"yarn add rails_admin@#{RailsAdmin::Version.js} sass\"\n      template('rails_admin.vite.js', File.join(vite_source_code_dir, 'entrypoints', 'rails_admin.js'))\n      @fa_font_path = '@fortawesome/fontawesome-free/webfonts'\n      template('rails_admin.scss.erb', File.join(vite_source_code_dir, 'stylesheets', 'rails_admin.scss'))\n    end\n\n    def configure_for_webpack\n      run \"yarn add rails_admin@#{RailsAdmin::Version.js}\"\n      template 'rails_admin.js', 'app/javascript/rails_admin.js'\n      webpack_config = File.join(destination_root, 'webpack.config.js')\n      marker = %r{application: [\"']./app/javascript/application.js[\"']}\n      if File.exist?(webpack_config) && File.read(webpack_config) =~ marker\n        insert_into_file 'webpack.config.js', %(,\\n    rails_admin: \"./app/javascript/rails_admin.js\"), after: marker\n      else\n        say 'Add `rails_admin: \"./app/javascript/rails_admin.js\"` to the entry section in your webpack.config.js.', :red\n      end\n      setup_css({'build' => 'webpack --config webpack.config.js'})\n    end\n\n    def configure_for_importmap\n      run \"yarn add rails_admin@#{RailsAdmin::Version.js}\"\n      template 'rails_admin.js', 'app/javascript/rails_admin.js'\n      require_relative 'importmap_formatter'\n      add_file 'config/importmap.rails_admin.rb', ImportmapFormatter.new.format\n      setup_css\n    end\n\n    def setup_css(additional_script_entries = {})\n      gem 'cssbundling-rails'\n      rake 'css:install:sass'\n\n      @fa_font_path = '.'\n      template 'rails_admin.scss.erb', 'app/assets/stylesheets/rails_admin.scss'\n      asset_config = %{Rails.application.config.assets.paths << Rails.root.join(\"node_modules/@fortawesome/fontawesome-free/webfonts\")\\n}\n      if File.exist? File.join(destination_root, 'config/initializers/assets.rb')\n        append_to_file 'config/initializers/assets.rb', asset_config\n      else\n        add_file 'config/initializers/assets.rb', asset_config\n      end\n      add_package_json_field('scripts', additional_script_entries.merge({'build:css' => 'sass ./app/assets/stylesheets/rails_admin.scss:./app/assets/builds/rails_admin.css --no-source-map --load-path=node_modules'}), <<~INSTRUCTION)\n        Taking 'build:css' as an example, if you're already have application.sass.css for the sass build, the resulting script would look like:\n          sass ./app/assets/stylesheets/application.sass.scss:./app/assets/builds/application.css ./app/assets/stylesheets/rails_admin.scss:./app/assets/builds/rails_admin.css --no-source-map --load-path=node_modules\n      INSTRUCTION\n    end\n\n    def add_package_json_field(name, entries, instruction = nil)\n      display \"Add #{name} to package.json\"\n      package = begin\n        JSON.parse(File.read(File.join(destination_root, 'package.json')))\n      rescue Errno::ENOENT, JSON::ParserError\n        {}\n      end\n      if package[name] && (package[name].keys & entries.keys).any?\n        say <<~MESSAGE, :red\n          You need to merge \"#{name}\": #{JSON.pretty_generate(entries)} into the existing #{name} in your package.json.#{instruction && \"\\n#{instruction}\"}\n        MESSAGE\n      else\n        package[name] ||= {}\n        entries.each do |entry, value|\n          package[name][entry] = value\n        end\n        add_file 'package.json', \"#{JSON.pretty_generate(package)}\\n\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/generators/rails_admin/templates/initializer.erb",
    "content": "RailsAdmin.config do |config|\n  config.asset_source = :<%= asset %>\n\n  ### Popular gems integration\n\n  ## == Devise ==\n  # config.authenticate_with do\n  #   warden.authenticate! scope: :user\n  # end\n  # config.current_user_method(&:current_user)\n\n  ## == CancanCan ==\n  # config.authorize_with :cancancan\n\n  ## == Pundit ==\n  # config.authorize_with :pundit\n\n  ## == PaperTrail ==\n  # config.audit_with :paper_trail, 'User', 'PaperTrail::Version' # PaperTrail >= 3.0.0\n\n  ### More at https://github.com/railsadminteam/rails_admin/wiki/Base-configuration\n\n  ## == Gravatar integration ==\n  ## To disable Gravatar integration in Navigation Bar set to false\n  # config.show_gravatar = true\n\n  config.actions do\n    dashboard                     # mandatory\n    index                         # mandatory\n    new\n    export\n    bulk_delete\n    show\n    edit\n    delete\n    show_in_app\n\n    ## With an audit adapter, you can add:\n    # history_index\n    # history_show\n  end\nend\n"
  },
  {
    "path": "lib/generators/rails_admin/templates/rails_admin.js",
    "content": "import \"rails_admin/src/rails_admin/base\";\n"
  },
  {
    "path": "lib/generators/rails_admin/templates/rails_admin.scss.erb",
    "content": "<%= @fa_font_path ? %{$fa-font-path: \"#{@fa_font_path}\";\\n} : '' %>@import \"rails_admin/src/rails_admin/styles/base\";\n"
  },
  {
    "path": "lib/generators/rails_admin/templates/rails_admin.vite.js",
    "content": "import \"~/stylesheets/rails_admin.scss\";\nimport \"rails_admin/src/rails_admin/base\";\n"
  },
  {
    "path": "lib/generators/rails_admin/templates/rails_admin.webpacker.js",
    "content": "import \"rails_admin/src/rails_admin/base\";\nimport \"../stylesheets/rails_admin.scss\";\n"
  },
  {
    "path": "lib/generators/rails_admin/utils.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Generators\n    module Utils\n      module InstanceMethods\n        def display(output, color = :green)\n          say(\"           -  #{output}\", color)\n        end\n\n        def ask_for(wording, default_value = nil, override_if_present_value = nil)\n          if override_if_present_value.present?\n            display(\"Using [#{override_if_present_value}] for question '#{wording}'\") && override_if_present_value\n          else\n            ask(\"           ?  #{wording} Press <enter> for [#{default_value}] >\", :yellow).presence || default_value\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/abstract_model.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/support/datetime'\n\nmodule RailsAdmin\n  class AbstractModel\n    cattr_accessor :all\n    attr_reader :adapter, :model_name\n\n    class << self\n      def reset\n        @@all = nil\n      end\n\n      def all(adapter = nil)\n        @@all ||= Config.models_pool.collect { |m| new(m) }.compact\n        adapter ? @@all.select { |m| m.adapter == adapter } : @@all\n      end\n\n      alias_method :old_new, :new\n      def new(m)\n        m = m.constantize unless m.is_a?(Class)\n        (am = old_new(m)).model && am.adapter ? am : nil\n      rescue *([LoadError, NameError] + (defined?(ActiveRecord) ? ['ActiveRecord::NoDatabaseError'.constantize, 'ActiveRecord::ConnectionNotEstablished'.constantize] : []))\n        puts \"[RailsAdmin] Could not load model #{m}, assuming model is non existing. (#{$ERROR_INFO})\" unless Rails.env.test?\n        nil\n      end\n\n      @@polymorphic_parents = {}\n\n      def polymorphic_parents(adapter, model_name, name)\n        @@polymorphic_parents[adapter.to_sym] ||= {}.tap do |hash|\n          all(adapter).each do |am|\n            am.associations.select(&:as).each do |association|\n              (hash[[association.klass.to_s.underscore, association.as].join('_').to_sym] ||= []) << am.model\n            end\n          end\n        end\n        @@polymorphic_parents[adapter.to_sym][[model_name.to_s.underscore, name].join('_').to_sym]\n      end\n\n      # For testing\n      def reset_polymorphic_parents\n        @@polymorphic_parents = {}\n      end\n    end\n\n    def initialize(model_or_model_name)\n      @model_name = model_or_model_name.to_s\n      ancestors = model.ancestors.collect(&:to_s)\n      if ancestors.include?('ActiveRecord::Base') && !model.abstract_class? && model.table_exists?\n        initialize_active_record\n      elsif ancestors.include?('Mongoid::Document')\n        initialize_mongoid\n      end\n    end\n\n    # do not store a reference to the model, does not play well with ActiveReload/Rails3.2\n    def model\n      @model_name.constantize\n    end\n\n    def quoted_table_name\n      table_name\n    end\n\n    def quote_column_name(name)\n      name\n    end\n\n    def to_s\n      model.to_s\n    end\n\n    def config\n      Config.model self\n    end\n\n    def to_param\n      @model_name.split('::').collect(&:underscore).join('~')\n    end\n\n    def param_key\n      @model_name.split('::').collect(&:underscore).join('_')\n    end\n\n    def pretty_name\n      model.model_name.human\n    end\n\n    def where(conditions)\n      model.where(conditions)\n    end\n\n    def each_associated_children(object)\n      associations.each do |association|\n        case association.type\n        when :has_one\n          child = object.send(association.name)\n          yield(association, [child]) if child\n        when :has_many\n          children = object.send(association.name)\n          yield(association, Array.new(children))\n        end\n      end\n    end\n\n    def format_id(id)\n      id\n    end\n\n    def parse_id(id)\n      id\n    end\n\n  private\n\n    def initialize_active_record\n      @adapter = :active_record\n      require 'rails_admin/adapters/active_record'\n      extend Adapters::ActiveRecord\n    end\n\n    def initialize_mongoid\n      @adapter = :mongoid\n      require 'rails_admin/adapters/mongoid'\n      extend Adapters::Mongoid\n    end\n\n    def parse_field_value(field, value)\n      value.is_a?(Array) ? value.map { |v| field.parse_value(v) } : field.parse_value(value)\n    end\n\n    class StatementBuilder\n      def initialize(column, type, value, operator)\n        @column = column\n        @type = type\n        @value = value\n        @operator = operator\n      end\n\n      def to_statement\n        return if [@operator, @value].any? { |v| v == '_discard' }\n\n        unary_operators[@operator] || unary_operators[@value] ||\n          build_statement_for_type_generic\n      end\n\n    protected\n\n      def get_filtering_duration\n        FilteringDuration.new(@operator, @value).get_duration\n      end\n\n      def build_statement_for_type_generic\n        build_statement_for_type || begin\n          case @type\n          when :date\n            build_statement_for_date\n          when :datetime, :timestamp, :time\n            build_statement_for_datetime_or_timestamp\n          end\n        end\n      end\n\n      def build_statement_for_type\n        raise 'You must override build_statement_for_type in your StatementBuilder'\n      end\n\n      def build_statement_for_integer_decimal_or_float\n        case @value\n        when Array\n          val, range_begin, range_end = *@value.collect do |v|\n            next unless v.to_i.to_s == v || v.to_f.to_s == v\n\n            @type == :integer ? v.to_i : v.to_f\n          end\n          case @operator\n          when 'between'\n            range_filter(range_begin, range_end)\n          else\n            column_for_value(val) if val\n          end\n        else\n          if @value.to_i.to_s == @value || @value.to_f.to_s == @value\n            @type == :integer ? column_for_value(@value.to_i) : column_for_value(@value.to_f)\n          end\n        end\n      end\n\n      def build_statement_for_date\n        start_date, end_date = get_filtering_duration\n        if start_date\n          start_date = begin\n            start_date.to_date\n          rescue StandardError\n            nil\n          end\n        end\n        if end_date\n          end_date = begin\n            end_date.to_date\n          rescue StandardError\n            nil\n          end\n        end\n        range_filter(start_date, end_date)\n      end\n\n      def build_statement_for_datetime_or_timestamp\n        start_date, end_date = get_filtering_duration\n        start_date = start_date.beginning_of_day if start_date.is_a?(Date)\n        end_date = end_date.end_of_day if end_date.is_a?(Date)\n        range_filter(start_date, end_date)\n      end\n\n      def unary_operators\n        raise 'You must override unary_operators in your StatementBuilder'\n      end\n\n      def range_filter(_min, _max)\n        raise 'You must override range_filter in your StatementBuilder'\n      end\n\n      class FilteringDuration\n        def initialize(operator, value)\n          @value = value\n          @operator = operator\n        end\n\n        def get_duration\n          case @operator\n          when 'between'   then between\n          when 'today'     then today\n          when 'yesterday' then yesterday\n          when 'this_week' then this_week\n          when 'last_week' then last_week\n          else default\n          end\n        end\n\n        def today\n          [Date.today, Date.today]\n        end\n\n        def yesterday\n          [Date.yesterday, Date.yesterday]\n        end\n\n        def this_week\n          [Date.today.beginning_of_week, Date.today.end_of_week]\n        end\n\n        def last_week\n          [1.week.ago.to_date.beginning_of_week,\n           1.week.ago.to_date.end_of_week]\n        end\n\n        def between\n          [@value[1], @value[2]]\n        end\n\n        def default\n          [default_date, default_date]\n        end\n\n      private\n\n        def default_date\n          Array.wrap(@value).first\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/active_record/association.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Adapters\n    module ActiveRecord\n      class Association\n        attr_reader :association, :model\n\n        def initialize(association, model)\n          @association = association\n          @model = model\n        end\n\n        def name\n          association.name.to_sym\n        end\n\n        def pretty_name\n          name.to_s.tr('_', ' ').capitalize\n        end\n\n        def type\n          association.macro\n        end\n\n        def field_type\n          if polymorphic?\n            :polymorphic_association\n          else\n            :\"#{association.macro}_association\"\n          end\n        end\n\n        def klass\n          if options[:polymorphic]\n            polymorphic_parents(:active_record, association.active_record.name.to_s, name) || []\n          else\n            association.klass\n          end\n        end\n\n        def primary_key\n          return nil if polymorphic?\n\n          value =\n            case type\n            when :has_one\n              association.klass.primary_key\n            else\n              association.association_primary_key\n            end\n\n          if value.is_a? Array\n            :id\n          else\n            value.to_sym\n          end\n        end\n\n        def foreign_key\n          if association.options[:query_constraints].present?\n            association.options[:query_constraints].map(&:to_sym)\n          elsif association.foreign_key.is_a?(Array)\n            association.foreign_key.map(&:to_sym)\n          else\n            association.foreign_key.to_sym\n          end\n        end\n\n        def foreign_key_nullable?\n          return true if foreign_key.nil? || type != :has_many\n\n          (column = klass.columns_hash[foreign_key.to_s]).nil? || column.null\n        end\n\n        def foreign_type\n          options[:foreign_type].try(:to_sym) || :\"#{name}_type\" if options[:polymorphic]\n        end\n\n        def foreign_inverse_of\n          nil\n        end\n\n        def key_accessor\n          case type\n          when :has_many, :has_and_belongs_to_many\n            :\"#{name.to_s.singularize}_ids\"\n          when :has_one\n            :\"#{name}_id\"\n          else\n            if foreign_key.is_a?(Array)\n              :\"#{name}_id\"\n            else\n              foreign_key\n            end\n          end\n        end\n\n        def as\n          options[:as].try :to_sym\n        end\n\n        def polymorphic?\n          options[:polymorphic] || false\n        end\n\n        def inverse_of\n          options[:inverse_of].try :to_sym\n        end\n\n        def read_only?\n          (klass.all.instance_exec(&scope).readonly_value if scope.is_a?(Proc) && scope.arity == 0) ||\n            association.nested? ||\n            false\n        end\n\n        def nested_options\n          model.nested_attributes_options.try { |o| o[name.to_sym] }\n        end\n\n        def association?\n          true\n        end\n\n        delegate :options, :scope, to: :association, prefix: false\n        delegate :polymorphic_parents, to: RailsAdmin::AbstractModel\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/active_record/object_extension.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Adapters\n    module ActiveRecord\n      module ObjectExtension\n        def assign_attributes(attributes)\n          super if attributes\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/active_record/property.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Adapters\n    module ActiveRecord\n      class Property\n        attr_reader :property, :model\n\n        def initialize(property, model)\n          @property = property\n          @model = model\n        end\n\n        def name\n          property.name.to_sym\n        end\n\n        def pretty_name\n          property.name.to_s.tr('_', ' ').capitalize\n        end\n\n        def type\n          if serialized?\n            :serialized\n          else\n            property.type\n          end\n        end\n\n        def length\n          property.limit\n        end\n\n        def nullable?\n          property.null\n        end\n\n        def serial?\n          model.primary_key == property.name\n        end\n\n        def association?\n          false\n        end\n\n        def read_only?\n          model.readonly_attributes.include? property.name.to_s\n        end\n\n      private\n\n        def serialized?\n          model.type_for_attribute(property.name).instance_of?(::ActiveRecord::Type::Serialized)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/active_record.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'active_record'\nrequire 'rails_admin/adapters/active_record/association'\nrequire 'rails_admin/adapters/active_record/object_extension'\nrequire 'rails_admin/adapters/active_record/property'\n\nmodule RailsAdmin\n  module Adapters\n    module ActiveRecord\n      DISABLED_COLUMN_TYPES = %i[tsvector blob binary spatial hstore geometry].freeze\n\n      def new(params = {})\n        model.new(params).extend(ObjectExtension)\n      end\n\n      def get(id, scope = scoped)\n        object = primary_key_scope(scope, id).first\n        return unless object\n\n        object.extend(ObjectExtension)\n      end\n\n      def scoped\n        model.all\n      end\n\n      def first(options = {}, scope = nil)\n        all(options, scope).first\n      end\n\n      def all(options = {}, scope = nil)\n        scope ||= scoped\n        scope = scope.includes(options[:include]) if options[:include]\n        scope = scope.limit(options[:limit]) if options[:limit]\n        scope = bulk_scope(scope, options) if options[:bulk_ids]\n        scope = query_scope(scope, options[:query]) if options[:query]\n        scope = filter_scope(scope, options[:filters]) if options[:filters]\n        scope = scope.send(Kaminari.config.page_method_name, options[:page]).per(options[:per]) if options[:page] && options[:per]\n        scope = sort_scope(scope, options) if options[:sort]\n        scope\n      end\n\n      def count(options = {}, scope = nil)\n        all(options.merge(limit: false, page: false), scope).count(:all)\n      end\n\n      def destroy(objects)\n        Array.wrap(objects).each(&:destroy)\n      end\n\n      def associations\n        model.reflect_on_all_associations.collect do |association|\n          Association.new(association, model)\n        end\n      end\n\n      def properties\n        columns = model.columns.reject do |c|\n          c.type.blank? ||\n            DISABLED_COLUMN_TYPES.include?(c.type.to_sym) ||\n            c.try(:array)\n        end\n        columns.collect do |property|\n          Property.new(property, model)\n        end\n      end\n\n      def base_class\n        model.base_class\n      end\n\n      delegate :primary_key, :table_name, to: :model, prefix: false\n\n      def quoted_table_name\n        model.quoted_table_name\n      end\n\n      def quote_column_name(name)\n        model.connection.quote_column_name(name)\n      end\n\n      def encoding\n        adapter =\n          if ::ActiveRecord::Base.respond_to?(:connection_db_config)\n            ::ActiveRecord::Base.connection_db_config.configuration_hash[:adapter]\n          else\n            ::ActiveRecord::Base.connection_config[:adapter]\n          end\n        case adapter\n        when 'postgresql'\n          ::ActiveRecord::Base.connection.select_one(\"SELECT ''::text AS str;\").values.first.encoding\n        when 'mysql2'\n          if RUBY_ENGINE == 'jruby'\n            ::ActiveRecord::Base.connection.select_one(\"SELECT '' AS str;\").values.first.encoding\n          else\n            ::ActiveRecord::Base.connection.raw_connection.encoding\n          end\n        when 'oracle_enhanced'\n          ::ActiveRecord::Base.connection.select_one('SELECT dummy FROM DUAL').values.first.encoding\n        else\n          ::ActiveRecord::Base.connection.select_one(\"SELECT '' AS str;\").values.first.encoding\n        end\n      end\n\n      def embedded?\n        false\n      end\n\n      def cyclic?\n        false\n      end\n\n      def adapter_supports_joins?\n        true\n      end\n\n      def format_id(id)\n        if primary_key.is_a? Array\n          RailsAdmin.config.composite_keys_serializer.serialize(id)\n        else\n          id\n        end\n      end\n\n      def parse_id(id)\n        if primary_key.is_a?(Array)\n          ids = RailsAdmin.config.composite_keys_serializer.deserialize(id)\n          primary_key.each_with_index do |key, i|\n            ids[i] = model.type_for_attribute(key).cast(ids[i])\n          end\n          ids\n        else\n          id\n        end\n      end\n\n    private\n\n      def primary_key_scope(scope, id)\n        if primary_key.is_a? Array\n          scope.where(primary_key.zip(parse_id(id)).to_h)\n        else\n          scope.where(primary_key => id)\n        end\n      end\n\n      def bulk_scope(scope, options)\n        if primary_key.is_a? Array\n          options[:bulk_ids].map { |id| primary_key_scope(scope, id) }.reduce(&:or)\n        else\n          scope.where(primary_key => options[:bulk_ids])\n        end\n      end\n\n      def sort_scope(scope, options)\n        direction = options[:sort_reverse] ? :asc : :desc\n        case options[:sort]\n        when String, Symbol\n          scope.reorder(\"#{options[:sort]} #{direction}\")\n        when Array\n          scope.reorder(options[:sort].zip(Array.new(options[:sort].size) { direction }).to_h)\n        when Hash\n          scope.reorder(options[:sort].map { |table_name, column| \"#{table_name}.#{column}\" }.\n            zip(Array.new(options[:sort].size) { direction }).to_h)\n        else\n          raise ArgumentError.new(\"Unsupported sort value: #{options[:sort]}\")\n        end\n      end\n\n      class WhereBuilder\n        def initialize(scope)\n          @statements = []\n          @values = []\n          @tables = []\n          @scope = scope\n        end\n\n        def add(field, value, operator)\n          field.searchable_columns.flatten.each do |column_infos|\n            statement, value1, value2 = StatementBuilder.new(column_infos[:column], column_infos[:type], value, operator, @scope.connection.adapter_name).to_statement\n            @statements << statement if statement.present?\n            @values << value1 unless value1.nil?\n            @values << value2 unless value2.nil?\n            table, column = column_infos[:column].split('.')\n            @tables.push(table) if column\n          end\n        end\n\n        def build\n          scope = @scope.where(@statements.join(' OR '), *@values)\n          scope = scope.references(*@tables.uniq) if @tables.any?\n          scope\n        end\n      end\n\n      def query_scope(scope, query, fields = config.list.fields.select(&:queryable?))\n        if config.list.search_by\n          scope.send(config.list.search_by, query)\n        else\n          wb = WhereBuilder.new(scope)\n          fields.each do |field|\n            value = parse_field_value(field, query)\n            wb.add(field, value, field.search_operator)\n          end\n          # OR all query statements\n          wb.build\n        end\n      end\n\n      # filters example => {\"string_field\"=>{\"0055\"=>{\"o\"=>\"like\", \"v\"=>\"test_value\"}}, ...}\n      # \"0055\" is the filter index, no use here. o is the operator, v the value\n      def filter_scope(scope, filters, fields = config.list.fields.select(&:filterable?))\n        filters.each_pair do |field_name, filters_dump|\n          filters_dump.each_value do |filter_dump|\n            wb = WhereBuilder.new(scope)\n            field = fields.detect { |f| f.name.to_s == field_name }\n            value = parse_field_value(field, filter_dump[:v])\n\n            wb.add(field, value, (filter_dump[:o] || RailsAdmin::Config.default_search_operator))\n            # AND current filter statements to other filter statements\n            scope = wb.build\n          end\n        end\n        scope\n      end\n\n      def build_statement(column, type, value, operator)\n        StatementBuilder.new(column, type, value, operator, model.connection.adapter_name).to_statement\n      end\n\n      class StatementBuilder < RailsAdmin::AbstractModel::StatementBuilder\n        def initialize(column, type, value, operator, adapter_name)\n          super column, type, value, operator\n          @adapter_name = adapter_name\n        end\n\n      protected\n\n        def unary_operators\n          case @type\n          when :boolean\n            boolean_unary_operators\n          when :uuid\n            uuid_unary_operators\n          when :integer, :decimal, :float\n            numeric_unary_operators\n          else\n            generic_unary_operators\n          end\n        end\n\n      private\n\n        def generic_unary_operators\n          {\n            '_blank' => [\"(#{@column} IS NULL OR #{@column} = '')\"],\n            '_present' => [\"(#{@column} IS NOT NULL AND #{@column} != '')\"],\n            '_null' => [\"(#{@column} IS NULL)\"],\n            '_not_null' => [\"(#{@column} IS NOT NULL)\"],\n            '_empty' => [\"(#{@column} = '')\"],\n            '_not_empty' => [\"(#{@column} != '')\"],\n          }\n        end\n\n        def boolean_unary_operators\n          generic_unary_operators.merge(\n            '_blank' => [\"(#{@column} IS NULL)\"],\n            '_empty' => [\"(#{@column} IS NULL)\"],\n            '_present' => [\"(#{@column} IS NOT NULL)\"],\n            '_not_empty' => [\"(#{@column} IS NOT NULL)\"],\n          )\n        end\n        alias_method :numeric_unary_operators, :boolean_unary_operators\n        alias_method :uuid_unary_operators, :boolean_unary_operators\n\n        def range_filter(min, max)\n          if min && max && min == max\n            [\"(#{@column} = ?)\", min]\n          elsif min && max\n            [\"(#{@column} BETWEEN ? AND ?)\", min, max]\n          elsif min\n            [\"(#{@column} >= ?)\", min]\n          elsif max\n            [\"(#{@column} <= ?)\", max]\n          end\n        end\n\n        def build_statement_for_type\n          case @type\n          when :boolean                   then build_statement_for_boolean\n          when :integer, :decimal, :float then build_statement_for_integer_decimal_or_float\n          when :string, :text, :citext    then build_statement_for_string_or_text\n          when :enum                      then build_statement_for_enum\n          when :belongs_to_association    then build_statement_for_belongs_to_association\n          when :uuid                      then build_statement_for_uuid\n          end\n        end\n\n        def build_statement_for_boolean\n          case @value\n          when 'false', 'f', '0'\n            [\"(#{@column} IS NULL OR #{@column} = ?)\", false]\n          when 'true', 't', '1'\n            [\"(#{@column} = ?)\", true]\n          end\n        end\n\n        def column_for_value(value)\n          [\"(#{@column} = ?)\", value]\n        end\n\n        def build_statement_for_belongs_to_association\n          return if @value.blank?\n\n          [\"(#{@column} = ?)\", @value.to_i] if @value.to_i.to_s == @value\n        end\n\n        def build_statement_for_string_or_text\n          return if @value.blank?\n\n          return [\"(#{@column} = ?)\", @value] if ['is', '='].include?(@operator)\n\n          @value = @value.mb_chars.downcase unless %w[postgresql postgis].include? ar_adapter\n\n          @value =\n            case @operator\n            when 'default', 'like', 'not_like'\n              \"%#{@value}%\"\n            when 'starts_with'\n              \"#{@value}%\"\n            when 'ends_with'\n              \"%#{@value}\"\n            else\n              return\n            end\n\n          if %w[postgresql postgis].include? ar_adapter\n            if @operator == 'not_like'\n              [\"(#{@column} NOT ILIKE ?)\", @value]\n            else\n              [\"(#{@column} ILIKE ?)\", @value]\n            end\n          elsif @operator == 'not_like'\n            [\"(LOWER(#{@column}) NOT LIKE ?)\", @value]\n          else\n            [\"(LOWER(#{@column}) LIKE ?)\", @value]\n          end\n        end\n\n        def build_statement_for_enum\n          return if @value.blank?\n\n          [\"(#{@column} IN (?))\", Array.wrap(@value)]\n        end\n\n        def build_statement_for_uuid\n          column_for_value(@value) if /\\A[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}\\z/.match?(@value.to_s)\n        end\n\n        def ar_adapter\n          @adapter_name.downcase\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/mongoid/association.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Adapters\n    module Mongoid\n      class Association\n        attr_reader :association, :model\n\n        delegate :autosave?, to: :association\n\n        def initialize(association, model)\n          @association = association\n          @model = model\n        end\n\n        def name\n          association.name.to_sym\n        end\n\n        def pretty_name\n          name.to_s.tr('_', ' ').capitalize\n        end\n\n        def type\n          case macro.to_sym\n          when :belongs_to, :referenced_in, :embedded_in\n            :belongs_to\n          when :has_one, :references_one, :embeds_one\n            :has_one\n          when :has_many, :references_many, :embeds_many\n            :has_many\n          when :has_and_belongs_to_many, :references_and_referenced_in_many\n            :has_and_belongs_to_many\n          else\n            raise \"Unknown association type: #{macro.inspect}\"\n          end\n        end\n\n        def field_type\n          if polymorphic?\n            :polymorphic_association\n          else\n            :\"#{type}_association\"\n          end\n        end\n\n        def klass\n          if polymorphic? && %i[referenced_in belongs_to].include?(macro)\n            polymorphic_parents(:mongoid, association.inverse_class_name, name) || []\n          else\n            association.klass\n          end\n        end\n\n        def primary_key\n          case type\n          when :belongs_to, :has_and_belongs_to_many\n            association.primary_key.to_sym\n          else\n            :_id\n          end\n        end\n\n        def foreign_key\n          return if embeds?\n\n          begin\n            association.foreign_key.to_sym\n          rescue StandardError\n            nil\n          end\n        end\n\n        def foreign_key_nullable?\n          return if foreign_key.nil?\n\n          true\n        end\n\n        def foreign_type\n          return unless polymorphic? && %i[referenced_in belongs_to].include?(macro)\n\n          association.inverse_type.try(:to_sym) || :\"#{name}_type\"\n        end\n\n        def foreign_inverse_of\n          return unless polymorphic? && %i[referenced_in belongs_to].include?(macro)\n\n          inverse_of_field.try(:to_sym)\n        end\n\n        def key_accessor\n          case macro.to_sym\n          when :has_many\n            :\"#{name.to_s.singularize}_ids\"\n          when :has_one\n            :\"#{name}_id\"\n          when :embedded_in, :embeds_one, :embeds_many\n            nil\n          else\n            foreign_key\n          end\n        end\n\n        def as\n          association.as.try :to_sym\n        end\n\n        def polymorphic?\n          association.polymorphic? && %i[referenced_in belongs_to].include?(macro)\n        end\n\n        def inverse_of\n          association.inverse_of.try :to_sym\n        end\n\n        def read_only?\n          false\n        end\n\n        def nested_options\n          nested = nested_attributes_options.try { |o| o[name] }\n          if !nested && %i[embeds_one embeds_many].include?(macro.to_sym) && !cyclic?\n            raise <<~MSG\n              Embedded association without accepts_nested_attributes_for can't be handled by RailsAdmin,\n              because embedded model doesn't have top-level access.\n              Please add `accepts_nested_attributes_for :#{association.name}' line to `#{model}' model.\n            MSG\n          end\n\n          nested\n        end\n\n        def association?\n          true\n        end\n\n        def macro\n          association.try(:macro) || association.class.name.split('::').last.underscore.to_sym\n        end\n\n        def embeds?\n          %i[embeds_one embeds_many].include?(macro)\n        end\n\n      private\n\n        def inverse_of_field\n          association.respond_to?(:inverse_of_field) && association.inverse_of_field\n        end\n\n        def cyclic?\n          association.respond_to?(:cyclic?) ? association.cyclic? : association.cyclic\n        end\n\n        delegate :nested_attributes_options, to: :model, prefix: false\n        delegate :polymorphic_parents, to: RailsAdmin::AbstractModel\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/mongoid/bson.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'mongoid'\n\nmodule RailsAdmin\n  module Adapters\n    module Mongoid\n      class Bson\n        OBJECT_ID =\n          if defined?(Moped::BSON)\n            Moped::BSON::ObjectId\n          elsif defined?(BSON::ObjectId)\n            BSON::ObjectId\n          end\n\n        class << self\n          def parse_object_id(value)\n            OBJECT_ID.from_string(value)\n          rescue StandardError => e\n            raise e if %w[\n              Moped::Errors::InvalidObjectId\n              BSON::ObjectId::Invalid\n              BSON::InvalidObjectId\n              BSON::Error::InvalidObjectId\n            ].exclude?(e.class.to_s)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/mongoid/extension.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Adapters\n    module Mongoid\n      module Extension\n        extend ActiveSupport::Concern\n\n        included do\n          class_attribute :nested_attributes_options\n          self.nested_attributes_options = {}\n          class << self\n            def rails_admin(&block)\n              RailsAdmin.config(self, &block)\n            end\n\n            alias_method :accepts_nested_attributes_for_without_rails_admin, :accepts_nested_attributes_for\n            alias_method :accepts_nested_attributes_for, :accepts_nested_attributes_for_with_rails_admin\n          end\n        end\n\n        def rails_admin_default_object_label_method\n          new_record? ? \"new #{self.class}\" : \"#{self.class} ##{id}\"\n        end\n\n        def safe_send(value)\n          if attributes.detect { |k, _v| k.to_s == value.to_s }\n            read_attribute(value)\n          else\n            send(value)\n          end\n        end\n\n        module ClassMethods\n          # Mongoid accepts_nested_attributes_for does not store options in accessible scope,\n          # so we intercept the call and store it in instance variable which can be accessed from outside\n          def accepts_nested_attributes_for_with_rails_admin(*args)\n            options = args.extract_options!\n            args.each do |arg|\n              nested_attributes_options[arg.to_sym] = options.reverse_merge(allow_destroy: false, update_only: false)\n            end\n            args << options\n            accepts_nested_attributes_for_without_rails_admin(*args)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/mongoid/object_extension.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Adapters\n    module Mongoid\n      module ObjectExtension\n        def self.extended(object)\n          object.associations.each do |name, association|\n            association = Association.new(association, object.class)\n            case association.macro\n            when :has_many\n              unless association.autosave?\n                object.singleton_class.after_create do\n                  send(name).each(&:save)\n                end\n              end\n            when :has_one\n              unless association.autosave?\n                object.singleton_class.after_create do\n                  send(name)&.save\n                end\n              end\n            end\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/mongoid/property.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Adapters\n    module Mongoid\n      class Property\n        STRING_TYPE_COLUMN_NAMES = %i[name title subject].freeze\n        attr_reader :property, :model\n\n        def initialize(property, model)\n          @property = property\n          @model = model\n        end\n\n        def name\n          (property.options[:as] || property.name).to_sym\n        end\n\n        def pretty_name\n          (property.options[:as] || property.name).to_s.tr('_', ' ').capitalize\n        end\n\n        def type\n          case property.type.to_s\n          when 'Array', 'Hash', 'Money'\n            :serialized\n          when 'BigDecimal'\n            :decimal\n          when 'Boolean', 'Mongoid::Boolean'\n            :boolean\n          when 'BSON::ObjectId', 'Moped::BSON::ObjectId'\n            :bson_object_id\n          when 'Date'\n            :date\n          when 'ActiveSupport::TimeWithZone', 'DateTime', 'Time'\n            :datetime\n          when 'Float'\n            :float\n          when 'Integer'\n            :integer\n          when 'Object'\n            object_field_type\n          when 'String'\n            string_field_type\n          when 'Symbol'\n            :string\n          else\n            :string\n          end\n        end\n\n        def length\n          (length_validation_lookup || 255) if type == :string\n        end\n\n        def nullable?\n          true\n        end\n\n        def serial?\n          name == :_id\n        end\n\n        def association?\n          false\n        end\n\n        def read_only?\n          model.readonly_attributes.include? property.name.to_s\n        end\n\n      private\n\n        def object_field_type\n          association = Association.new model.relations.values.detect { |r| r.try(:foreign_key).try(:to_sym) == name }, model\n          if %i[belongs_to referenced_in embedded_in].include?(association.macro)\n            :bson_object_id\n          else\n            :string\n          end\n        end\n\n        def string_field_type\n          if ((length = length_validation_lookup) && length < 256) || STRING_TYPE_COLUMN_NAMES.include?(name)\n            :string\n          else\n            :text\n          end\n        end\n\n        def length_validation_lookup\n          shortest = model.validators.select { |validator| validator.respond_to?(:attributes) && validator.attributes.include?(name.to_sym) && validator.kind == :length && validator.options[:maximum] }.min do |a, b|\n            a.options[:maximum] <=> b.options[:maximum]\n          end\n\n          shortest && shortest.options[:maximum]\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/adapters/mongoid.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'mongoid'\nrequire 'rails_admin/config/sections/list'\nrequire 'rails_admin/adapters/mongoid/association'\nrequire 'rails_admin/adapters/mongoid/object_extension'\nrequire 'rails_admin/adapters/mongoid/property'\nrequire 'rails_admin/adapters/mongoid/bson'\n\nmodule RailsAdmin\n  module Adapters\n    module Mongoid\n      DISABLED_COLUMN_TYPES = %w[Range Moped::BSON::Binary BSON::Binary Mongoid::Geospatial::Point].freeze\n\n      def parse_object_id(value)\n        Bson.parse_object_id(value)\n      end\n\n      def new(params = {})\n        model.new(params).extend(ObjectExtension)\n      end\n\n      def get(id, scope = scoped)\n        object = scope.find(id)\n        return nil unless object\n\n        object.extend(ObjectExtension)\n      rescue StandardError => e\n        raise e if %w[\n          Mongoid::Errors::DocumentNotFound\n          Mongoid::Errors::InvalidFind\n          Moped::Errors::InvalidObjectId\n          BSON::InvalidObjectId\n          BSON::Error::InvalidObjectId\n        ].exclude?(e.class.to_s)\n      end\n\n      def scoped\n        model.scoped\n      end\n\n      def first(options = {}, scope = nil)\n        all(options, scope).first\n      end\n\n      def all(options = {}, scope = nil)\n        scope ||= scoped\n        scope = scope.includes(*options[:include]) if options[:include]\n        scope = scope.limit(options[:limit]) if options[:limit]\n        scope = scope.any_in(_id: options[:bulk_ids]) if options[:bulk_ids]\n        scope = query_scope(scope, options[:query]) if options[:query]\n        scope = filter_scope(scope, options[:filters]) if options[:filters]\n        scope = scope.send(Kaminari.config.page_method_name, options[:page]).per(options[:per]) if options[:page] && options[:per]\n        scope = sort_by(options, scope) if options[:sort]\n        scope\n      rescue NoMethodError => e\n        if /page/.match?(e.message)\n          e = e.exception <<~ERROR\n            #{e.message}\n            If you don't have kaminari-mongoid installed, add `gem 'kaminari-mongoid'` to your Gemfile.\n          ERROR\n        end\n        raise e\n      end\n\n      def count(options = {}, scope = nil)\n        all(options.merge(limit: false, page: false), scope).count\n      end\n\n      def destroy(objects)\n        Array.wrap(objects).each(&:destroy)\n      end\n\n      def primary_key\n        '_id'\n      end\n\n      def associations\n        model.relations.values.collect do |association|\n          Association.new(association, model)\n        end\n      end\n\n      def properties\n        fields = model.fields.reject { |_name, field| DISABLED_COLUMN_TYPES.include?(field.type.to_s) }\n        fields.collect { |_name, field| Property.new(field, model) }\n      end\n\n      def base_class\n        klass = model\n        klass = klass.superclass while klass.hereditary?\n        klass\n      end\n\n      def table_name\n        model.collection_name.to_s\n      end\n\n      def encoding\n        Encoding::UTF_8\n      end\n\n      def embedded?\n        associations.detect { |a| a.macro == :embedded_in }\n      end\n\n      def cyclic?\n        model.cyclic?\n      end\n\n      def adapter_supports_joins?\n        false\n      end\n\n    private\n\n      def build_statement(column, type, value, operator)\n        StatementBuilder.new(column, type, value, operator).to_statement\n      end\n\n      def make_field_conditions(field, value, operator)\n        conditions_per_collection = {}\n        field.searchable_columns.each do |column_infos|\n          collection_name, column_name = parse_collection_name(column_infos[:column])\n          statement = build_statement(column_name, column_infos[:type], value, operator)\n          next unless statement\n\n          conditions_per_collection[collection_name] ||= []\n          conditions_per_collection[collection_name] << statement\n        end\n        conditions_per_collection\n      end\n\n      def query_scope(scope, query, fields = config.list.fields.select(&:queryable?))\n        if config.list.search_by\n          scope.send(config.list.search_by, query)\n        else\n          statements = []\n\n          fields.each do |field|\n            value = parse_field_value(field, query)\n            conditions_per_collection = make_field_conditions(field, value, field.search_operator)\n            statements.concat make_condition_for_current_collection(field, conditions_per_collection)\n          end\n\n          scope.where(statements.any? ? {'$or' => statements} : {})\n        end\n      end\n\n      # filters example => {\"string_field\"=>{\"0055\"=>{\"o\"=>\"like\", \"v\"=>\"test_value\"}}, ...}\n      # \"0055\" is the filter index, no use here. o is the operator, v the value\n      def filter_scope(scope, filters, fields = config.list.fields.select(&:filterable?))\n        statements = []\n\n        filters.each_pair do |field_name, filters_dump|\n          filters_dump.each_value do |filter_dump|\n            field = fields.detect { |f| f.name.to_s == field_name }\n            next unless field\n\n            value = parse_field_value(field, filter_dump[:v])\n            conditions_per_collection = make_field_conditions(field, value, (filter_dump[:o] || 'default'))\n            field_statements = make_condition_for_current_collection(field, conditions_per_collection)\n            if field_statements.many?\n              statements << {'$or' => field_statements}\n            elsif field_statements.any?\n              statements << field_statements.first\n            end\n          end\n        end\n\n        scope.where(statements.any? ? {'$and' => statements} : {})\n      end\n\n      def parse_collection_name(column)\n        collection_name, column_name = column.split('.')\n        if associations.detect { |a| a.name == collection_name.to_sym }.try(:embeds?)\n          [table_name, column]\n        else\n          [collection_name, column_name]\n        end\n      end\n\n      def make_condition_for_current_collection(target_field, conditions_per_collection)\n        result = []\n        conditions_per_collection.each do |collection_name, conditions|\n          if collection_name == table_name\n            # conditions referring current model column are passed directly\n            result.concat conditions\n          else\n            # otherwise, collect ids of documents that satisfy search condition\n            result.concat perform_search_on_associated_collection(target_field.name, conditions)\n          end\n        end\n        result\n      end\n\n      def perform_search_on_associated_collection(field_name, conditions)\n        target_association = associations.detect { |a| a.name == field_name }\n        return [] unless target_association\n\n        model = target_association.klass\n        case target_association.type\n        when :belongs_to, :has_and_belongs_to_many\n          [{target_association.foreign_key.to_s => {'$in' => model.where('$or' => conditions).all.collect { |r| r.send(target_association.primary_key) }}}]\n        when :has_many, :has_one\n          [{target_association.primary_key.to_s => {'$in' => model.where('$or' => conditions).all.collect { |r| r.send(target_association.foreign_key) }}}]\n        end\n      end\n\n      def sort_by(options, scope)\n        return scope unless options[:sort]\n\n        case options[:sort]\n        when String\n          field_name, collection_name = options[:sort].split('.').reverse\n          raise 'sorting by associated model column is not supported in Non-Relational databases' if collection_name && collection_name != table_name\n        when Symbol\n          field_name = options[:sort].to_s\n        end\n        if options[:sort_reverse]\n          scope.asc field_name\n        else\n          scope.desc field_name\n        end\n      end\n\n      class StatementBuilder < RailsAdmin::AbstractModel::StatementBuilder\n      protected\n\n        def unary_operators\n          {\n            '_blank' => {@column => {'$in' => [nil, '']}},\n            '_present' => {@column => {'$nin' => [nil, '']}},\n            '_null' => {@column => nil},\n            '_not_null' => {@column => {'$ne' => nil}},\n            '_empty' => {@column => ''},\n            '_not_empty' => {@column => {'$ne' => ''}},\n          }\n        end\n\n      private\n\n        def build_statement_for_type\n          case @type\n          when :boolean                   then build_statement_for_boolean\n          when :integer, :decimal, :float then build_statement_for_integer_decimal_or_float\n          when :string, :text             then build_statement_for_string_or_text\n          when :enum                      then build_statement_for_enum\n          when :belongs_to_association, :bson_object_id then build_statement_for_belongs_to_association_or_bson_object_id\n          end\n        end\n\n        def build_statement_for_boolean\n          case @value\n          when 'false', 'f', '0'\n            {@column => false}\n          when 'true', 't', '1'\n            {@column => true}\n          end\n        end\n\n        def column_for_value(value)\n          {@column => value}\n        end\n\n        def build_statement_for_string_or_text\n          return if @value.blank?\n\n          @value =\n            case @operator\n            when 'not_like'\n              Regexp.compile(\"^((?!#{Regexp.escape(@value)}).)*$\", Regexp::IGNORECASE)\n            when 'default', 'like'\n              Regexp.compile(Regexp.escape(@value), Regexp::IGNORECASE)\n            when 'starts_with'\n              Regexp.compile(\"^#{Regexp.escape(@value)}\", Regexp::IGNORECASE)\n            when 'ends_with'\n              Regexp.compile(\"#{Regexp.escape(@value)}$\", Regexp::IGNORECASE)\n            when 'is', '='\n              @value.to_s\n            else\n              return\n            end\n\n          {@column => @value}\n        end\n\n        def build_statement_for_enum\n          return if @value.blank?\n\n          {@column => {'$in' => Array.wrap(@value)}}\n        end\n\n        def build_statement_for_belongs_to_association_or_bson_object_id\n          {@column => @value} if @value\n        end\n\n        def range_filter(min, max)\n          if min && max && min == max\n            {@column => min}\n          elsif min && max\n            {@column => {'$gte' => min, '$lte' => max}}\n          elsif min\n            {@column => {'$gte' => min}}\n          elsif max\n            {@column => {'$lte' => max}}\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/base.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/proxyable'\nrequire 'rails_admin/config/configurable'\nrequire 'rails_admin/config/hideable'\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class Base\n        include RailsAdmin::Config::Proxyable\n        include RailsAdmin::Config::Configurable\n        include RailsAdmin::Config::Hideable\n\n        register_instance_option :only do\n          nil\n        end\n\n        register_instance_option :except do\n          []\n        end\n\n        register_instance_option :show_in_navigation do\n          root?\n        end\n\n        register_instance_option :show_in_sidebar do\n          !show_in_navigation\n        end\n\n        register_instance_option :show_in_menu do\n          true\n        end\n\n        register_instance_option :sidebar_label do\n          nil\n        end\n\n        # http://getbootstrap.com/2.3.2/base-css.html#icons\n        register_instance_option :link_icon do\n          'fas fa-question'\n        end\n\n        # Should the action be visible\n        register_instance_option :visible? do\n          authorized?\n        end\n\n        register_instance_option :enabled? do\n          bindings[:abstract_model].nil? || (\n            (only.nil? || [only].flatten.collect(&:to_s).include?(bindings[:abstract_model].to_s)) &&\n            ![except].flatten.collect(&:to_s).include?(bindings[:abstract_model].to_s) &&\n            !bindings[:abstract_model].config.excluded?\n          ) && (!respond_to?(:writable?) || writable?)\n        end\n\n        register_instance_option :authorized? do\n          enabled? && (\n            bindings[:controller].try(:authorization_adapter).nil? || bindings[:controller].authorization_adapter.authorized?(authorization_key, bindings[:abstract_model], bindings[:object])\n          )\n        end\n\n        # Is the action acting on the root level (Example: /admin/contact)\n        register_instance_option :root? do\n          false\n        end\n\n        # Is the action on a model scope (Example: /admin/team/export)\n        register_instance_option :collection? do\n          false\n        end\n\n        # Is the action on an object scope (Example: /admin/team/1/edit)\n        register_instance_option :member? do\n          false\n        end\n\n        # Target window [_self, _blank]\n        register_instance_option :link_target do\n          nil\n        end\n\n        # Determines whether to navigate via Turbo Drive or not\n        register_instance_option :turbo? do\n          true\n        end\n\n        # This block is evaluated in the context of the controller when action is called\n        # You can access:\n        # - @objects if you're on a model scope\n        # - @abstract_model & @model_config if you're on a model or object scope\n        # - @object if you're on an object scope\n        register_instance_option :controller do\n          proc do\n            render action: @action.template_name\n          end\n        end\n\n        # Model scoped actions only. You will need to handle params[:bulk_ids] in controller\n        register_instance_option :bulkable? do\n          false\n        end\n\n        # View partial name (called in default :controller block)\n        register_instance_option :template_name do\n          key.to_sym\n        end\n\n        # For CanCanCan and the like\n        register_instance_option :authorization_key do\n          key.to_sym\n        end\n\n        # List of methods allowed. Note that you are responsible for correctly handling them in :controller block\n        register_instance_option :http_methods do\n          [:get]\n        end\n\n        # Url fragment\n        register_instance_option :route_fragment do\n          custom_key.to_s\n        end\n\n        # Controller action name\n        register_instance_option :action_name do\n          custom_key.to_sym\n        end\n\n        # I18n key\n        register_instance_option :i18n_key do\n          key\n        end\n\n        # User should override only custom_key (action name and route fragment change, allows for duplicate actions)\n        register_instance_option :custom_key do\n          key\n        end\n\n        # Breadcrumb parent\n        register_instance_option :breadcrumb_parent do\n          if root?\n            [:dashboard]\n          elsif collection?\n            [:index, bindings[:abstract_model]]\n          elsif member?\n            [:show, bindings[:abstract_model], bindings[:object]]\n          end\n        end\n\n        # Off API.\n\n        def key\n          self.class.key\n        end\n\n        def self.key\n          name.to_s.demodulize.underscore.to_sym\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/bulk_delete.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class BulkDelete < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :collection do\n          true\n        end\n\n        register_instance_option :http_methods do\n          %i[post delete]\n        end\n\n        register_instance_option :controller do\n          proc do\n            if request.post? # BULK DELETE\n              @objects = list_entries(@model_config, :destroy)\n\n              if @objects.blank?\n                flash[:error] = t('admin.flash.error', name: pluralize(0, @model_config.label), action: t('admin.actions.delete.done'))\n                redirect_to index_path\n              else\n                render @action.template_name\n              end\n\n            elsif request.delete? # BULK DESTROY\n\n              destroyed = nil\n              not_destroyed = nil\n\n              unless params[:bulk_ids].blank?\n                @objects = list_entries(@model_config, :destroy)\n                unless @objects.blank?\n                  processed_objects = @abstract_model.destroy(@objects)\n                  destroyed = processed_objects.select(&:destroyed?)\n                  not_destroyed = processed_objects - destroyed\n                  destroyed.each do |object|\n                    @auditing_adapter&.delete_object(object, @abstract_model, _current_user)\n                  end\n                end\n              end\n\n              if destroyed.nil?\n                flash[:error] = t('admin.flash.error', name: pluralize(0, @model_config.label), action: t('admin.actions.delete.done'))\n              else\n                flash[:success] = t('admin.flash.successful', name: pluralize(destroyed.count, @model_config.label), action: t('admin.actions.delete.done')) unless destroyed.empty?\n                flash[:error] = t('admin.flash.error', name: pluralize(not_destroyed.count, @model_config.label), action: t('admin.actions.delete.done')) unless not_destroyed.empty?\n              end\n              redirect_to back_or_index\n            end\n          end\n        end\n\n        register_instance_option :authorization_key do\n          :destroy\n        end\n\n        register_instance_option :bulkable? do\n          true\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/dashboard.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class Dashboard < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :root? do\n          true\n        end\n\n        register_instance_option :breadcrumb_parent do\n          nil\n        end\n\n        register_instance_option :auditing_versions_limit do\n          100\n        end\n\n        register_instance_option :controller do\n          proc do\n            @history = @auditing_adapter&.latest(@action.auditing_versions_limit) if @action.history?\n            if @action.statistics?\n              model_configs = RailsAdmin::Config.visible_models(controller: self)\n\n              @abstract_models = model_configs.map(&:abstract_model)\n              @most_recent_created = {}\n              @count = {}\n              @max = 0\n              model_configs.each do |config|\n                scope = @authorization_adapter&.query(:index, config.abstract_model)\n                current_count = config.abstract_model.count({}, scope)\n                @max = current_count > @max ? current_count : @max\n                name = config.abstract_model.model.name\n                @count[name] = current_count\n                @most_recent_created[name] = config.last_created_at\n              end\n            end\n            render @action.template_name, status: @status_code || :ok\n          end\n        end\n\n        register_instance_option :route_fragment do\n          ''\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-home'\n        end\n\n        register_instance_option :statistics? do\n          true\n        end\n\n        register_instance_option :history? do\n          true\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/delete.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class Delete < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :member do\n          true\n        end\n\n        register_instance_option :route_fragment do\n          'delete'\n        end\n\n        register_instance_option :http_methods do\n          %i[get delete]\n        end\n\n        register_instance_option :authorization_key do\n          :destroy\n        end\n\n        register_instance_option :controller do\n          proc do\n            if request.get? # DELETE\n\n              respond_to do |format|\n                format.html { render @action.template_name }\n                format.js   { render @action.template_name, layout: false }\n              end\n\n            elsif request.delete? # DESTROY\n\n              @auditing_adapter&.delete_object(@object, @abstract_model, _current_user)\n              if @object.destroy\n                flash[:success] = t('admin.flash.successful', name: @model_config.label, action: t('admin.actions.delete.done'))\n                redirect_to index_path\n              else\n                handle_save_error :delete\n              end\n\n            end\n          end\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-times'\n        end\n\n        register_instance_option :writable? do\n          !(bindings[:object] && bindings[:object].readonly?)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/edit.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class Edit < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :member do\n          true\n        end\n\n        register_instance_option :http_methods do\n          %i[get put]\n        end\n\n        register_instance_option :controller do\n          proc do\n            if request.get? # EDIT\n\n              respond_to do |format|\n                format.html { render @action.template_name }\n                format.js   { render @action.template_name, layout: 'rails_admin/modal', content_type: Mime[:html].to_s }\n              end\n\n            elsif request.put? # UPDATE\n              sanitize_params_for!(request.xhr? ? :modal : :update)\n\n              @object.assign_attributes(params[@abstract_model.param_key])\n              @authorization_adapter&.authorize(:update, @abstract_model, @object)\n              changes = @object.changes\n              if @object.save\n                @auditing_adapter&.update_object(@object, @abstract_model, _current_user, changes)\n                respond_to do |format|\n                  format.html { redirect_to_on_success }\n                  format.json { render json: {id: @object.id.to_s, label: @model_config.with(object: @object).object_label} }\n                end\n              else\n                handle_save_error :edit\n              end\n\n            end\n          end\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-pencil-alt'\n        end\n\n        register_instance_option :writable? do\n          !(bindings[:object] && bindings[:object].readonly?)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/export.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class Export < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :collection do\n          true\n        end\n\n        register_instance_option :http_methods do\n          %i[get post]\n        end\n\n        register_instance_option :controller do\n          proc do\n            format = params[:json] && :json || params[:csv] && :csv || params[:xml] && :xml\n            if format\n              request.format = format\n              @schema = HashHelper.symbolize(params[:schema].slice(:except, :include, :methods, :only).permit!.to_h) if params[:schema] # to_json and to_xml expect symbols for keys AND values.\n              @objects = list_entries(@model_config, :export)\n              index\n            else\n              render @action.template_name\n            end\n          end\n        end\n\n        register_instance_option :bulkable? do\n          true\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-file-export'\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/history_index.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class HistoryIndex < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :authorization_key do\n          :history\n        end\n\n        register_instance_option :collection do\n          true\n        end\n\n        register_instance_option :route_fragment do\n          'history'\n        end\n\n        register_instance_option :controller do\n          proc do\n            @general = true\n            @history = @auditing_adapter&.listing_for_model(@abstract_model, params[:query], params[:sort], params[:sort_reverse], params[:all], params[Kaminari.config.param_name]) || []\n\n            render @action.template_name\n          end\n        end\n\n        register_instance_option :template_name do\n          :history\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-book'\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/history_show.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class HistoryShow < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :authorization_key do\n          :history\n        end\n\n        register_instance_option :member do\n          true\n        end\n\n        register_instance_option :route_fragment do\n          'history'\n        end\n\n        register_instance_option :controller do\n          proc do\n            @general = false\n            @history = @auditing_adapter&.listing_for_object(@abstract_model, @object, params[:query], params[:sort], params[:sort_reverse], params[:all], params[Kaminari.config.param_name]) || []\n\n            render @action.template_name\n          end\n        end\n\n        register_instance_option :template_name do\n          :history\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-book'\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/index.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'activemodel-serializers-xml'\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class Index < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :collection do\n          true\n        end\n\n        register_instance_option :http_methods do\n          %i[get post]\n        end\n\n        register_instance_option :route_fragment do\n          ''\n        end\n\n        register_instance_option :breadcrumb_parent do\n          parent_model = bindings[:abstract_model].try(:config).try(:parent)\n          am = parent_model && RailsAdmin.config(parent_model).try(:abstract_model)\n          if am\n            [:index, am]\n          else\n            [:dashboard]\n          end\n        end\n\n        register_instance_option :controller do\n          proc do\n            @objects ||= list_entries\n\n            unless @model_config.list.scopes.empty?\n              if params[:scope].blank?\n                @objects = @objects.send(@model_config.list.scopes.first) unless @model_config.list.scopes.first.nil?\n              elsif @model_config.list.scopes.collect(&:to_s).include?(params[:scope])\n                @objects = @objects.send(params[:scope].to_sym)\n              end\n            end\n\n            respond_to do |format|\n              format.html do\n                render @action.template_name, status: @status_code || :ok\n              end\n\n              format.json do\n                output =\n                  if params[:compact]\n                    if @association\n                      @association.collection(@objects).collect { |(label, id)| {id: id, label: label} }\n                    else\n                      @objects.collect { |object| {id: object.id.to_s, label: object.send(@model_config.object_label_method).to_s} }\n                    end\n                  else\n                    @objects.to_json(@schema)\n                  end\n\n                if params[:send_data]\n                  send_data output, filename: \"#{params[:model_name]}_#{DateTime.now.strftime('%Y-%m-%d_%Hh%Mm%S')}.json\"\n                else\n                  render json: output, root: false\n                end\n              end\n\n              format.xml do\n                output = @objects.to_xml(@schema)\n                if params[:send_data]\n                  send_data output, filename: \"#{params[:model_name]}_#{DateTime.now.strftime('%Y-%m-%d_%Hh%Mm%S')}.xml\"\n                else\n                  render xml: output\n                end\n              end\n\n              format.csv do\n                header, encoding, output = CSVConverter.new(@objects, @schema).to_csv(params[:csv_options].permit!.to_h)\n                if params[:send_data]\n                  send_data output,\n                            type: \"text/csv; charset=#{encoding}; #{'header=present' if header}\",\n                            disposition: \"attachment; filename=#{params[:model_name]}_#{DateTime.now.strftime('%Y-%m-%d_%Hh%Mm%S')}.csv\"\n                else\n                  render plain: output\n                end\n              end\n            end\n          end\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-th-list'\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/new.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class New < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :collection do\n          true\n        end\n\n        register_instance_option :http_methods do\n          %i[get post] # NEW / CREATE\n        end\n\n        register_instance_option :controller do\n          proc do\n            if request.get? # NEW\n\n              @object = @abstract_model.new\n              @action = @action.with(@action.bindings.merge(object: @object))\n              @authorization_adapter&.attributes_for(:new, @abstract_model)&.each do |name, value|\n                @object.send(\"#{name}=\", value)\n              end\n              object_params = params[@abstract_model.param_key]\n              if object_params\n                sanitize_params_for!(request.xhr? ? :modal : :create)\n                @object.assign_attributes(@object.attributes.merge(object_params.to_h))\n              end\n              respond_to do |format|\n                format.html { render @action.template_name }\n                format.js   { render @action.template_name, layout: 'rails_admin/modal', content_type: Mime[:html].to_s }\n              end\n\n            elsif request.post? # CREATE\n\n              @modified_assoc = []\n              @object = @abstract_model.new\n              sanitize_params_for!(request.xhr? ? :modal : :create)\n\n              @object.assign_attributes(params[@abstract_model.param_key])\n              @authorization_adapter&.authorize(:create, @abstract_model, @object)\n\n              if @object.save\n                @auditing_adapter&.create_object(@object, @abstract_model, _current_user)\n                respond_to do |format|\n                  format.html { redirect_to_on_success }\n                  format.json { render json: {id: @object.id.to_s, label: @model_config.with(object: @object).object_label} }\n                end\n              else\n                handle_save_error\n              end\n\n            end\n          end\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-plus'\n        end\n\n        register_instance_option :writable? do\n          !(bindings[:object] && bindings[:object].readonly?)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/show.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class Show < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :member do\n          true\n        end\n\n        register_instance_option :route_fragment do\n          ''\n        end\n\n        register_instance_option :breadcrumb_parent do\n          [:index, bindings[:abstract_model]]\n        end\n\n        register_instance_option :controller do\n          proc do\n            respond_to do |format|\n              format.json { render json: @object }\n              format.html { render @action.template_name }\n            end\n          end\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-info-circle'\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions/show_in_app.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class ShowInApp < RailsAdmin::Config::Actions::Base\n        RailsAdmin::Config::Actions.register(self)\n\n        register_instance_option :member do\n          true\n        end\n\n        register_instance_option :visible? do\n          authorized? && begin\n            bindings[:controller].main_app.url_for(bindings[:object])\n          rescue StandardError\n            false\n          end\n        end\n\n        register_instance_option :controller do\n          proc do\n            redirect_to main_app.url_for(@object)\n          end\n        end\n\n        register_instance_option :link_icon do\n          'fas fa-eye'\n        end\n\n        register_instance_option :turbo? do\n          false\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/actions.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Actions\n      class << self\n        def all(scope = nil, bindings = {})\n          if scope.is_a?(Hash)\n            bindings = scope\n            scope = :all\n          end\n          scope ||= :all\n          init_actions!\n          actions =\n            case scope\n            when :all\n              @@actions\n            when :root\n              @@actions.select(&:root?)\n            when :collection\n              @@actions.select(&:collection?)\n            when :bulkable\n              @@actions.select(&:bulkable?)\n            when :member\n              @@actions.select(&:member?)\n            end\n\n          actions = actions.collect { |action| action.with(bindings) }\n          bindings[:controller] ? actions.select(&:visible?) : actions\n        end\n\n        def find(custom_key, bindings = {})\n          init_actions!\n          action = @@actions.detect { |a| a.custom_key == custom_key }.try(:with, bindings)\n          bindings[:controller] ? (action.try(:visible?) && action || nil) : action\n        end\n\n        def collection(key, parent_class = :base, &block)\n          add_action key, parent_class, :collection, &block\n        end\n\n        def member(key, parent_class = :base, &block)\n          add_action key, parent_class, :member, &block\n        end\n\n        def root(key, parent_class = :base, &block)\n          add_action key, parent_class, :root, &block\n        end\n\n        def add_action(key, parent_class, parent, &block)\n          a = \"RailsAdmin::Config::Actions::#{parent_class.to_s.camelize}\".constantize.new\n          a.instance_eval(%(\n            #{parent} true\n            def key\n              :#{key}\n            end\n          ), __FILE__, __LINE__ - 5)\n          add_action_custom_key(a, &block)\n        end\n\n        def reset\n          @@actions = nil\n        end\n\n        def register(name, klass = nil)\n          if klass.nil? && name.is_a?(Class)\n            klass = name\n            name = klass.to_s.demodulize.underscore.to_sym\n          end\n\n          instance_eval %{\n            def #{name}(&block)\n              action = #{klass}.new\n              add_action_custom_key(action, &block)\n            end\n          }, __FILE__, __LINE__ - 5\n        end\n\n      private\n\n        def init_actions!\n          @@actions ||= [\n            Dashboard.new,\n            Index.new,\n            Show.new,\n            New.new,\n            Edit.new,\n            Export.new,\n            Delete.new,\n            BulkDelete.new,\n            HistoryShow.new,\n            HistoryIndex.new,\n            ShowInApp.new,\n          ]\n        end\n\n        def add_action_custom_key(action, &block)\n          action.instance_eval(&block) if block\n          @@actions ||= []\n          if action.custom_key.in?(@@actions.collect(&:custom_key))\n            raise \"Action #{action.custom_key} already exists. Please change its custom key.\"\n          else\n            @@actions << action\n          end\n        end\n      end\n    end\n  end\nend\n\nrequire 'rails_admin/config/actions/base'\nrequire 'rails_admin/config/actions/dashboard'\nrequire 'rails_admin/config/actions/index'\nrequire 'rails_admin/config/actions/show'\nrequire 'rails_admin/config/actions/show_in_app'\nrequire 'rails_admin/config/actions/history_show'\nrequire 'rails_admin/config/actions/history_index'\nrequire 'rails_admin/config/actions/new'\nrequire 'rails_admin/config/actions/edit'\nrequire 'rails_admin/config/actions/export'\nrequire 'rails_admin/config/actions/delete'\nrequire 'rails_admin/config/actions/bulk_delete'\n"
  },
  {
    "path": "lib/rails_admin/config/configurable.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    # A module for all configurables.\n\n    module Configurable\n      def self.included(base)\n        base.send :extend, ClassMethods\n      end\n\n      def has_option?(name) # rubocop:disable Naming/PredicatePrefix?\n        options = self.class.instance_variable_get('@config_options')\n        options&.key?(name)\n      end\n\n      # Register an instance option for this object only\n      def register_instance_option(option_name, &default)\n        scope = class << self; self; end\n        self.class.register_instance_option(option_name, scope, &default)\n      end\n\n      def register_deprecated_instance_option(option_name, replacement_option_name = nil, &custom_error)\n        scope = class << self; self; end\n        self.class.register_deprecated_instance_option(option_name, replacement_option_name, scope, &custom_error)\n      end\n\n    private\n\n      def with_recurring(option_name, value_proc, default_proc)\n        # Track recursive invocation with an instance variable. This prevents run-away recursion\n        # and allows configurations such as\n        # label { \"#{label}\".upcase }\n        # This will use the default definition when called recursively.\n        Thread.current[:rails_admin_recurring] ||= {}\n        Thread.current[:rails_admin_recurring][self] ||= {}\n        if Thread.current[:rails_admin_recurring][self][option_name]\n          instance_eval(&default_proc)\n        else\n          Thread.current[:rails_admin_recurring][self][option_name] = true\n          instance_eval(&value_proc)\n        end\n      ensure\n        Thread.current[:rails_admin_recurring].delete(self)\n      end\n\n      module ClassMethods\n        # Register an instance option. Instance option is a configuration\n        # option that stores its value within an instance variable and is\n        # accessed by an instance method. Both go by the name of the option.\n        def register_instance_option(option_name, scope = self, &default)\n          options = scope.instance_variable_get('@config_options') ||\n                    scope.instance_variable_set('@config_options', {})\n\n          option_name = option_name.to_s\n          options[option_name] = nil\n\n          # If it's a boolean create an alias for it and remove question mark\n          if option_name.end_with?('?')\n            scope.send(:define_method, \"#{option_name.chop!}?\") do\n              send(option_name)\n            end\n          end\n\n          # Define getter/setter by the option name\n          scope.send(:define_method, option_name) do |*args, &block|\n            if !args[0].nil? || block\n              # Invocation with args --> This is the declaration of the option, i.e. setter\n              instance_variable_set(\"@#{option_name}_registered\", args[0].nil? ? block : args[0])\n            else\n              # Invocation without args nor block --> It's the use of the option, i.e. getter\n              value = instance_variable_get(\"@#{option_name}_registered\")\n              case value\n              when Proc\n                value = with_recurring(option_name, value, default)\n              when nil\n                value = instance_eval(&default)\n              end\n              value\n            end\n          end\n        end\n\n        def register_deprecated_instance_option(option_name, replacement_option_name = nil, scope = self)\n          scope.send(:define_method, option_name) do |*args, &block|\n            if replacement_option_name\n              ActiveSupport::Deprecation.warn(\"The #{option_name} configuration option is deprecated, please use #{replacement_option_name}.\")\n              send(replacement_option_name, *args, &block)\n            elsif block_given?\n              yield\n            else\n              raise \"The #{option_name} configuration option is removed without replacement.\"\n            end\n          end\n        end\n\n        # Register a class option. Class option is a configuration\n        # option that stores it's value within a class object's instance variable\n        # and is accessed by a class method. Both go by the name of the option.\n        def register_class_option(option_name, &default)\n          scope = class << self; self; end\n          register_instance_option(option_name, scope, &default)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/const_load_suppressor.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module ConstLoadSuppressor\n      class << self\n        @original_const_missing = nil\n\n        def suppressing\n          raise 'Constant Loading is already suppressed' if @original_const_missing\n\n          begin\n            @original_const_missing = Object.method(:const_missing)\n            intercept_const_missing\n            yield\n          ensure\n            Object.define_singleton_method(:const_missing, @original_const_missing)\n            @original_const_missing = nil\n          end\n        end\n\n        def allowing\n          if @original_const_missing\n            begin\n              Object.define_singleton_method(:const_missing, @original_const_missing)\n              yield\n            ensure\n              intercept_const_missing\n            end\n          else\n            yield\n          end\n        end\n\n      private\n\n        def intercept_const_missing\n          Object.define_singleton_method(:const_missing) do |name|\n            ConstProxy.new(name.to_s)\n          end\n        end\n      end\n\n      class ConstProxy < BasicObject\n        attr_reader :name\n\n        def initialize(name)\n          @name = name\n        end\n\n        def klass\n          @klass ||=\n            begin\n              unless ::Object.const_defined?(name)\n                ::Kernel.raise <<~MESSAGE\n                  The constant #{name} is not loaded yet upon the execution of the RailsAdmin initializer.\n                  We don't recommend to do this and may lead to issues, but if you really have to do so you can explicitly require it by adding:\n\n                    require '#{name.underscore}'\n\n                  on top of config/initializers/rails_admin.rb.\n                MESSAGE\n              end\n              name.constantize\n            end\n        end\n\n        def method_missing(method_name, *args, &block)\n          klass.send(method_name, *args, &block)\n        end\n\n        def respond_to_missing?(method_name, include_private = false)\n          super || klass.respond_to?(method_name, include_private)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/association.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config'\nrequire 'rails_admin/config/fields/base'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      class Association < RailsAdmin::Config::Fields::Base\n        # Reader for the association information hash\n        def association\n          @properties\n        end\n\n        def method_name\n          nested_form ? :\"#{name}_attributes\" : association.key_accessor\n        end\n\n        register_instance_option :pretty_value do\n          v = bindings[:view]\n          [value].flatten.select(&:present?).collect do |associated|\n            amc = polymorphic? ? RailsAdmin.config(associated) : associated_model_config # perf optimization for non-polymorphic associations\n            am = amc.abstract_model\n            wording = associated.send(amc.object_label_method)\n            can_see = !am.embedded? && (show_action = v.action(:show, am, associated))\n            can_see ? v.link_to(wording, v.url_for(action: show_action.action_name, model_name: am.to_param, id: associated.id)) : ERB::Util.html_escape(wording)\n          end.to_sentence.html_safe.presence || '-'\n        end\n\n        # Accessor whether association is visible or not. By default\n        # association checks whether the child model is excluded in\n        # configuration or not.\n        register_instance_option :visible? do\n          @visible ||= !associated_model_config.excluded?\n        end\n\n        # use the association name as a key, not the association key anymore!\n        register_instance_option :label do\n          (@label ||= {})[::I18n.locale] ||= abstract_model.model.human_attribute_name association.name\n        end\n\n        # scope for possible associable records\n        register_instance_option :associated_collection_scope do\n          # bindings[:object] & bindings[:controller] available\n          associated_collection_scope_limit = (associated_collection_cache_all ? nil : 30)\n          proc do |scope|\n            scope.limit(associated_collection_scope_limit)\n          end\n        end\n\n        # inverse relationship\n        register_instance_option :inverse_of do\n          association.inverse_of\n        end\n\n        # preload entire associated collection (per associated_collection_scope) on load\n        # Be sure to set limit in associated_collection_scope if set is large\n        register_instance_option :associated_collection_cache_all do\n          @associated_collection_cache_all ||= dynamically_scope_by.blank? && (associated_model_config.abstract_model.count < associated_model_limit)\n        end\n\n        # client-side dynamic scoping\n        register_instance_option :dynamically_scope_by do\n          nil\n        end\n\n        # parses #dynamically_scope_by and returns a Hash in the form of\n        # {[form field name in this model]: [field name in the associated model]}\n        def dynamic_scope_relationships\n          @dynamic_scope_relationships ||=\n            Array.wrap(dynamically_scope_by).flat_map do |field|\n              field.is_a?(Hash) ? field.to_a : [[field, field]]\n            end.map do |field_name, target_name| # rubocop:disable Style/MultilineBlockChain\n              field = section.fields.detect { |f| f.name == field_name }\n              raise \"Field '#{field_name}' was given for #dynamically_scope_by but not found in '#{abstract_model.model_name}'\" unless field\n\n              target_field = associated_model_config.list.fields.detect { |f| f.name == target_name }\n              raise \"Field '#{field_name}' was given for #dynamically_scope_by but not found in '#{associated_model_config.abstract_model.model_name}'\" unless target_field\n              raise \"Field '#{field_name}' in '#{associated_model_config.abstract_model.model_name}' can't be used for dynamic scoping because it's not filterable\" unless target_field.filterable\n\n              [field.method_name, target_name]\n            end.to_h\n        end\n\n        # determines whether association's elements can be removed\n        register_instance_option :removable? do\n          association.foreign_key_nullable?\n        end\n\n        register_instance_option :eager_load do\n          !!searchable\n        end\n\n        register_instance_option :inline_add do\n          true\n        end\n\n        register_instance_option :inline_edit do\n          true\n        end\n\n        # Reader for the association's child model's configuration\n        def associated_model_config\n          @associated_model_config ||= RailsAdmin.config(association.klass)\n        end\n\n        # Reader for the association's child model object's label method\n        def associated_object_label_method\n          @associated_object_label_method ||= associated_model_config.object_label_method\n        end\n\n        # Reader for associated primary key\n        def associated_primary_key\n          association.primary_key\n        end\n\n        # Returns params which are to be set in modals\n        def associated_prepopulate_params\n          {}\n        end\n\n        # Reader whether this is a polymorphic association\n        def polymorphic?\n          association.polymorphic?\n        end\n\n        # Reader for nested attributes\n        register_instance_option :nested_form do\n          association.nested_options\n        end\n\n        # Reader for the association's value unformatted\n        def value\n          bindings[:object].send(association.name)\n        end\n\n        # Returns collection of all selectable records\n        def collection(scope = nil)\n          (scope || bindings[:controller].list_entries(associated_model_config, :index, associated_collection_scope, false)).\n            map { |o| [o.send(associated_object_label_method), format_key(o.send(associated_primary_key)).to_s] }\n        end\n\n        # has many?\n        def multiple?\n          true\n        end\n\n        def virtual?\n          true\n        end\n\n        def associated_model_limit\n          RailsAdmin.config.default_associated_collection_limit\n        end\n\n      private\n\n        def format_key(key)\n          if key.is_a?(Array)\n            RailsAdmin.config.composite_keys_serializer.serialize(key)\n          else\n            key\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/base.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/proxyable'\nrequire 'rails_admin/config/configurable'\nrequire 'rails_admin/config/hideable'\nrequire 'rails_admin/config/groupable'\nrequire 'rails_admin/config/inspectable'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      class Base # rubocop:disable Metrics/ClassLength\n        include RailsAdmin::Config::Proxyable\n        include RailsAdmin::Config::Configurable\n        include RailsAdmin::Config::Hideable\n        include RailsAdmin::Config::Groupable\n        include RailsAdmin::Config::Inspectable\n\n        attr_reader :name, :properties, :abstract_model, :parent, :root\n        attr_accessor :defined, :order, :section\n\n        NAMED_INSTANCE_VARIABLES = %i[\n          @parent @root @section @children_fields_registered\n          @associated_model_config @group\n        ].freeze\n\n        def initialize(parent, name, properties)\n          @parent = parent\n          @root = parent.root\n\n          @abstract_model = parent.abstract_model\n          @defined = false\n          @name = name.to_sym\n          @order = 0\n          @properties = properties\n          @section = parent\n        end\n\n        register_instance_option :css_class do\n          \"#{name}_field\"\n        end\n\n        def type_css_class\n          \"#{type}_type\"\n        end\n\n        def virtual?\n          properties.blank?\n        end\n\n        register_instance_option :column_width do\n          nil\n        end\n\n        register_instance_option :sticky? do\n          false\n        end\n\n        register_instance_option :sortable do\n          !virtual? || children_fields.first || false\n        end\n\n        def sort_column\n          if sortable == true\n            \"#{abstract_model.quoted_table_name}.#{abstract_model.quote_column_name(name)}\"\n          elsif (sortable.is_a?(String) || sortable.is_a?(Symbol)) && sortable.to_s.include?('.') # just provide sortable, don't do anything smart\n            sortable\n          elsif sortable.is_a?(Hash) # just join sortable hash, don't do anything smart\n            \"#{sortable.keys.first}.#{sortable.values.first}\"\n          elsif association? # use column on target table\n            \"#{associated_model_config.abstract_model.quoted_table_name}.#{abstract_model.quote_column_name(sortable)}\"\n          else # use described column in the field conf.\n            \"#{abstract_model.quoted_table_name}.#{abstract_model.quote_column_name(sortable)}\"\n          end\n        end\n\n        register_instance_option :searchable do\n          !virtual? || children_fields.first || false\n        end\n\n        register_instance_option :search_operator do\n          RailsAdmin::Config.default_search_operator\n        end\n\n        register_instance_option :queryable? do\n          !virtual?\n        end\n\n        register_instance_option :filterable? do\n          !!searchable\n        end\n\n        register_instance_option :filter_operators do\n          []\n        end\n\n        register_instance_option :default_filter_operator do\n          nil\n        end\n\n        def filter_options\n          {\n            label: label,\n            name: name,\n            operator: default_filter_operator,\n            operators: filter_operators,\n            type: type,\n          }\n        end\n\n        # serials and dates are reversed in list, which is more natural (last modified items first).\n        register_instance_option :sort_reverse? do\n          false\n        end\n\n        # list of columns I should search for that field [{ column: 'table_name.column', type: field.type }, {..}]\n        register_instance_option :searchable_columns do\n          @searchable_columns ||=\n            case searchable\n            when true\n              [{column: \"#{abstract_model.table_name}.#{name}\", type: type}]\n            when false\n              []\n            when :all # valid only for associations\n              table_name = associated_model_config.abstract_model.table_name\n              associated_model_config.list.fields.collect { |f| {column: \"#{table_name}.#{f.name}\", type: f.type} }\n            else\n              [searchable].flatten.collect do |f|\n                if f.is_a?(String) && f.include?('.')                            #  table_name.column\n                  table_name, column = f.split '.'\n                  type = nil\n                elsif f.is_a?(Hash)                                              #  <Model|table_name> => <attribute|column>\n                  am = AbstractModel.new(f.keys.first) if f.keys.first.is_a?(Class)\n                  table_name = am&.table_name || f.keys.first\n                  column = f.values.first\n                  property = am&.properties&.detect { |p| p.name == f.values.first.to_sym }\n                  type = property&.type\n                else                                                             #  <attribute|column>\n                  am = (association? ? associated_model_config.abstract_model : abstract_model)\n                  table_name = am.table_name\n                  column = f\n                  property = am.properties.detect { |p| p.name == f.to_sym }\n                  type = property&.type\n                end\n                {column: \"#{table_name}.#{column}\", type: (type || :string)}\n              end\n            end\n        end\n\n        register_instance_option :formatted_value do\n          value\n        end\n\n        # output for pretty printing (show, list)\n        register_instance_option :pretty_value do\n          formatted_value.presence || ' - '\n        end\n\n        # output for printing in export view (developers beware: no bindings[:view] and no data!)\n        register_instance_option :export_value do\n          pretty_value\n        end\n\n        # Accessor for field's help text displayed below input field.\n        register_instance_option :help do\n          (@help ||= {})[::I18n.locale] ||= generic_field_help\n        end\n\n        register_instance_option :html_attributes do\n          {\n            required: required?,\n          }\n        end\n\n        register_instance_option :default_value do\n          nil\n        end\n\n        # Accessor for field's label.\n        #\n        # @see RailsAdmin::AbstractModel.properties\n        register_instance_option :label do\n          (@label ||= {})[::I18n.locale] ||= abstract_model.model.human_attribute_name name\n        end\n\n        register_instance_option :hint do\n          (@hint ||= '')\n        end\n\n        # Accessor for field's maximum length per database.\n        #\n        # @see RailsAdmin::AbstractModel.properties\n        register_instance_option :length do\n          @length ||= properties&.length\n        end\n\n        # Accessor for field's length restrictions per validations\n        #\n        register_instance_option :valid_length do\n          @valid_length ||= abstract_model.model.validators_on(name).detect { |v| v.kind == :length }.try(&:options) || {}\n        end\n\n        register_instance_option :partial do\n          :form_field\n        end\n\n        # Accessor for whether this is field is mandatory.\n        #\n        # @see RailsAdmin::AbstractModel.properties\n        register_instance_option :required? do\n          context =\n            if bindings && bindings[:object]\n              bindings[:object].persisted? ? :update : :create\n            else\n              :nil\n            end\n\n          (@required ||= {})[context] ||= !!([name] + children_fields).uniq.detect do |column_name|\n            abstract_model.model.validators_on(column_name).detect do |v|\n              !(v.options[:allow_nil] || v.options[:allow_blank]) &&\n                %i[presence numericality attachment_presence].include?(v.kind) &&\n                (v.options[:on] == context || v.options[:on].blank?) &&\n                (v.options[:if].blank? && v.options[:unless].blank?)\n            end\n          end\n        end\n\n        # Accessor for whether this is a serial field (aka. primary key, identifier).\n        #\n        # @see RailsAdmin::AbstractModel.properties\n        register_instance_option :serial? do\n          properties&.serial?\n        end\n\n        register_instance_option :view_helper do\n          :text_field\n        end\n\n        register_instance_option :read_only? do\n          !editable?\n        end\n\n        # init status in the view\n        register_instance_option :active? do\n          false\n        end\n\n        register_instance_option :visible? do\n          returned = true\n          (RailsAdmin.config.default_hidden_fields || {}).each do |section, fields|\n            next unless self.section.is_a?(\"RailsAdmin::Config::Sections::#{section.to_s.camelize}\".constantize)\n\n            returned = false if fields.include?(name)\n          end\n          returned\n        end\n\n        # columns mapped (belongs_to, paperclip, etc.). First one is used for searching/sorting by default\n        register_instance_option :children_fields do\n          []\n        end\n\n        register_instance_option :eager_load do\n          false\n        end\n\n        register_deprecated_instance_option :eager_load?, :eager_load\n\n        def eager_load_values\n          case eager_load\n          when true\n            [name]\n          when false, nil\n            []\n          else\n            Array.wrap(eager_load)\n          end\n        end\n\n        register_instance_option :render do\n          bindings[:view].render partial: \"rails_admin/main/#{partial}\", locals: {field: self, form: bindings[:form]}\n        end\n\n        def editable?\n          !((@properties && @properties.read_only?) || (bindings[:object] && bindings[:object].readonly?))\n        end\n\n        # Is this an association\n        def association?\n          is_a?(RailsAdmin::Config::Fields::Association)\n        end\n\n        # Reader for validation errors of the bound object\n        def errors\n          ([name] + children_fields).uniq.collect do |column_name|\n            bindings[:object].errors[column_name]\n          end.uniq.flatten\n        end\n\n        # Reader whether field is optional.\n        #\n        # @see RailsAdmin::Config::Fields::Base.register_instance_option :required?\n        def optional?\n          !required?\n        end\n\n        # Inverse accessor whether this field is required.\n        #\n        # @see RailsAdmin::Config::Fields::Base.register_instance_option :required?\n        def optional(state = nil, &block)\n          if !state.nil? || block\n            required state.nil? ? proc { instance_eval(&block) == false } : state == false\n          else\n            optional?\n          end\n        end\n\n        # Writer to make field optional.\n        #\n        # @see RailsAdmin::Config::Fields::Base.optional\n        def optional=(state)\n          optional(state)\n        end\n\n        # Reader for field's type\n        def type\n          @type ||= self.class.name.to_s.demodulize.underscore.to_sym\n        end\n\n        # Reader for field's value\n        def value\n          bindings[:object].safe_send(name)\n        rescue NoMethodError => e\n          raise e.exception <<~ERROR\n            #{e.message}\n            If you want to use a RailsAdmin virtual field(= a field without corresponding instance method),\n            you should declare 'formatted_value' in the field definition.\n              field :#{name} do\n                formatted_value{ bindings[:object].call_some_method }\n              end\n          ERROR\n        end\n\n        # Reader for nested attributes\n        register_instance_option :nested_form do\n          false\n        end\n\n        # Allowed methods for the field in forms\n        register_instance_option :allowed_methods do\n          [method_name]\n        end\n\n        def generic_help\n          \"#{required? ? I18n.translate('admin.form.required') : I18n.translate('admin.form.optional')}. \"\n        end\n\n        def generic_field_help\n          model = abstract_model.model_name.underscore\n          model_lookup = :\"admin.help.#{model}.#{name}\"\n          translated = I18n.translate(model_lookup, help: generic_help, default: [generic_help])\n          (translated.is_a?(Hash) ? translated.to_a.first[1] : translated).html_safe\n        end\n\n        def parse_value(value)\n          value\n        end\n\n        def parse_input(_params)\n          # overridden\n        end\n\n        def inverse_of\n          nil\n        end\n\n        def method_name\n          name\n        end\n\n        def form_default_value\n          (default_value if bindings[:object].new_record? && value.nil?)\n        end\n\n        def form_value\n          form_default_value.nil? ? formatted_value : form_default_value\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/collection_association.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/association'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      class CollectionAssociation < Association\n        # orderable associated objects\n        register_instance_option :orderable do\n          false\n        end\n\n        register_instance_option :partial do\n          nested_form ? :form_nested_many : :form_filtering_multiselect\n        end\n\n        def collection(scope = nil)\n          if scope\n            super\n          elsif associated_collection_cache_all\n            selected = selected_ids\n            i = 0\n            super.sort_by { |a| [selected.index(a[1]) || selected.size, i += 1] }\n          else\n            value.map { |o| [o.send(associated_object_label_method), format_key(o.send(associated_primary_key))] }\n          end\n        end\n\n        def associated_prepopulate_params\n          {associated_model_config.abstract_model.param_key => {association.foreign_key => bindings[:object].try(:id)}}\n        end\n\n        def multiple?\n          true\n        end\n\n        def selected_ids\n          value.map { |s| format_key(s.send(associated_primary_key)).to_s }\n        end\n\n        def parse_input(params)\n          return unless associated_model_config.abstract_model.primary_key.is_a?(Array)\n\n          if nested_form\n            params[method_name].each_value do |value|\n              value[:id] = associated_model_config.abstract_model.parse_id(value[:id])\n            end\n          elsif params[method_name].is_a?(Array)\n            params[method_name] = params[method_name].map { |key| associated_model_config.abstract_model.parse_id(key) if key.present? }.compact\n            if params[method_name].empty?\n              # Workaround for Arel::Visitors::UnsupportedVisitError in #ids_writer, until https://github.com/rails/rails/pull/51116 is in place\n              params.delete(method_name)\n              params[name] = []\n            end\n          end\n        end\n\n        def form_default_value\n          (default_value if bindings[:object].new_record? && value.empty?)\n        end\n\n        def form_value\n          form_default_value.nil? ? selected_ids : form_default_value\n        end\n\n        def widget_options\n          {\n            xhr: !associated_collection_cache_all,\n            'edit-url': (inline_edit && bindings[:view].authorized?(:edit, associated_model_config.abstract_model) ? bindings[:view].edit_path(model_name: associated_model_config.abstract_model.to_param, id: '__ID__') : ''),\n            remote_source: bindings[:view].index_path(associated_model_config.abstract_model, source_object_id: abstract_model.format_id(bindings[:object].id), source_abstract_model: abstract_model.to_param, associated_collection: name, current_action: bindings[:view].current_action, compact: true),\n            scopeBy: dynamic_scope_relationships,\n            sortable: !!orderable,\n            removable: !!removable,\n            cacheAll: !!associated_collection_cache_all,\n            regional: {\n              add: ::I18n.t('admin.misc.add_new'),\n              chooseAll: ::I18n.t('admin.misc.chose_all'),\n              clearAll: ::I18n.t('admin.misc.clear_all'),\n              down: ::I18n.t('admin.misc.down'),\n              remove: ::I18n.t('admin.misc.remove'),\n              search: ::I18n.t('admin.misc.search'),\n              up: ::I18n.t('admin.misc.up'),\n            },\n          }\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/action_text.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types'\n\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  if defined?(::ActionText) && properties.try(:association?) && (match = /\\Arich_text_(.+)\\Z/.match properties.name) && properties.klass.to_s == 'ActionText::RichText'\n    field = RailsAdmin::Config::Fields::Types.load(:action_text).new(parent, match[1], properties)\n    fields << field\n    true\n  else\n    false\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/active_storage.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types'\nrequire 'rails_admin/config/fields/types/file_upload'\n\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  if defined?(::ActiveStorage) && properties.try(:association?) && (match = /\\A(.+)_attachments?\\Z/.match properties.name) && properties.klass.to_s == 'ActiveStorage::Attachment'\n    name = match[1]\n    field = RailsAdmin::Config::Fields::Types.load(\n      properties.type == :has_many ? :multiple_active_storage : :active_storage,\n    ).new(parent, name, properties)\n    fields << field\n    associations =\n      if properties.type == :has_many\n        [:\"#{name}_attachments\", :\"#{name}_blobs\"]\n      else\n        [:\"#{name}_attachment\", :\"#{name}_blob\"]\n      end\n    children_fields = associations.map do |child_name|\n      child_association = parent.abstract_model.associations.detect { |p| p.name.to_sym == child_name }\n      next unless child_association\n\n      child_field = fields.detect { |f| f.name == child_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_association, fields)\n      child_field.hide unless field == child_field\n      child_field.filterable(false) unless field == child_field\n      child_field.name\n    end.flatten.compact\n    field.children_fields(children_fields)\n    true\n  else\n    false\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/association.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types'\nrequire 'rails_admin/config/fields/types/belongs_to_association'\n\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  parent.abstract_model.associations.filter { |a| Array(a.foreign_key).include?(properties.name) && %i[belongs_to has_and_belongs_to_many].include?(a.type) }.each do |association|\n    field = RailsAdmin::Config::Fields::Types.load(association.field_type).new(parent, association.name, association)\n    fields << field\n\n    child_columns = []\n    possible_field_names = if association.polymorphic?\n                             %i[foreign_key foreign_type foreign_inverse_of]\n                           else\n                             [:foreign_key]\n                           end.flat_map { |k| Array(association.send(k)) }.compact\n\n    parent.abstract_model.properties.select { |p| possible_field_names.include? p.name }.each do |column|\n      child_field = fields.detect { |f| f.name.to_s == column.name.to_s }\n      child_field ||= RailsAdmin::Config::Fields.default_factory.call(parent, column, fields)\n      child_columns << child_field\n    end\n\n    child_columns.each do |child_column|\n      child_column.hide\n      child_column.filterable(false)\n    end\n\n    field.children_fields child_columns.collect(&:name)\n  end.any?\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/carrierwave.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types'\nrequire 'rails_admin/config/fields/types/file_upload'\n\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  model = parent.abstract_model.model\n  if defined?(::CarrierWave) && model.is_a?(CarrierWave::Mount) && model.uploaders.include?(attachment_name = properties.name.to_s.chomp('_file_name').to_sym)\n    columns = [model.uploader_options[attachment_name][:mount_on] || attachment_name, :\"#{attachment_name}_content_type\", :\"#{attachment_name}_file_size\"]\n    field = RailsAdmin::Config::Fields::Types.load(\n      %i[serialized json].include?(properties.type) ? :multiple_carrierwave : :carrierwave,\n    ).new(parent, attachment_name, properties)\n    fields << field\n    children_fields = []\n    columns.each do |children_column_name|\n      child_properties = parent.abstract_model.properties.detect { |p| p.name.to_s == children_column_name.to_s }\n      next unless child_properties\n\n      children_field = fields.detect { |f| f.name == children_column_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_properties, fields)\n      children_field.hide unless field == children_field\n      children_field.filterable(false) unless field == children_field\n      children_fields << children_field.name\n    end\n    field.children_fields(children_fields)\n    true\n  else\n    false\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/devise.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types'\nrequire 'rails_admin/config/fields/types/password'\n\n# Register a custom field factory for devise model\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  if properties.name == :encrypted_password\n    extensions = %i[password_salt reset_password_token remember_token]\n    fields << RailsAdmin::Config::Fields::Types.load(:password).new(parent, :password, properties)\n    fields << RailsAdmin::Config::Fields::Types.load(:password).new(parent, :password_confirmation, properties)\n    extensions.each do |ext|\n      properties = parent.abstract_model.properties.detect { |p| ext == p.name }\n      next unless properties\n\n      field = fields.detect { |f| f.name == ext }\n      unless field\n        RailsAdmin::Config::Fields.default_factory.call(parent, properties, fields)\n        field = fields.last\n      end\n      field.hide\n    end\n    true\n  else\n    false\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/dragonfly.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types'\nrequire 'rails_admin/config/fields/types/file_upload'\n\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  extensions = %i[name uid]\n  if (properties.name.to_s =~ /^(.+)_uid$/) && defined?(::Dragonfly) && parent.abstract_model.model.respond_to?(:dragonfly_attachment_classes) && parent.abstract_model.model.dragonfly_attachment_classes.collect(&:attribute).include?(attachment_name = Regexp.last_match[1].to_sym)\n    field = RailsAdmin::Config::Fields::Types.load(:dragonfly).new(parent, attachment_name, properties)\n    children_fields = []\n    extensions.each do |ext|\n      children_column_name = :\"#{attachment_name}_#{ext}\"\n      child_properties = parent.abstract_model.properties.detect { |p| p.name.to_s == children_column_name.to_s }\n      next unless child_properties\n\n      children_field = fields.detect { |f| f.name == children_column_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_properties, fields)\n      children_field.hide\n      children_field.filterable(false)\n      children_fields << children_field.name\n    end\n    field.children_fields(children_fields)\n    fields << field\n    true\n  else\n    false\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/enum.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types/enum'\nrequire 'rails_admin/config/fields/types/active_record_enum'\n\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  model = parent.abstract_model.model\n  method_name = \"#{properties.name}_enum\"\n\n  # NOTICE: _method_name could be `to_enum` and this method defined in Object.\n  if !Object.respond_to?(method_name) && \\\n     (model.respond_to?(method_name) || \\\n         model.method_defined?(method_name))\n    fields << RailsAdmin::Config::Fields::Types::Enum.new(parent, properties.name, properties)\n    true\n  elsif model.respond_to?(:defined_enums) && model.defined_enums[properties.name.to_s]\n    fields << RailsAdmin::Config::Fields::Types::ActiveRecordEnum.new(parent, properties.name, properties)\n    true\n  else\n    false\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/paperclip.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types'\nrequire 'rails_admin/config/fields/types/file_upload'\n\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  extensions = %i[file_name content_type file_size updated_at fingerprint]\n  model = parent.abstract_model.model\n  if (properties.name.to_s =~ /^(.+)_file_name$/) && defined?(::Paperclip) && model.try(:attachment_definitions) && model.attachment_definitions.key?(attachment_name = Regexp.last_match[1].to_sym)\n    field = RailsAdmin::Config::Fields::Types.load(:paperclip).new(parent, attachment_name, properties)\n    children_fields = []\n    extensions.each do |ext|\n      children_column_name = :\"#{attachment_name}_#{ext}\"\n      child_properties = parent.abstract_model.properties.detect { |p| p.name.to_s == children_column_name.to_s }\n      next unless child_properties\n\n      children_field = fields.detect { |f| f.name == children_column_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_properties, fields)\n      children_field.hide\n      children_field.filterable(false)\n      children_fields << children_field.name\n    end\n    field.children_fields(children_fields)\n    fields << field\n    true\n  else\n    false\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/password.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types/password'\n\n# Register a custom field factory for properties named as password. More property\n# names can be registered in RailsAdmin::Config::Fields::Password.column_names\n# array.\n#\n# @see RailsAdmin::Config::Fields::Types::Password.column_names\n# @see RailsAdmin::Config::Fields.register_factory\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  if [:password].include?(properties.name)\n    fields << RailsAdmin::Config::Fields::Types::Password.new(parent, properties.name, properties)\n    true\n  else\n    false\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/factories/shrine.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/types'\nrequire 'rails_admin/config/fields/types/file_upload'\n\nRailsAdmin::Config::Fields.register_factory do |parent, properties, fields|\n  next false unless defined?(::Shrine)\n\n  attachment_names = parent.abstract_model.model.ancestors.select { |m| m.is_a?(Shrine::Attachment) }.map { |a| a.instance_variable_get('@name') }\n  next false if attachment_names.blank?\n\n  attachment_name = attachment_names.detect { |a| a == properties.name.to_s.chomp('_data').to_sym }\n  next false unless attachment_name\n\n  field = RailsAdmin::Config::Fields::Types.load(:shrine).new(parent, attachment_name, properties)\n  fields << field\n\n  data_field_name = :\"#{attachment_name}_data\"\n  child_properties = parent.abstract_model.properties.detect { |p| p.name == data_field_name }\n  next true unless child_properties\n\n  children_field = fields.detect { |f| f.name == data_field_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_properties, fields)\n  children_field.hide unless field == children_field\n  children_field.filterable(false) unless field == children_field\n\n  field.children_fields([data_field_name])\n  true\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/group.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'active_support/core_ext/string/inflections'\nrequire 'rails_admin/config/proxyable'\nrequire 'rails_admin/config/configurable'\nrequire 'rails_admin/config/hideable'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      # A container for groups of fields in edit views\n      class Group\n        include RailsAdmin::Config::Proxyable\n        include RailsAdmin::Config::Configurable\n        include RailsAdmin::Config::Hideable\n\n        attr_reader :name, :abstract_model, :parent, :root\n        attr_accessor :section\n\n        def initialize(parent, name)\n          @parent = parent\n          @root = parent.root\n\n          @abstract_model = parent.abstract_model\n          @section = parent\n          @name = name.to_s.tr(' ', '_').downcase.to_sym\n        end\n\n        # Defines a configuration for a field by proxying parent's field method\n        # and setting the field's group as self\n        #\n        # @see RailsAdmin::Config::Fields.field\n        def field(name, type = nil, &block)\n          field = section.field(name, type, &block)\n          # Directly manipulate the variable instead of using the accessor\n          # as group probably is not yet registered to the parent object.\n          field.instance_variable_set('@group', self)\n          field\n        end\n\n        # Reader for fields attached to this group\n        def fields\n          section.fields.select { |f| f.group == self }\n        end\n\n        # Defines configuration for fields by their type\n        #\n        # @see RailsAdmin::Config::Fields.fields_of_type\n        def fields_of_type(type, &block)\n          selected = section.fields.select { |f| type == f.type }\n          selected.each { |f| f.instance_eval(&block) } if block\n          selected\n        end\n\n        # Reader for fields that are marked as visible\n        def visible_fields\n          section.with(bindings).visible_fields.select { |f| f.group == self }\n        end\n\n        # Should it open by default\n        register_instance_option :active? do\n          true\n        end\n\n        # Configurable group label which by default is group's name humanized.\n        register_instance_option :label do\n          (@label ||= {})[::I18n.locale] ||= (parent.fields.detect { |f| f.name == name }.try(:label) || name.to_s.humanize)\n        end\n\n        # Configurable help text\n        register_instance_option :help do\n          nil\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/singular_association.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/association'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      class SingularAssociation < Association\n        register_instance_option :filter_operators do\n          %w[_discard like not_like is starts_with ends_with] + (required? ? [] : %w[_separator _present _blank])\n        end\n\n        register_instance_option :formatted_value do\n          (o = value) && o.send(associated_model_config.object_label_method)\n        end\n\n        register_instance_option :partial do\n          nested_form ? :form_nested_one : :form_filtering_select\n        end\n\n        def collection(scope = nil)\n          if associated_collection_cache_all || scope\n            super\n          else\n            [[formatted_value, selected_id]]\n          end\n        end\n\n        def multiple?\n          false\n        end\n\n        def selected_id\n          raise NoMethodError # abstract\n        end\n\n        def parse_input(params)\n          return unless nested_form && params[method_name].try(:[], :id).present?\n\n          ids = associated_model_config.abstract_model.parse_id(params[method_name][:id])\n          ids = ids.to_composite_keys.to_s if ids.respond_to?(:to_composite_keys)\n          params[method_name][:id] = ids\n        end\n\n        def form_value\n          form_default_value.nil? ? selected_id : form_default_value\n        end\n\n        def widget_options\n          {\n            xhr: !associated_collection_cache_all,\n            remote_source: bindings[:view].index_path(associated_model_config.abstract_model, source_object_id: abstract_model.format_id(bindings[:object].id), source_abstract_model: abstract_model.to_param, associated_collection: name, current_action: bindings[:view].current_action, compact: true),\n            scopeBy: dynamic_scope_relationships,\n          }\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/action_text.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/text'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class ActionText < Text\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :version do\n            '1.3.1'\n          end\n\n          register_instance_option :css_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/trix/#{version}/trix.css\"\n          end\n\n          register_instance_option :js_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/trix/#{version}/trix.js\"\n          end\n\n          register_instance_option :warn_dynamic_load do\n            true\n          end\n\n          register_instance_option :partial do\n            :form_action_text\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/active_record_enum.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/enum'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class ActiveRecordEnum < Enum\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          def type\n            :enum\n          end\n\n          register_instance_option :enum do\n            abstract_model.model.defined_enums[name.to_s]\n          end\n\n          register_instance_option :pretty_value do\n            bindings[:object].send(name).presence || ' - '\n          end\n\n          register_instance_option :multiple? do\n            false\n          end\n\n          register_instance_option :queryable do\n            false\n          end\n\n          def parse_value(value)\n            return unless value.present?\n\n            abstract_model.model.attribute_types[name.to_s].serialize(value)\n          end\n\n          def parse_input(params)\n            value = params[name]\n            return unless value\n\n            params[name] = parse_input_value(value)\n          end\n\n          def form_value\n            enum[super] || super\n          end\n\n        private\n\n          def parse_input_value(value)\n            abstract_model.model.attribute_types[name.to_s].deserialize(value)\n          end\n\n          def type_cast_value(value)\n            abstract_model.model.column_types[name.to_s].type_cast_from_user(value)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/active_storage.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/file_upload'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class ActiveStorage < RailsAdmin::Config::Fields::Types::FileUpload\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :thumb_method do\n            {resize_to_limit: [100, 100]}\n          end\n\n          register_instance_option :delete_method do\n            \"remove_#{name}\" if bindings[:object].respond_to?(\"remove_#{name}\")\n          end\n\n          register_instance_option :image? do\n            value && (value.representable? || value.content_type.match?(/^image/))\n          end\n\n          register_instance_option :eager_load do\n            {\"#{name}_attachment\": :blob}\n          end\n\n          register_instance_option :direct? do\n            false\n          end\n\n          register_instance_option :html_attributes do\n            {\n              required: required? && !value.present?,\n            }.merge(\n              direct? && {data: {direct_upload_url: bindings[:view].main_app.rails_direct_uploads_url}} || {},\n            )\n          end\n\n          register_instance_option :searchable do\n            false\n          end\n\n          register_instance_option :sortable do\n            false\n          end\n\n          def resource_url(thumb = false)\n            return nil unless value\n\n            if thumb && value.representable?\n              thumb = thumb_method if thumb == true\n              representation = value.representation(thumb)\n              Rails.application.routes.url_helpers.rails_blob_representation_path(\n                representation.blob.signed_id, representation.variation.key, representation.blob.filename, only_path: true\n              )\n            else\n              Rails.application.routes.url_helpers.rails_blob_path(value, only_path: true)\n            end\n          end\n\n          def value\n            attachment = super\n            attachment if attachment&.attached?\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/all.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/action_text'\nrequire 'rails_admin/config/fields/types/active_record_enum'\nrequire 'rails_admin/config/fields/types/active_storage'\nrequire 'rails_admin/config/fields/types/belongs_to_association'\nrequire 'rails_admin/config/fields/types/boolean'\nrequire 'rails_admin/config/fields/types/bson_object_id'\nrequire 'rails_admin/config/fields/types/date'\nrequire 'rails_admin/config/fields/types/datetime'\nrequire 'rails_admin/config/fields/types/decimal'\nrequire 'rails_admin/config/fields/types/dragonfly'\nrequire 'rails_admin/config/fields/types/enum'\nrequire 'rails_admin/config/fields/types/file_upload'\nrequire 'rails_admin/config/fields/types/paperclip'\nrequire 'rails_admin/config/fields/types/carrierwave'\nrequire 'rails_admin/config/fields/types/multiple_file_upload'\nrequire 'rails_admin/config/fields/types/multiple_active_storage'\nrequire 'rails_admin/config/fields/types/multiple_carrierwave'\nrequire 'rails_admin/config/fields/types/float'\nrequire 'rails_admin/config/fields/types/has_and_belongs_to_many_association'\nrequire 'rails_admin/config/fields/types/has_many_association'\nrequire 'rails_admin/config/fields/types/has_one_association'\nrequire 'rails_admin/config/fields/types/integer'\nrequire 'rails_admin/config/fields/types/password'\nrequire 'rails_admin/config/fields/types/polymorphic_association'\nrequire 'rails_admin/config/fields/types/string'\nrequire 'rails_admin/config/fields/types/hidden'\nrequire 'rails_admin/config/fields/types/text'\nrequire 'rails_admin/config/fields/types/serialized'\nrequire 'rails_admin/config/fields/types/shrine'\nrequire 'rails_admin/config/fields/types/time'\nrequire 'rails_admin/config/fields/types/timestamp'\nrequire 'rails_admin/config/fields/types/color'\nrequire 'rails_admin/config/fields/types/simple_mde'\nrequire 'rails_admin/config/fields/types/ck_editor'\nrequire 'rails_admin/config/fields/types/code_mirror'\nrequire 'rails_admin/config/fields/types/wysihtml5'\nrequire 'rails_admin/config/fields/types/froala'\nrequire 'rails_admin/config/fields/types/json'\nrequire 'rails_admin/config/fields/types/inet'\nrequire 'rails_admin/config/fields/types/uuid'\nrequire 'rails_admin/config/fields/types/citext'\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/belongs_to_association.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/singular_association'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class BelongsToAssociation < RailsAdmin::Config::Fields::SingularAssociation\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :sortable do\n            @sortable ||= abstract_model.adapter_supports_joins? && associated_model_config.abstract_model.properties.collect(&:name).include?(associated_model_config.object_label_method) ? associated_model_config.object_label_method : {abstract_model.table_name => method_name}\n          end\n\n          register_instance_option :searchable do\n            @searchable ||= associated_model_config.abstract_model.properties.collect(&:name).include?(associated_model_config.object_label_method) ? [associated_model_config.object_label_method, {abstract_model.model => method_name}] : {abstract_model.model => method_name}\n          end\n\n          register_instance_option :eager_load do\n            true\n          end\n\n          register_instance_option :allowed_methods do\n            nested_form ? [method_name] : Array(association.foreign_key)\n          end\n\n          def selected_id\n            if association.foreign_key.is_a?(Array)\n              format_key(association.foreign_key.map { |attribute| bindings[:object].safe_send(attribute) })\n            else\n              bindings[:object].safe_send(association.key_accessor)\n            end\n          end\n\n          def parse_input(params)\n            return super if nested_form\n            return unless params[method_name].present? && association.foreign_key.is_a?(Array)\n\n            association.foreign_key.zip(RailsAdmin.config.composite_keys_serializer.deserialize(params.delete(method_name))).each do |key, value|\n              params[key] = value\n            end\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/boolean.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Boolean < RailsAdmin::Config::Fields::Base\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :labels do\n            {\n              true => %(<span class=\"fas fa-check\"></span>),\n              false => %(<span class=\"fas fa-times\"></span>),\n              nil => %(<span class=\"fas fa-minus\"></span>),\n            }\n          end\n\n          register_instance_option :css_classes do\n            {\n              true => 'success',\n              false => 'danger',\n              nil => 'default',\n            }\n          end\n\n          register_instance_option :filter_operators do\n            %w[_discard true false] + (required? ? [] : %w[_separator _present _blank])\n          end\n\n          register_instance_option :nullable? do\n            properties&.nullable?\n          end\n\n          register_instance_option :view_helper do\n            :check_box\n          end\n\n          register_instance_option :pretty_value do\n            %(<span class=\"badge bg-#{css_classes[form_value]}\">#{labels[form_value]}</span>).html_safe\n          end\n\n          register_instance_option :export_value do\n            value.inspect\n          end\n\n          register_instance_option :partial do\n            :form_boolean\n          end\n\n          def form_value\n            case value\n            when true, false\n              value\n            end\n          end\n\n          # Accessor for field's help text displayed below input field.\n          def generic_help\n            ''\n          end\n\n          def parse_input(params)\n            params[name] = params[name].presence if params.key?(name)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/bson_object_id.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/string'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class BsonObjectId < RailsAdmin::Config::Fields::Types::String\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :label do\n            label = ((@label ||= {})[::I18n.locale] ||= abstract_model.model.human_attribute_name name)\n            label = 'Id' if label == ''\n            label\n          end\n\n          def generic_help\n            'BSON::ObjectId'\n          end\n\n          register_instance_option :read_only do\n            true\n          end\n\n          register_instance_option :sort_reverse? do\n            serial?\n          end\n\n          def parse_value(value)\n            value.present? ? abstract_model.parse_object_id(value) : nil\n          end\n\n          def parse_input(params)\n            params[name] = parse_value(params[name]) if params[name].is_a?(::String)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/carrierwave.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/base'\nrequire 'rails_admin/config/fields/types/file_upload'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Carrierwave < RailsAdmin::Config::Fields::Types::FileUpload\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :thumb_method do\n            @thumb_method ||= ((versions = bindings[:object].send(name).versions.keys).detect { |k| k.in?([:thumb, :thumbnail, 'thumb', 'thumbnail']) } || versions.first.to_s)\n          end\n\n          register_instance_option :delete_method do\n            \"remove_#{name}\"\n          end\n\n          register_instance_option :cache_method do\n            \"#{name}_cache\"\n          end\n\n          def resource_url(thumb = false)\n            return nil unless (uploader = bindings[:object].send(name)).present?\n\n            thumb.present? ? uploader.send(thumb).url : uploader.url\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/citext.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/text'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Citext < Text\n          RailsAdmin::Config::Fields::Types.register(:citext, self)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/ck_editor.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/text'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class CKEditor < Text\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :version do\n            '4.11.4'\n          end\n\n          # If you want to have a different toolbar configuration for CKEditor\n          # create your own custom config.js and override this configuration\n          register_instance_option :config_js do\n            nil\n          end\n\n          # Use this if you want to point to a cloud instances of CKeditor\n          register_instance_option :location do\n            nil\n          end\n\n          # Use this if you want to point to a cloud instances of the base CKeditor\n          register_instance_option :base_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/ckeditor/#{version}/\"\n          end\n\n          register_instance_option :partial do\n            :form_ck_editor\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/code_mirror.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/text'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class CodeMirror < Text\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          # Pass the theme and mode for Codemirror\n          register_instance_option :config do\n            {\n              mode: 'css',\n              theme: 'night',\n            }\n          end\n\n          register_instance_option :version do\n            '5.46.0'\n          end\n\n          # Pass the location of the theme and mode for Codemirror\n          register_instance_option :assets do\n            {\n              mode: \"https://cdnjs.cloudflare.com/ajax/libs/codemirror/#{version}/mode/css/css.min.js\",\n              theme: \"https://cdnjs.cloudflare.com/ajax/libs/codemirror/#{version}/theme/night.min.css\",\n            }\n          end\n\n          register_instance_option :js_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/codemirror/#{version}/codemirror.min.js\"\n          end\n\n          register_instance_option :css_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/codemirror/#{version}/codemirror.min.css\"\n          end\n\n          register_instance_option :partial do\n            :form_code_mirror\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/color.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/string_like'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Color < StringLike\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :pretty_value do\n            bindings[:view].content_tag :strong, (value.presence || ' - '), style: \"color: #{color}\"\n          end\n\n          register_instance_option :partial do\n            :form_colorpicker\n          end\n\n          register_instance_option :view_helper do\n            :color_field\n          end\n\n          register_instance_option :color do\n            if value.present?\n              if /^[0-9a-fA-F]{3,6}$/.match?(value)\n                \"##{value}\"\n              else\n                value\n              end\n            else\n              'white'\n            end\n          end\n\n          register_instance_option :export_value do\n            formatted_value\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/date.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/datetime'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Date < RailsAdmin::Config::Fields::Types::Datetime\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          def parse_value(value)\n            ::Date.parse(value) if value.present?\n          end\n\n          register_instance_option :date_format do\n            :long\n          end\n\n          register_instance_option :datepicker_options do\n            {\n              allowInput: true,\n              altFormat: flatpickr_format,\n            }\n          end\n\n          register_instance_option :i18n_scope do\n            %i[date formats]\n          end\n\n          register_instance_option :html_attributes do\n            {\n              required: required?,\n              size: 18,\n            }\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/datetime.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/base'\nrequire 'rails_admin/support/datetime'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Datetime < RailsAdmin::Config::Fields::Base\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          def parse_value(value)\n            ::Time.zone.parse(value)\n          end\n\n          def parse_input(params)\n            params[name] = parse_value(params[name]) if params[name]\n          end\n\n          register_instance_option :filter_operators do\n            %w[default between today yesterday this_week last_week] + (required? ? [] : %w[_separator _not_null _null])\n          end\n\n          def filter_options\n            super.merge(\n              datetimepicker_options: datepicker_options,\n            )\n          end\n\n          register_instance_option :date_format do\n            :long\n          end\n\n          register_instance_option :i18n_scope do\n            %i[time formats]\n          end\n\n          register_instance_option :strftime_format do\n            ::I18n.t(date_format, scope: i18n_scope, raise: true)\n          rescue ::I18n::ArgumentError\n            '%B %d, %Y %H:%M'\n          end\n\n          register_instance_option :flatpickr_format do\n            RailsAdmin::Support::Datetime.to_flatpickr_format(strftime_format)\n          end\n\n          register_instance_option :datepicker_options do\n            {\n              allowInput: true,\n              enableTime: true,\n              altFormat: flatpickr_format,\n            }\n          end\n\n          register_instance_option :html_attributes do\n            {\n              required: required?,\n              size: 22,\n            }\n          end\n\n          register_instance_option :sort_reverse? do\n            true\n          end\n\n          register_instance_option :queryable? do\n            false\n          end\n\n          register_instance_option :formatted_value do\n            time = (value || default_value)\n            if time\n              ::I18n.l(time, format: strftime_format)\n            else\n              ''.html_safe\n            end\n          end\n\n          register_instance_option :partial do\n            :form_datetime\n          end\n\n          register_deprecated_instance_option :momentjs_format do\n            ActiveSupport::Deprecation.warn('The momentjs_format configuration option is deprecated, please use flatpickr_format with corresponding values here: https://flatpickr.js.org/formatting/')\n          end\n\n          def form_value\n            value&.in_time_zone&.strftime('%FT%T') || form_default_value\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/decimal.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/numeric'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Decimal < RailsAdmin::Config::Fields::Types::Numeric\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :html_attributes do\n            {\n              required: required?,\n              step: 'any',\n            }\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/dragonfly.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/base'\nrequire 'rails_admin/config/fields/types/file_upload'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        # Field type that supports Paperclip file uploads\n        class Dragonfly < RailsAdmin::Config::Fields::Types::FileUpload\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :image? do\n            if abstract_model.model.new.respond_to?(\"#{name}_name\")\n              mime_type = Mime::Type.lookup_by_extension(bindings[:object].send(\"#{name}_name\").to_s.split('.').last)\n              mime_type.to_s.match?(/^image/)\n            else\n              true # Dragonfly really is image oriented\n            end\n          end\n\n          register_instance_option :delete_method do\n            \"remove_#{name}\"\n          end\n\n          register_instance_option :cache_method do\n            \"retained_#{name}\"\n          end\n\n          register_instance_option :thumb_method do\n            '100x100>'\n          end\n\n          def resource_url(thumb = false)\n            return nil unless (v = value)\n\n            thumb ? v.thumb(thumb).try(:url) : v.url\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/enum.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/string'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Enum < RailsAdmin::Config::Fields::Base\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :filter_operators do\n            %w[_discard] +\n              enum.map do |label, value|\n                {label: label, value: value || label}\n              end + (required? ? [] : %w[_separator _present _blank])\n          end\n\n          register_instance_option :partial do\n            :form_enumeration\n          end\n\n          register_instance_option :enum_method do\n            @enum_method ||= bindings[:object].class.respond_to?(\"#{name}_enum\") || (bindings[:object] || abstract_model.model.new).respond_to?(\"#{name}_enum\") ? \"#{name}_enum\" : name\n          end\n\n          register_instance_option :enum do\n            if abstract_model.model.respond_to?(enum_method)\n              abstract_model.model.send(enum_method)\n            else\n              (bindings[:object] || abstract_model.model.new).send(enum_method)\n            end\n          end\n\n          register_instance_option :pretty_value do\n            if enum.is_a?(::Hash)\n              enum.select { |_k, v| v.to_s == value.to_s }.keys.first.to_s.presence || value.presence || ' - '\n            elsif enum.is_a?(::Array) && enum.first.is_a?(::Array)\n              enum.detect { |e| e[1].to_s == value.to_s }.try(:first).to_s.presence || value.presence || ' - '\n            else\n              value.presence || ' - '\n            end\n          end\n\n          register_instance_option :multiple? do\n            properties && [:serialized].include?(properties.type)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/file_upload.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/string'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class FileUpload < RailsAdmin::Config::Fields::Base\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :partial do\n            :form_file_upload\n          end\n\n          register_instance_option :thumb_method do\n            nil\n          end\n\n          register_instance_option :delete_method do\n            nil\n          end\n\n          register_instance_option :cache_method do\n            nil\n          end\n\n          register_instance_option :cache_value do\n            bindings[:object].public_send(cache_method) if cache_method\n          end\n\n          register_instance_option :export_value do\n            resource_url.to_s\n          end\n\n          register_instance_option :link_name do\n            value\n          end\n\n          register_instance_option :pretty_value do\n            if value.presence\n              v = bindings[:view]\n              url = resource_url\n              if image\n                thumb_url = resource_url(thumb_method)\n                image_html = v.image_tag(thumb_url, class: 'img-thumbnail')\n                url == thumb_url ? image_html : v.link_to(image_html, url, target: '_blank', rel: 'noopener noreferrer')\n              else\n                v.link_to(link_name, url, target: '_blank', rel: 'noopener noreferrer')\n              end\n            end\n          end\n\n          register_instance_option :image? do\n            mime_type = Mime::Type.lookup_by_extension(extension)\n            mime_type.to_s.match?(/^image/)\n          end\n\n          register_instance_option :allowed_methods do\n            [method_name, delete_method, cache_method].compact\n          end\n\n          register_instance_option :html_attributes do\n            {\n              required: required? && !value.present?,\n            }\n          end\n\n          def extension\n            URI.parse(resource_url).path.split('.').last\n          rescue URI::InvalidURIError\n            nil\n          end\n\n          # virtual class\n          def resource_url\n            raise 'not implemented'\n          end\n\n          def virtual?\n            true\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/float.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/numeric'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Float < RailsAdmin::Config::Fields::Types::Numeric\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :html_attributes do\n            {\n              required: required?,\n              step: 'any',\n            }\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/froala.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/text'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Froala < Text\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          # See https://www.froala.com/wysiwyg-editor/docs/options\n          register_instance_option :config_options do\n            nil\n          end\n\n          register_instance_option :version do\n            '2.9.5'\n          end\n\n          register_instance_option :css_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/froala-editor/#{version}/css/froala_editor.min.css\"\n          end\n\n          register_instance_option :js_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/froala-editor/#{version}/js/froala_editor.min.js\"\n          end\n\n          register_instance_option :partial do\n            :form_froala\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/has_and_belongs_to_many_association.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/collection_association'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class HasAndBelongsToManyAssociation < RailsAdmin::Config::Fields::CollectionAssociation\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/has_many_association.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/collection_association'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class HasManyAssociation < RailsAdmin::Config::Fields::CollectionAssociation\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/has_one_association.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/singular_association'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class HasOneAssociation < RailsAdmin::Config::Fields::SingularAssociation\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :allowed_methods do\n            nested_form ? [method_name] : [name]\n          end\n\n          def associated_prepopulate_params\n            {associated_model_config.abstract_model.param_key => {association.foreign_key => bindings[:object].try(:id)}}\n          end\n\n          def parse_input(params)\n            return super if nested_form\n\n            id = params.delete(method_name)\n            params[name] = associated_model_config.abstract_model.get(id) if id\n          end\n\n          def selected_id\n            format_key(value.try(:id)).try(:to_s)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/hidden.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/string_like'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Hidden < StringLike\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :view_helper do\n            :hidden_field\n          end\n\n          register_instance_option :label do\n            false\n          end\n\n          register_instance_option :help do\n            false\n          end\n\n          def generic_help\n            false\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/inet.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/base'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Inet < RailsAdmin::Config::Fields::Base\n          RailsAdmin::Config::Fields::Types.register(self)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/integer.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/numeric'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Integer < RailsAdmin::Config::Fields::Types::Numeric\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :sort_reverse? do\n            serial?\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/json.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/text'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Json < RailsAdmin::Config::Fields::Types::Text\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n          RailsAdmin::Config::Fields::Types.register(:jsonb, self)\n\n          register_instance_option :formatted_value do\n            value ? JSON.pretty_generate(value) : nil\n          end\n\n          register_instance_option :pretty_value do\n            bindings[:view].content_tag(:pre) { formatted_value }.html_safe\n          end\n\n          register_instance_option :export_value do\n            formatted_value\n          end\n\n          def parse_value(value)\n            value.present? ? JSON.parse(value) : nil\n          end\n\n          def parse_input(params)\n            params[name] = parse_value(params[name]) if params[name].is_a?(::String)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/multiple_active_storage.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/multiple_file_upload'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class MultipleActiveStorage < RailsAdmin::Config::Fields::Types::MultipleFileUpload\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          class ActiveStorageAttachment < RailsAdmin::Config::Fields::Types::MultipleFileUpload::AbstractAttachment\n            register_instance_option :thumb_method do\n              {resize_to_limit: [100, 100]}\n            end\n\n            register_instance_option :keep_value do\n              value.signed_id\n            end\n\n            register_instance_option :delete_value do\n              value.id\n            end\n\n            register_instance_option :image? do\n              value && (value.representable? || value.content_type.match?(/^image/))\n            end\n\n            def resource_url(thumb = false)\n              return nil unless value\n\n              if thumb && value.representable?\n                representation = value.representation(thumb_method)\n                Rails.application.routes.url_helpers.rails_blob_representation_path(\n                  representation.blob.signed_id, representation.variation.key, representation.blob.filename, only_path: true\n                )\n              else\n                Rails.application.routes.url_helpers.rails_blob_path(value, only_path: true)\n              end\n            end\n          end\n\n          register_instance_option :attachment_class do\n            ActiveStorageAttachment\n          end\n\n          register_instance_option :keep_method do\n            method_name if ::ActiveStorage.gem_version >= Gem::Version.new('7.1') || ::ActiveStorage.replace_on_assign_to_many\n          end\n\n          register_instance_option :delete_method do\n            \"remove_#{name}\" if bindings[:object].respond_to?(\"remove_#{name}\")\n          end\n\n          register_instance_option :eager_load do\n            {\"#{name}_attachments\": :blob}\n          end\n\n          register_instance_option :direct? do\n            false\n          end\n\n          register_instance_option :html_attributes do\n            {\n              required: required? && !value.present?,\n            }.merge(\n              direct? && {data: {direct_upload_url: bindings[:view].main_app.rails_direct_uploads_url}} || {},\n            )\n          end\n\n          register_instance_option :searchable do\n            false\n          end\n\n          register_instance_option :sortable do\n            false\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/multiple_carrierwave.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/multiple_file_upload'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class MultipleCarrierwave < RailsAdmin::Config::Fields::Types::MultipleFileUpload\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          class CarrierwaveAttachment < RailsAdmin::Config::Fields::Types::MultipleFileUpload::AbstractAttachment\n            register_instance_option :thumb_method do\n              @thumb_method ||= ((versions = value.versions.keys).detect { |k| k.in?([:thumb, :thumbnail, 'thumb', 'thumbnail']) } || versions.first.to_s)\n            end\n\n            register_instance_option :keep_value do\n              value.cache_name || value.identifier\n            end\n\n            register_instance_option :delete_value do\n              value.file.filename\n            end\n\n            def resource_url(thumb = false)\n              return nil unless value\n\n              thumb.present? ? value.send(thumb).url : value.url\n            end\n          end\n\n          register_instance_option :attachment_class do\n            CarrierwaveAttachment\n          end\n\n          register_instance_option :cache_method do\n            \"#{name}_cache\" unless ::CarrierWave::VERSION >= '2'\n          end\n\n          register_instance_option :keep_method do\n            name if ::CarrierWave::VERSION >= '2'\n          end\n\n          register_instance_option :reorderable? do\n            ::CarrierWave::VERSION >= '2'\n          end\n\n          register_instance_option :delete_method do\n            \"delete_#{name}\" if bindings[:object].respond_to?(\"delete_#{name}\")\n          end\n\n          def value\n            bindings[:object].send(name)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/multiple_file_upload.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class MultipleFileUpload < RailsAdmin::Config::Fields::Base\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          class AbstractAttachment\n            include RailsAdmin::Config::Proxyable\n            include RailsAdmin::Config::Configurable\n\n            attr_reader :value\n\n            def initialize(value)\n              @value = value\n            end\n\n            register_instance_option :thumb_method do\n              nil\n            end\n\n            register_instance_option :keep_value do\n              nil\n            end\n\n            register_instance_option :delete_value do\n              nil\n            end\n\n            register_deprecated_instance_option :delete_key, :delete_value\n\n            register_instance_option :pretty_value do\n              if value.presence\n                v = bindings[:view]\n                url = resource_url\n                if image\n                  thumb_url = resource_url(thumb_method)\n                  image_html = v.image_tag(thumb_url, class: 'img-thumbnail')\n                  url == thumb_url ? image_html : v.link_to(image_html, url, target: '_blank', rel: 'noopener noreferrer')\n                else\n                  display_value = value.respond_to?(:filename) ? value.filename : value\n                  v.link_to(display_value, url, target: '_blank', rel: 'noopener noreferrer')\n                end\n              end\n            end\n\n            register_instance_option :image? do\n              mime_type = Mime::Type.lookup_by_extension(extension)\n              mime_type.to_s.match?(/^image/)\n            end\n\n            def resource_url(_thumb = false)\n              raise 'not implemented'\n            end\n\n            def extension\n              URI.parse(resource_url).path.split('.').last\n            rescue URI::InvalidURIError\n              nil\n            end\n          end\n\n          def initialize(*args)\n            super\n            @attachment_configurations = []\n          end\n\n          register_instance_option :attachment_class do\n            AbstractAttachment\n          end\n\n          register_instance_option :partial do\n            :form_multiple_file_upload\n          end\n\n          register_instance_option :cache_method do\n            nil\n          end\n\n          register_instance_option :delete_method do\n            nil\n          end\n\n          register_instance_option :keep_method do\n            nil\n          end\n\n          register_instance_option :reorderable? do\n            false\n          end\n\n          register_instance_option :export_value do\n            attachments.map(&:resource_url).map(&:to_s).join(',')\n          end\n\n          register_instance_option :pretty_value do\n            bindings[:view].safe_join attachments.map(&:pretty_value), ' '\n          end\n\n          register_instance_option :allowed_methods do\n            [method_name, cache_method, delete_method].compact\n          end\n\n          register_instance_option :html_attributes do\n            {\n              required: required? && !value.present?,\n            }\n          end\n\n          def attachment(&block)\n            @attachment_configurations << block\n          end\n\n          def attachments\n            Array(value).map do |attached|\n              attachment = attachment_class.new(attached)\n              @attachment_configurations.each do |config|\n                attachment.instance_eval(&config)\n              end\n              attachment.with(bindings)\n            end\n          end\n\n          # virtual class\n          def virtual?\n            true\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/numeric.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/base'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Numeric < RailsAdmin::Config::Fields::Base\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :filter_operators do\n            %w[default between] + (required? ? [] : %w[_separator _not_null _null])\n          end\n\n          register_instance_option :view_helper do\n            :number_field\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/paperclip.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/base'\nrequire 'rails_admin/config/fields/types/file_upload'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        # Field type that supports Paperclip file uploads\n        class Paperclip < RailsAdmin::Config::Fields::Types::FileUpload\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :delete_method do\n            \"delete_#{name}\" if bindings[:object].respond_to?(\"delete_#{name}\")\n          end\n\n          register_instance_option :thumb_method do\n            @styles ||= bindings[:object].send(name).styles.collect(&:first)\n            @thumb_method ||= @styles.detect { |s| [:thumb, 'thumb', :thumbnail, 'thumbnail'].include?(s) } || @styles.first || :original\n          end\n\n          def resource_url(thumb = false)\n            value.try(:url, (thumb || :original))\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/password.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/string'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Password < RailsAdmin::Config::Fields::Types::String\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :view_helper do\n            :password_field\n          end\n\n          def parse_input(params)\n            if params[name].present?\n              params[name] = params[name]\n            else\n              params.delete(name)\n            end\n          end\n\n          register_instance_option :formatted_value do\n            ''.html_safe\n          end\n\n          # Password field's value does not need to be read\n          def value\n            ''\n          end\n\n          register_instance_option :visible do\n            section.is_a?(RailsAdmin::Config::Sections::Edit)\n          end\n\n          register_instance_option :pretty_value do\n            '*****'\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/polymorphic_association.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/belongs_to_association'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class PolymorphicAssociation < RailsAdmin::Config::Fields::Types::BelongsToAssociation\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :partial do\n            :form_polymorphic_association\n          end\n\n          # Accessor whether association is visible or not. By default\n          # association checks that any of the child models are included in\n          # configuration.\n          register_instance_option :visible? do\n            associated_model_config.any?\n          end\n\n          register_instance_option :formatted_value do\n            (o = value) && o.send(RailsAdmin.config(o).object_label_method)\n          end\n\n          register_instance_option :sortable do\n            false\n          end\n\n          register_instance_option :searchable do\n            false\n          end\n\n          # TODO: not supported yet\n          register_instance_option :associated_collection_cache_all do\n            false\n          end\n\n          # TODO: not supported yet\n          register_instance_option :associated_collection_scope do\n            nil\n          end\n\n          register_instance_option :allowed_methods do\n            [children_fields]\n          end\n\n          register_instance_option :eager_load do\n            false\n          end\n\n          def associated_model_config\n            @associated_model_config ||= association.klass.collect { |type| RailsAdmin.config(type) }.reject(&:excluded?)\n          end\n\n          def collection(_scope = nil)\n            if value\n              [[formatted_value, selected_id]]\n            else\n              [[]]\n            end\n          end\n\n          def type_column\n            association.foreign_type.to_s\n          end\n\n          def type_collection\n            associated_model_config.collect do |config|\n              [config.label, config.abstract_model.model.name]\n            end\n          end\n\n          def type_urls\n            types = associated_model_config.collect do |config|\n              [config.abstract_model.model.name, config.abstract_model.to_param]\n            end\n            ::Hash[*types.collect { |v| [v[0], bindings[:view].index_path(v[1])] }.flatten]\n          end\n\n          # Reader for field's value\n          def value\n            bindings[:object].send(association.name)\n          end\n\n          def widget_options_for_types\n            type_collection.inject({}) do |options, model|\n              options.merge(\n                model.second.downcase.gsub('::', '-') => {\n                  xhr: true,\n                  remote_source: bindings[:view].index_path(model.second.underscore, source_object_id: bindings[:object].id, source_abstract_model: abstract_model.to_param, current_action: bindings[:view].current_action, compact: true),\n                  float_left: false,\n                },\n              )\n            end\n          end\n\n          def widget_options\n            widget_options_for_types[selected_type.try(:downcase)] || {float_left: false}\n          end\n\n          def selected_type\n            bindings[:object].send(type_column)\n          end\n\n          def parse_input(params)\n            if (type_value = params[association.foreign_type.to_sym]).present?\n              config = associated_model_config.find { |c| type_value == c.abstract_model.model.name }\n              params[association.foreign_type.to_sym] = config.abstract_model.base_class.name if config\n            end\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/serialized.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/text'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Serialized < RailsAdmin::Config::Fields::Types::Text\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :formatted_value do\n            RailsAdmin.yaml_dump(value) unless value.nil?\n          end\n\n          def parse_value(value)\n            value.present? ? (RailsAdmin.yaml_load(value) || nil) : nil\n          end\n\n          def parse_input(params)\n            params[name] = parse_value(params[name]) if params[name].is_a?(::String)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/shrine.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/file_upload'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Shrine < RailsAdmin::Config::Fields::Types::FileUpload\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :thumb_method do\n            unless defined? @thumb_method\n              @thumb_method = begin\n                next nil unless bindings[:object].respond_to?(\"#{name}_derivatives\")\n\n                derivatives = bindings[:object].public_send(\"#{name}_derivatives\")\n\n                if derivatives.key?(:thumb)\n                  :thumb\n                elsif derivatives.key?(:thumbnail)\n                  :thumbnail\n                else\n                  derivatives.keys.first\n                end\n              end\n            end\n            @thumb_method\n          end\n\n          register_instance_option :delete_method do\n            \"remove_#{name}\" if bindings[:object].respond_to?(\"remove_#{name}\")\n          end\n\n          register_instance_option :cache_method do\n            name if bindings[:object].try(\"cached_#{name}_data\")\n          end\n\n          register_instance_option :cache_value do\n            bindings[:object].try(\"cached_#{name}_data\")\n          end\n\n          register_instance_option :link_name do\n            value.original_filename\n          end\n\n          def resource_url(thumb = nil)\n            return nil unless value\n\n            thumb && bindings[:object].public_send(:\"#{name}\", thumb).try(:url) || value.url\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/simple_mde.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/text'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class SimpleMDE < Text\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          # If you want to have a different SimpleMDE config for each instance\n          # you can override this option with these values: https://github.com/sparksuite/simplemde-markdown-editor#configuration\n          register_instance_option :instance_config do\n            nil\n          end\n\n          register_instance_option :version do\n            '1.11.2'\n          end\n\n          register_instance_option :js_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/simplemde/#{version}/simplemde.min.js\"\n          end\n\n          register_instance_option :css_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/simplemde/#{version}/simplemde.min.css\"\n          end\n\n          register_instance_option :partial do\n            :form_simple_mde\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/string.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/string_like'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class String < StringLike\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          def input_size\n            [50, length.to_i].reject(&:zero?).min\n          end\n\n          register_instance_option :html_attributes do\n            {\n              required: required?,\n              maxlength: length,\n              size: input_size,\n            }\n          end\n\n          def generic_help\n            text = \"#{required? ? I18n.translate('admin.form.required') : I18n.translate('admin.form.optional')}. \"\n            if valid_length.present? && valid_length[:is].present?\n              text += \"#{I18n.translate('admin.form.char_length_of').capitalize} #{valid_length[:is]}.\"\n            else\n              max_length = [length, valid_length[:maximum] || nil].compact.min\n              min_length = [0, valid_length[:minimum] || nil].compact.max\n              if max_length\n                text +=\n                  if min_length == 0\n                    \"#{I18n.translate('admin.form.char_length_up_to').capitalize} #{max_length}.\"\n                  else\n                    \"#{I18n.translate('admin.form.char_length_of').capitalize} #{min_length}-#{max_length}.\"\n                  end\n              end\n            end\n            text\n          end\n\n          register_instance_option :partial do\n            :form_field\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/string_like.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/base'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class StringLike < RailsAdmin::Config::Fields::Base\n          register_instance_option :filter_operators do\n            %w[_discard like not_like is starts_with ends_with] + (required? ? [] : %w[_separator _present _blank])\n          end\n\n          register_instance_option :treat_empty_as_nil? do\n            properties.try(:nullable?)\n          end\n\n          def parse_input(params)\n            params[name] = params[name].presence if params.key?(name) && treat_empty_as_nil?\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/text.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/string_like'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Text < StringLike\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          register_instance_option :html_attributes do\n            {\n              required: required?,\n              cols: '48',\n              rows: '3',\n            }\n          end\n\n          register_instance_option :partial do\n            :form_text\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/time.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/datetime'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Time < RailsAdmin::Config::Fields::Types::Datetime\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          def parse_value(value)\n            abstract_model.model.type_for_attribute(name.to_s).serialize(super)&.change(year: 2000, month: 1, day: 1)\n          end\n\n          register_instance_option :filter_operators do\n            %w[default between] + (required? ? [] : %w[_separator _not_null _null])\n          end\n\n          register_instance_option :datepicker_options do\n            {\n              allowInput: true,\n              altFormat: flatpickr_format,\n              enableTime: true,\n              noCalendar: true,\n            }\n          end\n\n          register_instance_option :strftime_format do\n            '%H:%M'\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/timestamp.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/datetime'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Timestamp < RailsAdmin::Config::Fields::Types::Datetime\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/uuid.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/string'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Uuid < RailsAdmin::Config::Fields::Types::String\n          RailsAdmin::Config::Fields::Types.register(self)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types/wysihtml5.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/types/text'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        class Wysihtml5 < Text\n          # Register field type for the type loader\n          RailsAdmin::Config::Fields::Types.register(self)\n\n          # If you want to have a different toolbar configuration for wysihtml5\n          # you can use a Ruby hash to configure these options:\n          # https://github.com/bootstrap-wysiwyg/bootstrap3-wysiwyg\n          register_instance_option :config_options do\n            {\n              toolbar: {\n                fa: true,\n              },\n            }\n          end\n\n          register_instance_option :version do\n            '0.3.3'\n          end\n\n          register_instance_option :css_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/bootstrap3-wysiwyg/#{version}/bootstrap3-wysihtml5.min.css\"\n          end\n\n          register_instance_option :js_location do\n            \"https://cdnjs.cloudflare.com/ajax/libs/bootstrap3-wysiwyg/#{version}/bootstrap3-wysihtml5.all.min.js\"\n          end\n\n          register_instance_option :partial do\n            :form_wysihtml5\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields/types.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'active_support/core_ext/string/inflections'\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/fields/association'\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      module Types\n        @@registry = {}\n\n        def self.load(type)\n          @@registry.fetch(type.to_sym) { raise \"Unsupported field datatype: #{type}\" }\n        end\n\n        def self.register(type, klass = nil)\n          if klass.nil? && type.is_a?(Class)\n            klass = type\n            type = klass.name.to_s.demodulize.underscore\n          end\n          @@registry[type.to_sym] = klass\n        end\n\n        require 'rails_admin/config/fields/types/all'\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/fields.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Fields\n      # Default field factory loads fields based on their property type or\n      # association type.\n      #\n      # @see RailsAdmin::Config::Fields.registry\n      mattr_reader :default_factory\n      @@default_factory = proc do |parent, properties, fields|\n        # If it's an association\n        if properties.association?\n          association = parent.abstract_model.associations.detect { |a| a.name.to_s == properties.name.to_s }\n          field = RailsAdmin::Config::Fields::Types.load(\"#{association.polymorphic? ? :polymorphic : properties.type}_association\").new(parent, properties.name, association)\n        else\n          field = RailsAdmin::Config::Fields::Types.load(properties.type).new(parent, properties.name, properties)\n        end\n        fields << field\n        field\n      end\n\n      # Registry of field factories.\n      #\n      # Field factory is an anonymous function that receives the parent object,\n      # an array of field properties and an array of fields already instantiated.\n      #\n      # If the factory returns true then that property will not be run through\n      # the rest of the registered factories. If it returns false then the\n      # arguments will be passed to the next factory.\n      #\n      # By default a basic factory is registered which loads fields by their\n      # database column type. Also a password factory is registered which\n      # loads fields if their name is password. Third default factory is a\n      # devise specific factory which loads fields for devise user models.\n      #\n      # @see RailsAdmin::Config::Fields.register_factory\n      # @see rails_admin/config/fields/factories/password.rb\n      # @see rails_admin/config/fields/factories/devise.rb\n      @@registry = [@@default_factory]\n\n      # Build an array of fields by the provided parent object's abstract_model's\n      # property and association information. Each property and association is\n      # passed to the registered field factories which will populate the fields\n      # array that will be returned.\n      #\n      # @see RailsAdmin::Config::Fields.registry\n      def self.factory(parent)\n        fields = []\n        # Load fields for all properties (columns)\n\n        parent.abstract_model.properties.each do |properties|\n          # Unless a previous factory has already loaded current field as well\n          next if fields.detect { |f| f.name == properties.name }\n\n          # Loop through factories until one returns true\n          @@registry.detect { |factory| factory.call(parent, properties, fields) }\n        end\n        # Load fields for all associations (relations)\n        parent.abstract_model.associations.reject { |a| a.type == :belongs_to }.each do |association| # :belongs_to are created by factory for belongs_to fields\n          # Unless a previous factory has already loaded current field as well\n          next if fields.detect { |f| f.name == association.name }\n\n          # Loop through factories until one returns true\n          @@registry.detect { |factory| factory.call(parent, association, fields) }\n        end\n        fields\n      end\n\n      # Register a field factory to be included in the factory stack.\n      #\n      # Factories are invoked lifo (last in first out).\n      #\n      # @see RailsAdmin::Config::Fields.registry\n      def self.register_factory(&block)\n        @@registry.unshift(block)\n      end\n    end\n  end\nend\n\nrequire 'rails_admin/config/fields/types'\nrequire 'rails_admin/config/fields/factories/password'\nrequire 'rails_admin/config/fields/factories/enum'\nrequire 'rails_admin/config/fields/factories/devise'\nrequire 'rails_admin/config/fields/factories/paperclip'\nrequire 'rails_admin/config/fields/factories/dragonfly'\nrequire 'rails_admin/config/fields/factories/carrierwave'\nrequire 'rails_admin/config/fields/factories/active_storage'\nrequire 'rails_admin/config/fields/factories/shrine'\nrequire 'rails_admin/config/fields/factories/action_text'\nrequire 'rails_admin/config/fields/factories/association'\n"
  },
  {
    "path": "lib/rails_admin/config/groupable.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/group'\n\nmodule RailsAdmin\n  module Config\n    module Groupable\n      # Register a group instance variable and accessor methods for objects\n      # extending the has groups mixin. The extended objects must implement\n      # reader for a parent object which includes this module.\n      #\n      # @see RailsAdmin::Config::HasGroups.group\n      # @see RailsAdmin::Config::Fields::Group\n      def group(name = nil)\n        @group = parent.group(name) unless name.nil? # setter\n        @group ||= parent.group(:default) # getter\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/has_description.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    # Provides accessor and autoregistering of model's description.\n    module HasDescription\n      attr_reader :description\n\n      def desc(description, &_block)\n        @description ||= description\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/has_fields.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    # Provides accessors and autoregistering of model's fields.\n    module HasFields\n      # Defines a configuration for a field.\n      def field(name, type = nil, add_to_section = true, &block)\n        field = _fields.detect { |f| name == f.name }\n\n        # some fields are hidden by default (belongs_to keys, has_many associations in list views.)\n        # unhide them if config specifically defines them\n        field.show if field && !field.instance_variable_get(\"@#{field.name}_registered\").is_a?(Proc)\n        # Specify field as virtual if type is not specifically set and field was not\n        # found in default stack\n        if field.nil? && type.nil?\n          field = (_fields << RailsAdmin::Config::Fields::Types.load(:string).new(self, name, nil)).last\n\n        # Register a custom field type if one is provided and it is different from\n        # one found in default stack\n        elsif type && type != (field.nil? ? nil : field.type)\n          if field\n            properties = field.properties\n            field = _fields[_fields.index(field)] = RailsAdmin::Config::Fields::Types.load(type).new(self, name, properties)\n          else\n            properties = abstract_model.properties.detect { |p| name == p.name }\n            field = (_fields << RailsAdmin::Config::Fields::Types.load(type).new(self, name, properties)).last\n          end\n        end\n\n        # If field has not been yet defined add some default properties\n        if add_to_section && !field.defined\n          field.defined = true\n          field.order = _fields.count(&:defined)\n        end\n\n        # If a block has been given evaluate it and sort fields after that\n        field.instance_eval(&block) if block\n        field\n      end\n\n      # configure field(s) from the default group in a section without changing the original order.\n      def configure(name, type = nil, &block)\n        [*name].each { |field_name| field(field_name, type, false, &block) }\n      end\n\n      # include fields by name and apply an optional block to each (through a call to fields),\n      # or include fields by conditions if no field names\n      def include_fields(*field_names, &block)\n        if field_names.empty?\n          _fields.select { |f| f.instance_eval(&block) }.each do |f|\n            next if f.defined\n\n            f.defined = true\n            f.order = _fields.count(&:defined)\n          end\n        else\n          fields(*field_names, &block)\n        end\n      end\n\n      # exclude fields by name or by condition (block)\n      def exclude_fields(*field_names, &block)\n        block ||= proc { |f| field_names.include?(f.name) }\n        _fields.each { |f| f.defined = true } if _fields.select(&:defined).empty?\n        _fields.select { |f| f.instance_eval(&block) }.each { |f| f.defined = false }\n      end\n\n      # API candy\n      alias_method :exclude_fields_if, :exclude_fields\n      alias_method :include_fields_if, :include_fields\n\n      def include_all_fields\n        include_fields_if { true }\n      end\n\n      # Returns all field configurations for the model configuration instance. If no fields\n      # have been defined returns all fields. Defined fields are sorted to match their\n      # order property. If order was not specified it will match the order in which fields\n      # were defined.\n      #\n      # If a block is passed it will be evaluated in the context of each field\n      def fields(*field_names, &block)\n        return all_fields if field_names.empty? && !block\n\n        if field_names.empty?\n          defined = _fields.select(&:defined)\n          defined = _fields if defined.empty?\n        else\n          defined = field_names.collect { |field_name| _fields.detect { |f| f.name == field_name } }\n        end\n        defined.collect do |f|\n          unless f.defined\n            f.defined = true\n            f.order = _fields.count(&:defined)\n          end\n          f.instance_eval(&block) if block\n          f\n        end\n      end\n\n      # Defines configuration for fields by their type.\n      def fields_of_type(type, &block)\n        _fields.select { |f| type == f.type }.map! { |f| f.instance_eval(&block) } if block\n      end\n\n      # Accessor for all fields\n      def all_fields\n        ((ro_fields = _fields(true)).select(&:defined).presence || ro_fields).collect do |f|\n          f.section = self\n          f\n        end\n      end\n\n      # Get all fields defined as visible, in the correct order.\n      def visible_fields\n        i = 0\n        all_fields.collect { |f| f.with(bindings) }.select(&:visible?).sort_by { |f| [f.order, i += 1] } # stable sort, damn\n      end\n\n      def possible_fields\n        _fields(true)\n      end\n\n    protected\n\n      # Raw fields.\n      # Recursively returns parent section's raw fields\n      # Duping it if accessed for modification.\n      def _fields(readonly = false)\n        return @_fields if @_fields\n        return @_ro_fields if readonly && @_ro_fields\n\n        if instance_of?(RailsAdmin::Config::Sections::Base)\n          @_ro_fields = @_fields = RailsAdmin::Config::Fields.factory(self)\n        else\n          # parent is RailsAdmin::Config::Model, recursion is on Section's classes\n          @_ro_fields ||= parent.send(self.class.superclass.to_s.underscore.split('/').last)._fields(true).clone.freeze\n        end\n        readonly ? @_ro_fields : (@_fields ||= @_ro_fields.collect(&:clone))\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/has_groups.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/fields/group'\n\nmodule RailsAdmin\n  module Config\n    module HasGroups\n      # Accessor for a group\n      #\n      # If group with given name does not yet exist it will be created. If a\n      # block is passed it will be evaluated in the context of the group\n      def group(name, &block)\n        group = parent.groups.detect { |g| name == g.name }\n        group ||= (parent.groups << RailsAdmin::Config::Fields::Group.new(self, name)).last\n        group.tap { |g| g.section = self }.instance_eval(&block) if block\n        group\n      end\n\n      # Reader for groups that are marked as visible\n      def visible_groups\n        parent.groups.collect { |f| f.section = self; f.with(bindings) }.select(&:visible?).select do |g| # rubocop:disable Style/Semicolon\n          g.visible_fields.present?\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/hideable.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    # Defines a visibility configuration\n    module Hideable\n      # Visibility defaults to true.\n      def self.included(klass)\n        klass.register_instance_option :visible? do\n          !root.try :excluded?\n        end\n      end\n\n      # Reader whether object is hidden.\n      def hidden?\n        !visible\n      end\n\n      # Writer to hide object.\n      def hide(&block)\n        visible block ? proc { instance_eval(&block) == false } : false\n      end\n\n      # Writer to show field.\n      def show(&block)\n        visible block || true\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/inspectable.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Inspectable\n      def inspect\n        set_named_instance_variables\n\n        instance_name = try(:name) || try(:abstract_model).try(:model).try(:name)\n        instance_name = instance_name ? \"[#{instance_name}]\" : ''\n\n        instance_vars = instance_variables.collect do |v|\n          instance_variable_name(v)\n        end.join(', ')\n\n        \"#<#{self.class.name}#{instance_name} #{instance_vars}>\"\n      end\n\n    private\n\n      def instance_variable_name(variable)\n        value = instance_variable_get(variable)\n        if self.class::NAMED_INSTANCE_VARIABLES.include?(variable)\n          if value.respond_to?(:name)\n            \"#{variable}=#{value.name.inspect}\"\n          else\n            \"#{variable}=#{value.class.name}\"\n          end\n        else\n          \"#{variable}=#{value.inspect}\"\n        end\n      end\n\n      def set_named_instance_variables\n        self.class.const_set('NAMED_INSTANCE_VARIABLES', []) unless defined?(self.class::NAMED_INSTANCE_VARIABLES)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/lazy_model.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/model'\n\nmodule RailsAdmin\n  module Config\n    class LazyModel < BasicObject\n      def initialize(entity, &block)\n        @entity = entity\n        @deferred_blocks = [*block]\n        @initialized = false\n      end\n\n      def add_deferred_block(&block)\n        if @initialized\n          @model.instance_eval(&block)\n        else\n          @deferred_blocks << block\n        end\n      end\n\n      def target\n        @model ||= ::RailsAdmin::Config::Model.new(@entity)\n        # When evaluating multiple configuration blocks, the order of\n        # execution is important. As one would expect (in my opinion),\n        # options defined within a resource should take precedence over\n        # more general options defined in an initializer. This way,\n        # general settings for a number of resources could be specified\n        # in the initializer, while models could override these settings\n        # later, if required.\n        #\n        # CAVEAT: It cannot be guaranteed that blocks defined in an initializer\n        # will be loaded (and adde to @deferred_blocks) first. For instance, if\n        # the initializer references a model class before defining\n        # a RailsAdmin configuration block, the configuration from the\n        # resource will get added to @deferred_blocks first:\n        #\n        #     # app/models/some_model.rb\n        #     class SomeModel\n        #       rails_admin do\n        #         :\n        #       end\n        #     end\n        #\n        #     # config/initializers/rails_admin.rb\n        #     model = 'SomeModel'.constantize # blocks from SomeModel get loaded\n        #     model.config model do           # blocks from initializer gets loaded\n        #       :\n        #     end\n        #\n        # Thus, sort all blocks to execute for a resource by Proc.source_path,\n        # to guarantee that blocks from 'config/initializers' evaluate before\n        # blocks defined within a model class.\n        unless @deferred_blocks.empty?\n          @deferred_blocks.\n            partition { |block| block.source_location.first =~ %r{config/initializers} }.\n            flatten.\n            each { |block| @model.instance_eval(&block) }\n          @deferred_blocks = []\n        end\n        @initialized = true\n        @model\n      end\n\n      def method_missing(method_name, *args, &block)\n        target.send(method_name, *args, &block)\n      end\n\n      def respond_to_missing?(method_name, include_private = false)\n        super || target.respond_to?(method_name, include_private)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/model.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config'\nrequire 'rails_admin/config/proxyable'\nrequire 'rails_admin/config/configurable'\nrequire 'rails_admin/config/hideable'\nrequire 'rails_admin/config/has_groups'\nrequire 'rails_admin/config/fields/group'\nrequire 'rails_admin/config/fields'\nrequire 'rails_admin/config/has_fields'\nrequire 'rails_admin/config/has_description'\nrequire 'rails_admin/config/sections'\nrequire 'rails_admin/config/actions'\nrequire 'rails_admin/config/inspectable'\n\nmodule RailsAdmin\n  module Config\n    # Model specific configuration object.\n    class Model\n      include RailsAdmin::Config::Proxyable\n      include RailsAdmin::Config::Configurable\n      include RailsAdmin::Config::Hideable\n      include RailsAdmin::Config::Sections\n      include RailsAdmin::Config::Inspectable\n\n      attr_reader :abstract_model, :parent, :root\n      attr_accessor :groups\n\n      NAMED_INSTANCE_VARIABLES = %i[@parent @root].freeze\n\n      def initialize(entity)\n        @parent = nil\n        @root = self\n\n        @abstract_model =\n          case entity\n          when RailsAdmin::AbstractModel\n            entity\n          when Class, String\n            RailsAdmin::AbstractModel.new(entity)\n          when Symbol\n            RailsAdmin::AbstractModel.new(entity.to_s)\n          else\n            RailsAdmin::AbstractModel.new(entity.class)\n          end\n\n        @groups = [RailsAdmin::Config::Fields::Group.new(self, :default).tap { |g| g.label { I18n.translate('admin.form.basic_info') } }]\n      end\n\n      def excluded?\n        return @excluded if defined?(@excluded)\n\n        @excluded = !RailsAdmin::AbstractModel.all.collect(&:model_name).include?(abstract_model.try(:model_name))\n      end\n\n      def object_label\n        bindings[:object].send(object_label_method).presence ||\n          bindings[:object].send(:rails_admin_default_object_label_method)\n      end\n\n      # The display for a model instance (i.e. a single database record).\n      # Unless configured in a model config block, it'll try to use :name followed by :title methods, then\n      # any methods that may have been added to the label_methods array via Configuration.\n      # Failing all of these, it'll return the class name followed by the model's id.\n      register_instance_option :object_label_method do\n        @object_label_method ||= Config.label_methods.detect { |method| (@dummy_object ||= abstract_model.model.new).respond_to? method } || :rails_admin_default_object_label_method\n      end\n\n      register_instance_option :label do\n        (@label ||= {})[::I18n.locale] ||= abstract_model.model.model_name.human\n      end\n\n      register_instance_option :label_plural do\n        (@label_plural ||= {})[::I18n.locale] ||= abstract_model.model.model_name.human(count: Float::INFINITY, default: label.pluralize(::I18n.locale))\n      end\n\n      def pluralize(count)\n        count == 1 ? label : label_plural\n      end\n\n      register_instance_option :weight do\n        0\n      end\n\n      # parent node in navigation/breadcrumb\n      register_instance_option :parent do\n        @parent_model ||= begin\n          klass = abstract_model.model.superclass\n          klass = nil if klass.to_s.in?(%w[Object BasicObject ActiveRecord::Base])\n          klass\n        end\n      end\n\n      register_instance_option :navigation_label do\n        @navigation_label ||=\n          if (parent_module = abstract_model.model.try(:module_parent) || abstract_model.model.try!(:parent)) != Object\n            parent_module.to_s\n          end\n      end\n\n      register_instance_option :navigation_icon do\n        nil\n      end\n\n      register_instance_option :scope do\n        abstract_model.scoped\n      end\n\n      register_instance_option :last_created_at do\n        abstract_model.model.last.try(:created_at) if abstract_model.properties.detect { |c| c.name == :created_at }\n      end\n\n      # Act as a proxy for the base section configuration that actually\n      # store the configurations.\n      def method_missing(method_name, *args, &block)\n        send(:base).send(method_name, *args, &block)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/proxyable/proxy.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Config\n    module Proxyable\n      class Proxy < BasicObject\n        def initialize(object, bindings = {})\n          @object = object\n          @bindings = bindings\n        end\n\n        # Bind variables to be used by the configuration options\n        def bind(key, value = nil)\n          if key.is_a?(::Hash)\n            @bindings = key\n          else\n            @bindings[key] = value\n          end\n          self\n        end\n\n        def method_missing(method_name, *args, &block)\n          if @object.respond_to?(method_name)\n            reset = @object.bindings\n            begin\n              @object.bindings = @bindings\n              response = @object.__send__(method_name, *args, &block)\n            ensure\n              @object.bindings = reset\n            end\n            response\n          else\n            super(method_name, *args, &block)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/proxyable.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/proxyable/proxy'\nmodule RailsAdmin\n  module Config\n    module Proxyable\n      def bindings\n        Thread.current[:rails_admin_bindings] ||= {}\n        Thread.current[:rails_admin_bindings][self]\n      end\n\n      def bindings=(new_bindings)\n        Thread.current[:rails_admin_bindings] ||= {}\n        if new_bindings.nil?\n          Thread.current[:rails_admin_bindings].delete(self)\n        else\n          Thread.current[:rails_admin_bindings][self] = new_bindings\n        end\n      end\n\n      def with(bindings = {})\n        RailsAdmin::Config::Proxyable::Proxy.new(self, bindings)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections/base.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/proxyable'\nrequire 'rails_admin/config/configurable'\nrequire 'rails_admin/config/inspectable'\nrequire 'rails_admin/config/has_fields'\nrequire 'rails_admin/config/has_groups'\nrequire 'rails_admin/config/has_description'\n\nmodule RailsAdmin\n  module Config\n    module Sections\n      # Configuration of the show view for a new object\n      class Base\n        include RailsAdmin::Config::Proxyable\n        include RailsAdmin::Config::Configurable\n        include RailsAdmin::Config::Inspectable\n\n        include RailsAdmin::Config::HasFields\n        include RailsAdmin::Config::HasGroups\n        include RailsAdmin::Config::HasDescription\n\n        attr_reader :abstract_model, :parent, :root\n\n        NAMED_INSTANCE_VARIABLES = %i[@parent @root @abstract_model].freeze\n\n        def initialize(parent)\n          @parent = parent\n          @root = parent.root\n\n          @abstract_model = root.abstract_model\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections/create.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/sections/edit'\n\nmodule RailsAdmin\n  module Config\n    module Sections\n      # Configuration of the edit view for a new object\n      class Create < RailsAdmin::Config::Sections::Edit\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections/edit.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/sections/base'\n\nmodule RailsAdmin\n  module Config\n    module Sections\n      # Configuration of the edit view for an existing object\n      class Edit < RailsAdmin::Config::Sections::Base\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections/export.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/sections/base'\n\nmodule RailsAdmin\n  module Config\n    module Sections\n      # Configuration of the navigation view\n      class Export < RailsAdmin::Config::Sections::Base\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections/list.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/sections/base'\n\nmodule RailsAdmin\n  module Config\n    module Sections\n      # Configuration of the list view\n      class List < RailsAdmin::Config::Sections::Base\n        register_instance_option :checkboxes? do\n          true\n        end\n\n        register_instance_option :filters do\n          []\n        end\n\n        # Number of items listed per page\n        register_instance_option :items_per_page do\n          RailsAdmin::Config.default_items_per_page\n        end\n\n        # Positive value shows only prev, next links in pagination.\n        # This is for avoiding count(*) query.\n        register_instance_option :limited_pagination do\n          false\n        end\n\n        register_instance_option :search_by do\n          nil\n        end\n\n        register_instance_option :search_help do\n          nil\n        end\n\n        register_instance_option :sort_by do\n          parent.abstract_model.primary_key\n        end\n\n        register_instance_option :scopes do\n          []\n        end\n\n        register_instance_option :row_css_class do\n          ''\n        end\n\n        register_deprecated_instance_option :sidescroll do\n          ActiveSupport::Deprecation.warn('The sidescroll configuration option was removed, it is always enabled now.')\n        end\n\n        def fields_for_table\n          visible_fields.partition(&:sticky?).flatten\n        end\n\n        register_deprecated_instance_option :sort_reverse do\n          ActiveSupport::Deprecation.warn('The sort_reverse configuration option is deprecated and has no effect.')\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections/modal.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/sections/edit'\n\nmodule RailsAdmin\n  module Config\n    module Sections\n      class Modal < RailsAdmin::Config::Sections::Edit\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections/nested.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/sections/edit'\n\nmodule RailsAdmin\n  module Config\n    module Sections\n      class Nested < RailsAdmin::Config::Sections::Edit\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections/show.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/sections/base'\n\nmodule RailsAdmin\n  module Config\n    module Sections\n      class Show < RailsAdmin::Config::Sections::Base\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections/update.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/sections/edit'\n\nmodule RailsAdmin\n  module Config\n    module Sections\n      class Update < RailsAdmin::Config::Sections::Edit\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config/sections.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'active_support/core_ext/string/inflections'\nrequire 'rails_admin/config/sections/base'\nrequire 'rails_admin/config/sections/edit'\nrequire 'rails_admin/config/sections/update'\nrequire 'rails_admin/config/sections/create'\nrequire 'rails_admin/config/sections/nested'\nrequire 'rails_admin/config/sections/modal'\nrequire 'rails_admin/config/sections/list'\nrequire 'rails_admin/config/sections/export'\nrequire 'rails_admin/config/sections/show'\n\nmodule RailsAdmin\n  module Config\n    # Sections describe different views in the RailsAdmin engine. Configurable sections are\n    # list and navigation.\n    #\n    # Each section's class object can store generic configuration about that section (such as the\n    # number of visible tabs in the main navigation), while the instances (accessed via model\n    # configuration objects) store model specific configuration (such as the visibility of the\n    # model).\n    module Sections\n      def self.included(klass)\n        # Register accessors for all the sections in this namespace\n        constants.each do |name|\n          section = RailsAdmin::Config::Sections.const_get(name)\n          name = name.to_s.underscore.to_sym\n          klass.send(:define_method, name) do |&block|\n            @sections ||= {}\n            @sections[name] = section.new(self) unless @sections[name]\n            @sections[name].instance_eval(&block) if block\n            @sections[name]\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/config.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/config/lazy_model'\nrequire 'rails_admin/config/sections/list'\nrequire 'rails_admin/support/composite_keys_serializer'\nrequire 'active_support/core_ext/module/attribute_accessors'\n\nmodule RailsAdmin\n  module Config\n    # RailsAdmin is setup to try and authenticate with warden\n    # If warden is found, then it will try to authenticate\n    #\n    # This is valid for custom warden setups, and also devise\n    # If you're using the admin setup for devise, you should set RailsAdmin to use the admin\n    #\n    # @see RailsAdmin::Config.authenticate_with\n    # @see RailsAdmin::Config.authorize_with\n    DEFAULT_AUTHENTICATION = proc {}\n\n    DEFAULT_AUTHORIZE = proc {}\n\n    DEFAULT_AUDIT = proc {}\n\n    DEFAULT_CURRENT_USER = proc {}\n\n    class << self\n      # Application title, can be an array of two elements\n      attr_accessor :main_app_name\n\n      # Configuration option to specify which models you want to exclude.\n      attr_accessor :excluded_models\n\n      # Configuration option to specify a allowlist of models you want to RailsAdmin to work with.\n      # The excluded_models list applies against the allowlist as well and further reduces the models\n      # RailsAdmin will use.\n      # If included_models is left empty ([]), then RailsAdmin will automatically use all the models\n      # in your application (less any excluded_models you may have specified).\n      attr_accessor :included_models\n\n      # Fields to be hidden in show, create and update views\n      attr_reader :default_hidden_fields\n\n      # Default items per page value used if a model level option has not\n      # been configured\n      attr_accessor :default_items_per_page\n\n      # Default association limit\n      attr_accessor :default_associated_collection_limit\n\n      attr_reader :default_search_operator\n\n      # Configuration option to specify which method names will be searched for\n      # to be used as a label for object records. This defaults to [:name, :title]\n      attr_accessor :label_methods\n\n      # hide blank fields in show view if true\n      attr_accessor :compact_show_view\n\n      # Tell browsers whether to use the native HTML5 validations (novalidate form option).\n      attr_accessor :browser_validations\n\n      # set parent controller\n      attr_reader :parent_controller\n\n      # set settings for `protect_from_forgery` method\n      # By default, it raises exception upon invalid CSRF tokens\n      attr_accessor :forgery_protection_settings\n\n      # Stores model configuration objects in a hash identified by model's class\n      # name.\n      #\n      # @see RailsAdmin.config\n      attr_reader :registry\n\n      # Bootstrap CSS classes used for Navigation bar\n      attr_accessor :navbar_css_classes\n\n      # show Gravatar in Navigation bar\n      attr_accessor :show_gravatar\n\n      # accepts a hash of static links to be shown below the main navigation\n      attr_accessor :navigation_static_links\n      attr_accessor :navigation_static_label\n\n      # Set where RailsAdmin fetches JS/CSS from, defaults to :sprockets\n      attr_writer :asset_source\n\n      # For customization of composite keys representation\n      attr_accessor :composite_keys_serializer\n\n      # Setup authentication to be run as a before filter\n      # This is run inside the controller instance so you can setup any authentication you need to\n      #\n      # By default, the authentication will run via warden if available\n      # and will run the default.\n      #\n      # If you use devise, this will authenticate the same as _authenticate_user!_\n      #\n      # @example Devise admin\n      #   RailsAdmin.config do |config|\n      #     config.authenticate_with do\n      #       authenticate_admin!\n      #     end\n      #   end\n      #\n      # @example Custom Warden\n      #   RailsAdmin.config do |config|\n      #     config.authenticate_with do\n      #       warden.authenticate! scope: :paranoid\n      #     end\n      #   end\n      #\n      # @see RailsAdmin::Config::DEFAULT_AUTHENTICATION\n      def authenticate_with(&blk)\n        @authenticate = blk if blk\n        @authenticate || DEFAULT_AUTHENTICATION\n      end\n\n      # Setup auditing/versioning provider that observe objects lifecycle\n      def audit_with(*args, &block)\n        extension = args.shift\n        if extension\n          klass = RailsAdmin::AUDITING_ADAPTERS[extension]\n          klass.setup if klass.respond_to? :setup\n          @audit = proc do\n            @auditing_adapter = klass.new(*([self] + args).compact, &block)\n          end\n        elsif block\n          @audit = block\n        end\n        @audit || DEFAULT_AUDIT\n      end\n\n      # Setup authorization to be run as a before filter\n      # This is run inside the controller instance so you can setup any authorization you need to.\n      #\n      # By default, there is no authorization.\n      #\n      # @example Custom\n      #   RailsAdmin.config do |config|\n      #     config.authorize_with do\n      #       redirect_to root_path unless warden.user.is_admin?\n      #     end\n      #   end\n      #\n      # To use an authorization adapter, pass the name of the adapter. For example,\n      # to use with CanCanCan[https://github.com/CanCanCommunity/cancancan/], pass it like this.\n      #\n      # @example CanCanCan\n      #   RailsAdmin.config do |config|\n      #     config.authorize_with :cancancan\n      #   end\n      #\n      # See the wiki[https://github.com/railsadminteam/rails_admin/wiki] for more on authorization.\n      #\n      # @see RailsAdmin::Config::DEFAULT_AUTHORIZE\n      def authorize_with(*args, &block)\n        extension = args.shift\n        if extension\n          klass = RailsAdmin::AUTHORIZATION_ADAPTERS[extension]\n          klass.setup if klass.respond_to? :setup\n          @authorize = proc do\n            @authorization_adapter = klass.new(*([self] + args).compact, &block)\n          end\n        elsif block\n          @authorize = block\n        end\n        @authorize || DEFAULT_AUTHORIZE\n      end\n\n      # Setup configuration using an extension-provided ConfigurationAdapter\n      #\n      # @example Custom configuration for role-based setup.\n      #   RailsAdmin.config do |config|\n      #     config.configure_with(:custom) do |config|\n      #       config.models = ['User', 'Comment']\n      #       config.roles  = {\n      #         'Admin' => :all,\n      #         'User'  => ['User']\n      #       }\n      #     end\n      #   end\n      def configure_with(extension)\n        configuration = RailsAdmin::CONFIGURATION_ADAPTERS[extension].new\n        yield(configuration) if block_given?\n      end\n\n      # Setup a different method to determine the current user or admin logged in.\n      # This is run inside the controller instance and made available as a helper.\n      #\n      # By default, _request.env[\"warden\"].user_ or _current_user_ will be used.\n      #\n      # @example Custom\n      #   RailsAdmin.config do |config|\n      #     config.current_user_method do\n      #       current_admin\n      #     end\n      #   end\n      #\n      # @see RailsAdmin::Config::DEFAULT_CURRENT_USER\n      def current_user_method(&block)\n        @current_user = block if block\n        @current_user || DEFAULT_CURRENT_USER\n      end\n\n      def default_search_operator=(operator)\n        if %w[default like not_like starts_with ends_with is =].include? operator\n          @default_search_operator = operator\n        else\n          raise ArgumentError.new(\"Search operator '#{operator}' not supported\")\n        end\n      end\n\n      # pool of all found model names from the whole application\n      def models_pool\n        (viable_models - excluded_models.collect(&:to_s)).uniq.sort\n      end\n\n      # Loads a model configuration instance from the registry or registers\n      # a new one if one is yet to be added.\n      #\n      # First argument can be an instance of requested model, its class object,\n      # its class name as a string or symbol or a RailsAdmin::AbstractModel\n      # instance.\n      #\n      # If a block is given it is evaluated in the context of configuration instance.\n      #\n      # Returns given model's configuration\n      #\n      # @see RailsAdmin::Config.registry\n      def model(entity, &block)\n        key =\n          case entity\n          when RailsAdmin::AbstractModel\n            entity.model.try(:name).try :to_sym\n          when Class, ConstLoadSuppressor::ConstProxy\n            entity.name.to_sym\n          when String, Symbol\n            entity.to_sym\n          else\n            entity.class.name.to_sym\n          end\n\n        @registry[key] ||= RailsAdmin::Config::LazyModel.new(key.to_s)\n        @registry[key].add_deferred_block(&block) if block\n        @registry[key]\n      end\n\n      def asset_source\n        @asset_source ||=\n          begin\n            detected = defined?(Sprockets) ? :sprockets : :invalid\n            unless ARGV.join(' ').include? 'rails_admin:install'\n              warn <<~MSG\n                [Warning] After upgrading RailsAdmin to 3.x you haven't set asset_source yet, using :#{detected} as the default.\n                To suppress this message, run 'rails rails_admin:install' to setup the asset delivery method suitable to you.\n              MSG\n            end\n            detected\n          end\n      end\n\n      def default_hidden_fields=(fields)\n        if fields.is_a?(Array)\n          @default_hidden_fields = {}\n          @default_hidden_fields[:edit] = fields\n          @default_hidden_fields[:show] = fields\n        else\n          @default_hidden_fields = fields\n        end\n      end\n\n      def parent_controller=(name)\n        @parent_controller = name\n\n        if defined?(RailsAdmin::ApplicationController) || defined?(RailsAdmin::MainController)\n          RailsAdmin::Config::ConstLoadSuppressor.allowing do\n            RailsAdmin.send(:remove_const, :ApplicationController)\n            RailsAdmin.send(:remove_const, :MainController)\n            load RailsAdmin::Engine.root.join('app/controllers/rails_admin/application_controller.rb')\n            load RailsAdmin::Engine.root.join('app/controllers/rails_admin/main_controller.rb')\n          end\n        end\n      end\n\n      def total_columns_width=(_)\n        ActiveSupport::Deprecation.warn('The total_columns_width configuration option is deprecated and has no effect.')\n      end\n\n      def sidescroll=(_)\n        ActiveSupport::Deprecation.warn('The sidescroll configuration option was removed, it is always enabled now.')\n      end\n\n      # Setup actions to be used.\n      def actions(&block)\n        return unless block\n\n        RailsAdmin::Config::Actions.reset\n        RailsAdmin::Config::Actions.instance_eval(&block)\n      end\n\n      # Returns all model configurations\n      #\n      # @see RailsAdmin::Config.registry\n      def models\n        RailsAdmin::AbstractModel.all.collect { |m| model(m) }\n      end\n\n      # Reset all configurations to defaults.\n      #\n      # @see RailsAdmin::Config.registry\n      def reset\n        @compact_show_view = true\n        @browser_validations = true\n        @authenticate = nil\n        @authorize = nil\n        @audit = nil\n        @current_user = nil\n        @default_hidden_fields = {}\n        @default_hidden_fields[:base] = [:_type]\n        @default_hidden_fields[:edit] = %i[id _id created_at created_on deleted_at updated_at updated_on deleted_on]\n        @default_hidden_fields[:show] = %i[id _id created_at created_on deleted_at updated_at updated_on deleted_on]\n        @default_items_per_page = 20\n        @default_associated_collection_limit = 100\n        @default_search_operator = 'default'\n        @excluded_models = []\n        @included_models = []\n        @label_methods = %i[name title]\n        @main_app_name = proc { [Rails.application.engine_name.titleize.chomp(' Application'), 'Admin'] }\n        @registry = {}\n        @navbar_css_classes = %w[navbar-dark bg-primary border-bottom]\n        @show_gravatar = true\n        @navigation_static_links = {}\n        @navigation_static_label = nil\n        @asset_source = nil\n        @composite_keys_serializer = RailsAdmin::Support::CompositeKeysSerializer\n        @parent_controller = '::ActionController::Base'\n        @forgery_protection_settings = {with: :exception}\n        RailsAdmin::Config::Actions.reset\n        RailsAdmin::AbstractModel.reset\n      end\n\n      # Reset a provided model's configuration.\n      #\n      # @see RailsAdmin::Config.registry\n      def reset_model(model)\n        key = model.is_a?(Class) ? model.name.to_sym : model.to_sym\n        @registry.delete(key)\n      end\n\n      # Perform reset, then load RailsAdmin initializer again\n      def reload!\n        reset\n        load RailsAdmin::Engine.config.initializer_path\n      end\n\n      # Get all models that are configured as visible sorted by their weight and label.\n      #\n      # @see RailsAdmin::Config::Hideable\n      def visible_models(bindings)\n        visible_models_with_bindings(bindings).sort do |a, b|\n          if (weight_order = a.weight <=> b.weight) == 0\n            a.label.casecmp(b.label)\n          else\n            weight_order\n          end\n        end\n      end\n\n    private\n\n      def viable_models\n        included_models.collect(&:to_s).presence || begin\n          @@system_models ||= # memoization for tests\n            ([Rails.application] + Rails::Engine.subclasses.collect(&:instance)).flat_map do |app|\n              (app.paths['app/models'].to_a + app.config.eager_load_paths).collect do |load_path|\n                Dir.glob(app.root.join(load_path)).collect do |load_dir|\n                  path_prefix = \"#{app.root.join(load_dir)}/\"\n                  Dir.glob(\"#{load_dir}/**/*.rb\").collect do |filename|\n                    # app/models/module/class.rb => module/class.rb => module/class => Module::Class\n                    filename.delete_prefix(path_prefix).chomp('.rb').camelize\n                  end\n                end\n              end\n            end.flatten.reject { |m| m.starts_with?('Concerns::') } # rubocop:disable Style/MultilineBlockChain\n\n          @@system_models + @registry.keys.collect(&:to_s)\n        end\n      end\n\n      def visible_models_with_bindings(bindings)\n        models.collect { |m| m.with(bindings) }.select do |m|\n          m.visible? &&\n            RailsAdmin::Config::Actions.find(:index, bindings.merge(abstract_model: m.abstract_model)).try(:authorized?) &&\n            (!m.abstract_model.embedded? || m.abstract_model.cyclic?)\n        end\n      end\n    end\n\n    # Set default values for configuration options on load\n    reset\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/engine.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'kaminari'\nrequire 'nested_form'\nrequire 'rails'\nrequire 'rails_admin'\nrequire 'rails_admin/extensions/url_for_extension'\nrequire 'rails_admin/version'\nrequire 'turbo-rails'\n\nmodule RailsAdmin\n  class Engine < Rails::Engine\n    isolate_namespace RailsAdmin\n\n    attr_accessor :importmap\n\n    config.action_dispatch.rescue_responses['RailsAdmin::ActionNotAllowed'] = :forbidden\n\n    initializer 'RailsAdmin load UrlForExtension' do\n      RailsAdmin::Engine.routes.singleton_class.prepend(RailsAdmin::Extensions::UrlForExtension)\n    end\n\n    initializer 'RailsAdmin reload config in development' do |app|\n      config.initializer_path = app.root.join('config/initializers/rails_admin.rb')\n\n      unless Rails.application.config.cache_classes\n        ActiveSupport::Reloader.before_class_unload do\n          RailsAdmin::Config.reload!\n        end\n\n        reloader = app.config.file_watcher.new([config.initializer_path], []) do\n          # Do nothing, ActiveSupport::Reloader will trigger class_unload! anyway\n        end\n\n        app.reloaders << reloader\n        app.reloader.to_run do\n          reloader.execute_if_updated { require_unload_lock! }\n        end\n        reloader.execute\n      end\n    end\n\n    initializer 'RailsAdmin precompile hook', group: :all do |app|\n      case RailsAdmin.config.asset_source\n      when :sprockets\n        app.config.assets.precompile += %w[\n          rails_admin/application.js\n          rails_admin/application.css\n        ]\n        app.config.assets.paths << RailsAdmin::Engine.root.join('src')\n        require 'rails_admin/support/es_module_processor'\n        Sprockets.register_bundle_processor 'application/javascript', RailsAdmin::Support::ESModuleProcessor\n      when :importmap\n        self.importmap = Importmap::Map.new.draw(app.root.join('config/importmap.rails_admin.rb'))\n      end\n    end\n\n    # Check for required middlewares, users may forget to use them in Rails API mode\n    config.after_initialize do |app|\n      has_session_store = app.config.middleware.to_a.any? do |m|\n        m.klass.try(:<=, ActionDispatch::Session::AbstractStore) ||\n          m.klass.try(:<=, ActionDispatch::Session::AbstractSecureStore) ||\n          m.klass.name =~ /^ActionDispatch::Session::/\n      end\n      loaded = app.config.middleware.to_a.map(&:name)\n      required = %w[ActionDispatch::Cookies ActionDispatch::Flash Rack::MethodOverride]\n      missing = required - loaded\n      unless missing.empty? && has_session_store\n        configs = missing.map { |m| \"config.middleware.use #{m}\" }\n        configs << \"config.middleware.use #{app.config.session_store.try(:name) || 'ActionDispatch::Session::CookieStore'}, #{app.config.session_options}\" unless has_session_store\n        raise <<~ERROR\n          Required middlewares for RailsAdmin are not added\n          To fix this, add\n\n            #{configs.join(\"\\n  \")}\n\n          to config/application.rb.\n        ERROR\n      end\n\n      RailsAdmin::Version.warn_with_js_version\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/extension.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/extensions/controller_extension'\n\nmodule RailsAdmin\n  EXTENSIONS = [] # rubocop:disable Style/MutableConstant\n  AUTHORIZATION_ADAPTERS = {} # rubocop:disable Style/MutableConstant\n  AUDITING_ADAPTERS = {} # rubocop:disable Style/MutableConstant\n  CONFIGURATION_ADAPTERS = {} # rubocop:disable Style/MutableConstant\n\n  # Extend RailsAdmin\n  #\n  # The extension may define various adapters (e.g., for authorization) and\n  # register those via the options hash.\n  def self.add_extension(extension_key, extension_definition, options = {})\n    options.assert_valid_keys(:authorization, :configuration, :auditing)\n\n    EXTENSIONS << extension_key\n\n    AUTHORIZATION_ADAPTERS[extension_key] = extension_definition::AuthorizationAdapter if options[:authorization]\n\n    CONFIGURATION_ADAPTERS[extension_key] = extension_definition::ConfigurationAdapter if options[:configuration]\n\n    AUDITING_ADAPTERS[extension_key] = extension_definition::AuditingAdapter if options[:auditing]\n  end\n\n  # Setup all extensions for testing\n  def self.setup_all_extensions\n    (AUTHORIZATION_ADAPTERS.values + AUDITING_ADAPTERS.values).each do |klass|\n      klass.setup if klass.respond_to? :setup\n    rescue # rubocop:disable Style/RescueStandardError\n      # ignore errors\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/extensions/cancancan/authorization_adapter.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Extensions\n    module CanCanCan\n      # This adapter is for the CanCanCan[https://github.com/CanCanCommunity/cancancan] authorization library.\n      class AuthorizationAdapter\n        module ControllerExtension\n          def current_ability\n            # use _current_user instead of default current_user so it works with\n            # whatever current user method is defined with RailsAdmin\n            @current_ability ||= ability_class.new(_current_user)\n          end\n        end\n\n        include RailsAdmin::Config::Configurable\n\n        def self.setup\n          RailsAdmin::Extensions::ControllerExtension.include ControllerExtension\n        end\n\n        # See the +authorize_with+ config method for where the initialization happens.\n        def initialize(controller, ability = nil, &block)\n          @controller = controller\n          ability_class { ability } if ability\n          instance_eval(&block) if block\n\n          adapter = self\n          ControllerExtension.define_method(:ability_class) do\n            adapter.ability_class\n          end\n          @controller.current_ability.authorize! :access, :rails_admin\n        end\n\n        register_instance_option :ability_class do\n          Ability\n        end\n\n        # This method is called in every controller action and should raise an exception\n        # when the authorization fails. The first argument is the name of the controller\n        # action as a symbol (:create, :bulk_delete, etc.). The second argument is the\n        # AbstractModel instance that applies. The third argument is the actual model\n        # instance if it is available.\n        def authorize(action, abstract_model = nil, model_object = nil)\n          return unless action\n\n          action, subject = resolve_action_and_subject(action, abstract_model, model_object)\n          @controller.current_ability.authorize!(action, subject)\n        end\n\n        # This method is called primarily from the view to determine whether the given user\n        # has access to perform the action on a given model. It should return true when authorized.\n        # This takes the same arguments as +authorize+. The difference is that this will\n        # return a boolean whereas +authorize+ will raise an exception when not authorized.\n        def authorized?(action, abstract_model = nil, model_object = nil)\n          return unless action\n\n          action, subject = resolve_action_and_subject(action, abstract_model, model_object)\n          @controller.current_ability.can?(action, subject)\n        end\n\n        # This is called when needing to scope a database query. It is called within the list\n        # and bulk_delete/destroy actions and should return a scope which limits the records\n        # to those which the user can perform the given action on.\n        def query(action, abstract_model)\n          abstract_model.model.accessible_by(@controller.current_ability, action)\n        end\n\n        # This is called in the new/create actions to determine the initial attributes for new\n        # records. It should return a hash of attributes which match what the user\n        # is authorized to create.\n        def attributes_for(action, abstract_model)\n          @controller.current_ability.attributes_for(action, abstract_model&.model)\n        end\n\n      private\n\n        def resolve_action_and_subject(action, abstract_model, model_object)\n          subject = model_object || abstract_model&.model\n          if subject\n            [action, subject]\n          else\n            # For :dashboard compatibility\n            [:read, action]\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/extensions/cancancan.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/extensions/cancancan/authorization_adapter'\n\nRailsAdmin.add_extension(:cancancan, RailsAdmin::Extensions::CanCanCan, authorization: true)\n"
  },
  {
    "path": "lib/rails_admin/extensions/controller_extension.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Extensions\n    module ControllerExtension\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/extensions/paper_trail/auditing_adapter.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'active_support/core_ext/string/strip'\n\nmodule RailsAdmin\n  module Extensions\n    module PaperTrail\n      class VersionProxy\n        def initialize(version, user_class = User)\n          @version = version\n          @user_class = user_class\n        end\n\n        def message\n          @message = @version.event\n          @version.respond_to?(:changeset) && @version.changeset.present? ? @message + ' [' + @version.changeset.to_a.collect { |c| \"#{c[0]} = #{c[1][1]}\" }.join(', ') + ']' : @message\n        end\n\n        def created_at\n          @version.created_at\n        end\n\n        def table\n          @version.item_type\n        end\n\n        def username\n          begin\n            @user_class.find(@version.whodunnit).try(:email)\n          rescue StandardError\n            nil\n          end || @version.whodunnit\n        end\n\n        def item\n          @version.item_id\n        end\n      end\n\n      module ControllerExtension\n        def user_for_paper_trail\n          _current_user.try(:id) || _current_user\n        end\n      end\n\n      class AuditingAdapter\n        COLUMN_MAPPING = {\n          table: :item_type,\n          username: :whodunnit,\n          item: :item_id,\n          created_at: :created_at,\n          message: :event,\n        }.freeze\n        E_USER_CLASS_NOT_SET = <<~ERROR\n          Please set up PaperTrail's user class explicitly.\n\n              config.audit_with :paper_trail do\n                user_class { User }\n              end\n        ERROR\n        E_VERSION_MODEL_NOT_SET = <<~ERROR\n          Please set up PaperTrail's version model explicitly.\n\n              config.audit_with :paper_trail do\n                version_class { PaperTrail::Version }\n              end\n\n          If you have configured a model to use a custom version class\n          (https://github.com/paper-trail-gem/paper_trail#6a-custom-version-classes)\n          that configuration will take precedence over what you specify in `audit_with`.\n        ERROR\n\n        include RailsAdmin::Config::Configurable\n\n        def self.setup\n          raise 'PaperTrail not found' unless defined?(::PaperTrail)\n\n          RailsAdmin::Extensions::ControllerExtension.include ControllerExtension\n        end\n\n        def initialize(controller, user_class_name = nil, version_class_name = nil, &block)\n          @controller = controller\n          @controller&.send(:set_paper_trail_whodunnit)\n\n          user_class { user_class_name.to_s.constantize } if user_class_name\n          version_class { version_class_name.to_s.constantize } if version_class_name\n\n          instance_eval(&block) if block\n        end\n\n        register_instance_option :user_class do\n          User\n        rescue NameError\n          raise E_USER_CLASS_NOT_SET\n        end\n\n        register_instance_option :version_class do\n          PaperTrail::Version\n        rescue NameError\n          raise E_VERSION_MODEL_NOT_SET\n        end\n\n        register_instance_option :sort_by do\n          {id: :desc}\n        end\n\n        def latest(count = 100)\n          version_class.\n            order(sort_by).includes(:item).limit(count).\n            collect { |version| VersionProxy.new(version, user_class) }\n        end\n\n        def delete_object(_object, _model, _user)\n          # do nothing\n        end\n\n        def update_object(_object, _model, _user, _changes)\n          # do nothing\n        end\n\n        def create_object(_object, _abstract_model, _user)\n          # do nothing\n        end\n\n        def listing_for_model(model, query, sort, sort_reverse, all, page, per_page = (RailsAdmin::Config.default_items_per_page || 20))\n          listing_for_model_or_object(model, nil, query, sort, sort_reverse, all, page, per_page)\n        end\n\n        def listing_for_object(model, object, query, sort, sort_reverse, all, page, per_page = (RailsAdmin::Config.default_items_per_page || 20))\n          listing_for_model_or_object(model, object, query, sort, sort_reverse, all, page, per_page)\n        end\n\n      protected\n\n        # - model - a RailsAdmin::AbstractModel\n        def listing_for_model_or_object(model, object, query, sort, sort_reverse, all, page, per_page)\n          sort =\n            if sort.present?\n              {COLUMN_MAPPING[sort.to_sym] => sort_reverse ? :desc : :asc}\n            else\n              sort_by\n            end\n\n          current_page = page.presence || '1'\n\n          versions = object.nil? ? versions_for_model(model) : object.public_send(model.model.versions_association_name)\n          versions = versions.where('event LIKE ?', \"%#{query}%\") if query.present?\n          versions = versions.order(sort)\n          versions = versions.send(Kaminari.config.page_method_name, current_page).per(per_page) unless all\n          paginated_proxies = Kaminari.paginate_array([], total_count: versions.try(:total_count) || versions.count)\n          paginated_proxies = paginated_proxies.send(\n            paginated_proxies.respond_to?(Kaminari.config.page_method_name) ? Kaminari.config.page_method_name : :page,\n            current_page,\n          ).per(per_page)\n          versions.each do |version|\n            paginated_proxies << VersionProxy.new(version, user_class)\n          end\n          paginated_proxies\n        end\n\n        def versions_for_model(model)\n          model_name = model.model.name\n          base_class_name = model.model.base_class.name\n\n          options =\n            if base_class_name == model_name\n              {item_type: model_name}\n            else\n              {item_type: base_class_name, item_id: model.model.all}\n            end\n\n          version_class_for(model.model).where(options)\n        end\n\n        # PT can be configured to use [custom version\n        # classes](https://github.com/paper-trail-gem/paper_trail#6a-custom-version-classes)\n        #\n        # ```ruby\n        # has_paper_trail versions: { class_name: 'MyVersion' }\n        # ```\n        def version_class_for(model)\n          model.paper_trail.version_class\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/extensions/paper_trail.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/extensions/paper_trail/auditing_adapter'\n\nRailsAdmin.add_extension(:paper_trail, RailsAdmin::Extensions::PaperTrail, auditing: true)\n"
  },
  {
    "path": "lib/rails_admin/extensions/pundit/authorization_adapter.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Extensions\n    module Pundit\n      # This adapter is for the Pundit[https://github.com/elabs/pundit] authorization library.\n      # You can create another adapter for different authorization behavior, just be certain it\n      # responds to each of the public methods here.\n      class AuthorizationAdapter\n        # This method is called first time only and used for setup\n        def self.setup\n          RailsAdmin::Extensions::ControllerExtension.include defined?(::Pundit::Authorization) ? ::Pundit::Authorization : ::Pundit\n        end\n\n        # See the +authorize_with+ config method for where the initialization happens.\n        def initialize(controller)\n          @controller = controller\n        end\n\n        # This method is called in every controller action and should raise an exception\n        # when the authorization fails. The first argument is the name of the controller\n        # action as a symbol (:create, :bulk_delete, etc.). The second argument is the\n        # AbstractModel instance that applies. The third argument is the actual model\n        # instance if it is available.\n        def authorize(action, abstract_model = nil, model_object = nil)\n          record = model_object || abstract_model&.model\n          raise ::Pundit::NotAuthorizedError.new(\"not allowed to #{action} this #{record}\") if action && !policy(record).send(action_for_pundit(action))\n\n          @controller.instance_variable_set(:@_pundit_policy_authorized, true)\n        end\n\n        # This method is called primarily from the view to determine whether the given user\n        # has access to perform the action on a given model. It should return true when authorized.\n        # This takes the same arguments as +authorize+. The difference is that this will\n        # return a boolean whereas +authorize+ will raise an exception when not authorized.\n        def authorized?(action, abstract_model = nil, model_object = nil)\n          record = model_object || abstract_model&.model\n          policy(record).send(action_for_pundit(action)) if action\n        end\n\n        # This is called when needing to scope a database query. It is called within the list\n        # and bulk_delete/destroy actions and should return a scope which limits the records\n        # to those which the user can perform the given action on.\n        def query(_action, abstract_model)\n          @controller.send(:policy_scope, abstract_model.model.all)\n        rescue ::Pundit::NotDefinedError\n          abstract_model.model.all\n        end\n\n        # This is called in the new/create actions to determine the initial attributes for new\n        # records. It should return a hash of attributes which match what the user\n        # is authorized to create.\n        def attributes_for(action, abstract_model)\n          record = abstract_model&.model\n          policy(record).try(:attributes_for, action) || {}\n        end\n\n      private\n\n        def policy(record)\n          @controller.send(:policy, record)\n        rescue ::Pundit::NotDefinedError\n          ::ApplicationPolicy.new(@controller.send(:pundit_user), record)\n        end\n\n        def action_for_pundit(action)\n          action[-1, 1] == '?' ? action : \"#{action}?\"\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/extensions/pundit.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/extensions/pundit/authorization_adapter'\n\nRailsAdmin.add_extension(:pundit, RailsAdmin::Extensions::Pundit, authorization: true)\n"
  },
  {
    "path": "lib/rails_admin/extensions/url_for_extension.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Extensions\n    module UrlForExtension\n      def url_for(options, *args)\n        case options[:id]\n        when Array\n          options[:id] = RailsAdmin.config.composite_keys_serializer.serialize(options[:id])\n        end\n        super options, *args\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/support/composite_keys_serializer.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Support\n    module CompositeKeysSerializer\n      def self.serialize(keys)\n        keys.map { |key| key&.to_s&.gsub('_', '__') }.join('_')\n      end\n\n      def self.deserialize(string)\n        string.split('_').map { |key| key&.gsub('__', '_') }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/support/csv_converter.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'csv'\n\nmodule RailsAdmin\n  class CSVConverter\n    def initialize(objects = [], schema = nil)\n      @fields = []\n      @associations = []\n      schema ||= {}\n\n      return self if (@objects = objects).blank?\n\n      @model = objects.dup.first.class\n      @abstract_model = RailsAdmin::AbstractModel.new(@model)\n      @model_config = @abstract_model.config\n      @methods = [(schema[:only] || []) + (schema[:methods] || [])].flatten.compact\n      @fields = @methods.collect { |m| export_field_for(m) }.compact\n      @empty = ::I18n.t('admin.export.empty_value_for_associated_objects')\n      schema_include = schema.delete(:include) || {}\n\n      @associations = schema_include.each_with_object({}) do |(key, values), hash|\n        association = export_field_for(key)\n        next unless association&.association?\n\n        model_config = association.associated_model_config\n        abstract_model = model_config.abstract_model\n        methods = [(values[:only] || []) + (values[:methods] || [])].flatten.compact\n\n        hash[key] = {\n          association: association,\n          model: abstract_model.model,\n          abstract_model: abstract_model,\n          model_config: model_config,\n          fields: methods.collect { |m| export_field_for(m, model_config) }.compact,\n        }\n        hash\n      end\n    end\n\n    def to_csv(options = {})\n      if CSV::VERSION == '3.0.2'\n        raise <<~MSG\n          CSV library bundled with Ruby 2.6.0 has encoding issue, please upgrade Ruby to 2.6.1 or later.\n          https://github.com/ruby/csv/issues/62\n        MSG\n      end\n\n      options = HashWithIndifferentAccess.new(options)\n      encoding_to = Encoding.find(options[:encoding_to]) if options[:encoding_to].present?\n\n      csv_string = generate_csv_string(options)\n      csv_string = csv_string.encode(encoding_to, invalid: :replace, undef: :replace, replace: '?') if encoding_to\n\n      # Add a BOM for utf8 encodings, helps with utf8 auto-detect for some versions of Excel.\n      # Don't add if utf8 but user don't want to touch input encoding:\n      # If user chooses utf8, they will open it in utf8 and BOM will disappear at reading.\n      # But that way \"English\" users who don't bother and chooses to let utf8 by default won't get BOM added\n      # and will not see it if Excel opens the file with a different encoding.\n      csv_string = \"\\xEF\\xBB\\xBF#{csv_string}\" if encoding_to == Encoding::UTF_8\n\n      [!options[:skip_header], (encoding_to || csv_string.encoding).to_s, csv_string]\n    end\n\n  private\n\n    def export_field_for(method, model_config = @model_config)\n      model_config.export.fields.detect { |f| f.name == method }\n    end\n\n    def generate_csv_string(options)\n      generator_options = (options[:generator] || {}).symbolize_keys.delete_if { |_, value| value.blank? }\n      method = @objects.respond_to?(:find_each) ? :find_each : :each\n\n      CSV.generate(**generator_options) do |csv|\n        csv << generate_csv_header unless options[:skip_header]\n\n        @objects.send(method) do |object|\n          csv << generate_csv_row(object)\n        end\n      end\n    end\n\n    def generate_csv_header\n      @fields.collect do |field|\n        ::I18n.t('admin.export.csv.header_for_root_methods', name: field.label, model: @abstract_model.pretty_name)\n      end +\n        @associations.flat_map do |_association_name, option_hash|\n          option_hash[:fields].collect do |field|\n            ::I18n.t('admin.export.csv.header_for_association_methods', name: field.label, association: option_hash[:association].label)\n          end\n        end\n    end\n\n    def generate_csv_row(object)\n      @fields.collect do |field|\n        field.with(object: object).export_value\n      end +\n        @associations.flat_map do |association_name, option_hash|\n          associated_objects = [object.send(association_name)].flatten.compact\n          option_hash[:fields].collect do |field|\n            associated_objects.collect { |ao| field.with(object: ao).export_value.presence || @empty }.join(',')\n          end\n        end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/support/datetime.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Support\n    class Datetime\n      # Ruby format options as a key and flatpickr format options as a value\n      FLATPICKR_TRANSLATIONS = {\n        '%A' => 'l',       # The  full  weekday  name (\"Sunday\")\n        '%a' => 'D',       # The abbreviated weekday name (\"Sun\")\n        '%B' => 'F',       # The  full  month  name (\"January\")\n        '%b' => 'M',       # The abbreviated month name (\"Jan\")\n        '%D' => 'm/d/y',   # American date format mm/dd/yy\n        '%d' => 'd',       # Day of the month (01..31)\n        '%-d' => 'j',      # Day of the month (1..31)\n        '%e' => 'j',       # Day of the month (1..31)\n        '%F' => 'Y-m-d',   # ISO 8601 date format\n        '%H' => 'H',       # Hour of the day, 24-hour clock (00..23)\n        '%-H' => 'H',      # Hour of the day, 24-hour clock (0..23)\n        '%h' => 'M',       # Same as %b\n        '%I' => 'G',       # Hour of the day, 12-hour clock (01..12)\n        '%-I' => 'h',      # Hour of the day, 12-hour clock (1..12)\n        '%k' => 'H',       # Hour of the day, 24-hour clock (0..23)\n        '%l' => 'h',       # Hour of the day, 12-hour clock (1..12)\n        '%-l' => 'h',      # Hour of the day, 12-hour clock (1..12)\n        '%M' => 'i',       # Minute of the hour (00..59)\n        '%-M' => 'i',      # Minute of the hour (00..59)\n        '%m' => 'm',       # Month of the year (01..12)\n        '%-m' => 'n',      # Month of the year (1..12)\n        '%P' => 'K',       # Meridian indicator ('am' or 'pm')\n        '%p' => 'K',       # Meridian indicator ('AM' or 'PM')\n        '%R' => 'H:i',     # 24-hour time (%H:%M)\n        '%r' => 'G:i:S K', # 12-hour time (%I:%M:%S %p)\n        '%S' => 'S',       # Second of the minute (00..60)\n        '%-S' => 's',      # Second of the minute (0..60)\n        '%s' => 'U',       # Number of seconds since 1970-01-01 00:00:00 UTC.\n        '%T' => 'H:i:S',   # 24-hour time (%H:%M:%S)\n        '%U' => 'W',       # Week number of the year.  The week starts with Sunday.  (00..53)\n        '%w' => 'w',       # Day of the week (Sunday is 0, 0..6)\n        '%X' => 'H:i:S',   # Same as %T\n        '%x' => 'm/d/y',   # Same as %D\n        '%Y' => 'Y',       # Year with century\n        '%y' => 'y',       # Year without a century (00..99)\n        '%%' => '%',\n      }.freeze\n\n      class << self\n        def to_flatpickr_format(strftime_format)\n          strftime_format.gsub(/(?<!%)(?<![-0-9:])\\w/, '\\\\\\\\\\0').gsub(/%([-0-9:]?\\w)/) do |match|\n            # Timezone can't be handled by frontend, the server's one is always used\n            case match\n            when '%Z', '%:z' # Time zone as hour and minute offset from UTC with a colon (e.g. +09:00)\n              Time.zone.formatted_offset\n            when '%z' # Time zone as hour and minute offset from UTC (e.g. +0900)\n              Time.zone.formatted_offset(false)\n            else\n              FLATPICKR_TRANSLATIONS[match] or raise <<~MSG\n                Unsupported strftime directive '#{match}' was found. Please consider explicitly setting flatpickr_format instance option for the field.\n                  field(:name_of_field) { flatpickr_format '...' }\n              MSG\n            end\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/support/es_module_processor.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  module Support\n    class ESModuleProcessor\n      def self.instance\n        @instance ||= new\n      end\n\n      def self.call(input)\n        instance.call(input)\n      end\n\n      def initialize; end\n\n      def call(input)\n        return unless input[:name] == 'rails_admin/application'\n\n        input[:data].gsub(/^((?:import|export) .+)$/) { \"// #{Regexp.last_match(1)}\" }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/support/hash_helper.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  class HashHelper\n    def self.symbolize(obj)\n      case obj\n      when Array\n        obj.each_with_object([]) do |val, res|\n          res << case val\n                 when Hash, Array then symbolize(val)\n                 when String      then val.to_sym\n                 else val\n                 end\n        end\n      when Hash\n        obj.each_with_object({}) do |(key, val), res|\n          nkey = key.is_a?(String) ? key.to_sym : key\n          nval =\n            case val\n            when Hash, Array then symbolize(val)\n            when String      then val.to_sym\n            else val\n            end\n          res[nkey] = nval\n        end\n      else\n        obj\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin/version.rb",
    "content": "# frozen_string_literal: true\n\nmodule RailsAdmin\n  class Version\n    MAJOR = 3\n    MINOR = 3\n    PATCH = 0\n    PRE = nil\n\n    class << self\n      # @return [String]\n      def to_s\n        [MAJOR, MINOR, PATCH, PRE].compact.join('.')\n      end\n\n      def js\n        JSON.parse(File.read(\"#{__dir__}/../../package.json\"))['version']\n      end\n\n      def actual_js_version\n        case RailsAdmin.config.asset_source\n        when :webpacker, :webpack\n          js_version_from_node_modules\n        else\n          js\n        end\n      end\n\n      def warn_with_js_version\n        return unless Rails.env.development? || Rails.env.test?\n\n        case actual_js_version\n        when js\n          # Good\n        when nil\n          warn \"[Warning] Failed to detect RailsAdmin npm package, did you run 'yarn install'?\"\n        else\n          warn <<~MSG\n            [Warning] RailsAdmin npm package version inconsistency detected, expected #{js} but actually used is #{actual_js_version}.\n            This may cause partial or total malfunction of RailsAdmin frontend features.\n          MSG\n        end\n      end\n\n    private\n\n      def js_version_from_node_modules\n        JSON.parse(File.read(Rails.root.join('node_modules/rails_admin/package.json')))['version']\n      rescue StandardError\n        nil\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rails_admin.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/engine'\nrequire 'rails_admin/abstract_model'\nrequire 'rails_admin/config'\nrequire 'rails_admin/config/const_load_suppressor'\nrequire 'rails_admin/extension'\nrequire 'rails_admin/extensions/cancancan'\nrequire 'rails_admin/extensions/pundit'\nrequire 'rails_admin/extensions/paper_trail'\nrequire 'rails_admin/support/csv_converter'\nrequire 'rails_admin/support/hash_helper'\nrequire 'yaml'\n\nmodule RailsAdmin\n  extend RailsAdmin::Config::ConstLoadSuppressor\n\n  # Setup RailsAdmin\n  #\n  # Given the first argument is a model class, a model class name\n  # or an abstract model object proxies to model configuration method.\n  #\n  # If only a block is passed it is stored to initializer stack to be evaluated\n  # on first request in production mode and on each request in development. If\n  # initialization has already occurred (in other words RailsAdmin.setup has\n  # been called) the block will be added to stack and evaluated at once.\n  #\n  # Otherwise returns RailsAdmin::Config class.\n  #\n  # @see RailsAdmin::Config\n  def self.config(entity = nil, &block)\n    if entity\n      RailsAdmin::Config.model(entity, &block)\n    elsif block_given?\n      RailsAdmin::Config::ConstLoadSuppressor.suppressing { yield(RailsAdmin::Config) }\n    else\n      RailsAdmin::Config\n    end\n  end\n\n  # Backwards-compatible with safe_yaml/load when SafeYAML isn't available.\n  # Evaluates available YAML loaders at boot and creates appropriate method,\n  # so no conditionals are required at runtime.\n  begin\n    require 'safe_yaml/load'\n    def self.yaml_load(yaml)\n      SafeYAML.load(yaml)\n    end\n  rescue LoadError\n    if YAML.respond_to?(:safe_load)\n      def self.yaml_load(yaml)\n        YAML.safe_load(yaml)\n      end\n    else\n      raise LoadError.new \"Safe-loading of YAML is not available. Please install 'safe_yaml' or install Psych 2.0+\"\n    end\n  end\n\n  def self.yaml_dump(object)\n    YAML.dump(object)\n  end\nend\n"
  },
  {
    "path": "lib/tasks/.gitkeep",
    "content": ""
  },
  {
    "path": "lib/tasks/rails_admin.rake",
    "content": "# frozen_string_literal: true\n\nnamespace :rails_admin do\n  desc 'Install rails_admin'\n  task :install do\n    system 'rails g rails_admin:install'\n  end\n\n  desc 'Uninstall rails_admin'\n  task :uninstall do\n    system 'rails g rails_admin:uninstall'\n  end\n\n  desc 'CI env for GitHub Actions'\n  task :prepare_ci_env do\n    adapter = ENV['CI_DB_ADAPTER'] || 'sqlite3'\n    database = (adapter == 'sqlite3' ? 'db/development.sqlite3' : 'ci_rails_admin')\n    username =\n      case adapter\n      when 'postgresql'\n        'postgres'\n      when 'mysql2'\n        'root'\n      else\n        ''\n      end\n\n    configuration = {\n      'test' => {\n        'adapter' => adapter,\n        'database' => database,\n        'username' => username,\n        'password' => (adapter == 'postgresql' ? 'postgres' : ''),\n        'host' => '127.0.0.1',\n        'encoding' => 'utf8',\n        'pool' => 5,\n        'timeout' => 5000,\n      },\n    }\n\n    filename = Rails.root.join('config/database.yml')\n\n    File.open(filename, 'w') do |f|\n      f.write(configuration.to_yaml)\n    end\n  end\nend\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"rails_admin\",\n  \"version\": \"3.3.0\",\n  \"description\": \"RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.\",\n  \"homepage\": \"https://github.com/railsadminteam/rails_admin\",\n  \"license\": \"MIT\",\n  \"author\": \"Mitsuhiro Shibuya <mit.shibuya@gmail.com>\",\n  \"files\": [\n    \"src\"\n  ],\n  \"main\": \"src/rails_admin/base.js\",\n  \"scripts\": {\n    \"link\": \"yarn link && cd spec/dummy_app && yarn link rails_admin\",\n    \"format\": \"prettier -w .\"\n  },\n  \"dependencies\": {\n    \"@babel/runtime\": \"^7.16.7\",\n    \"@fortawesome/fontawesome-free\": \">=5.15.0 <7.0.0\",\n    \"@hotwired/turbo-rails\": \"^7.1.0\",\n    \"@popperjs/core\": \"^2.11.0\",\n    \"@rails/ujs\": \"^6.1.4-1\",\n    \"bootstrap\": \"^5.1.3\",\n    \"flatpickr\": \"^4.6.9\",\n    \"jquery\": \"^3.6.0\",\n    \"jquery-ui\": \"^1.12.1 <1.14.0\"\n  },\n  \"devDependencies\": {\n    \"prettier\": \"^2.4.1\"\n  }\n}\n"
  },
  {
    "path": "rails_admin.gemspec",
    "content": "# frozen_string_literal: true\n\nrequire_relative 'lib/rails_admin/version'\n\nGem::Specification.new do |spec|\n  # If you add a dependency, please maintain alphabetical order\n  spec.add_dependency 'activemodel-serializers-xml', '>= 1.0'\n  spec.add_dependency 'csv'\n  spec.add_dependency 'kaminari', '>= 0.14', '< 2.0'\n  spec.add_dependency 'nested_form', '~> 0.3'\n  spec.add_dependency 'rails', ['>= 6.0', '< 9']\n  spec.add_dependency 'turbo-rails', ['>= 1.0', '< 3']\n  spec.add_development_dependency 'bundler', '>= 1.0'\n  spec.authors = ['Erik Michaels-Ober', 'Bogdan Gaza', 'Petteri Kaapa', 'Benoit Benezech', 'Mitsuhiro Shibuya']\n  spec.description = 'RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.'\n  spec.email = ['sferik@gmail.com', 'bogdan@cadmio.org', 'petteri.kaapa@gmail.com']\n  spec.files = Dir['Gemfile', 'LICENSE.md', 'README.md', 'Rakefile', 'package.json', 'app/**/*', 'config/**/*', 'lib/**/*', 'public/**/*', 'src/**/*', 'vendor/**/*']\n  spec.licenses = %w[MIT]\n  spec.homepage = 'https://github.com/railsadminteam/rails_admin'\n  spec.name = 'rails_admin'\n  spec.require_paths = %w[lib]\n  spec.required_ruby_version     = '>= 2.6.0'\n  spec.required_rubygems_version = '>= 1.8.11'\n  spec.summary = 'Admin for Rails'\n  spec.version = RailsAdmin::Version\n  spec.post_install_message = <<~MSG\n    ### Upgrading RailsAdmin from 2.x.x to 3.x.x ###\n\n    Due to introduction of Webpack/Webpacker support, some additional dependencies and configuration will be needed.\n    Running `bin/rails g rails_admin:install` will suggest required changes, based on the current setup of your app.\n\n    For a complete list of changes, see https://github.com/railsadminteam/rails_admin/blob/master/CHANGELOG.md\n  MSG\nend\n"
  },
  {
    "path": "spec/controllers/rails_admin/application_controller_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::ApplicationController, type: :controller do\n  describe '#to_model_name' do\n    it 'works with modules' do\n      expect(controller.to_model_name('conversations~conversation')).to eq('Conversations::Conversation')\n    end\n  end\n\n  describe 'helper method _get_plugin_name' do\n    it 'works by default' do\n      expect(controller.send(:_get_plugin_name)).to eq(['Dummy App', 'Admin'])\n    end\n\n    it 'works for static names' do\n      RailsAdmin.config do |config|\n        config.main_app_name = %w[static value]\n      end\n      expect(controller.send(:_get_plugin_name)).to eq(%w[static value])\n    end\n\n    it 'works for dynamic names in the controller context' do\n      RailsAdmin.config do |config|\n        config.main_app_name = proc { |controller| [Rails.application.engine_name&.titleize, controller.params[:action].titleize] }\n      end\n      controller.params[:action] = 'dashboard'\n      expect(controller.send(:_get_plugin_name)).to eq(['Dummy App Application', 'Dashboard'])\n    end\n  end\n\n  describe '#_current_user' do\n    it 'is public' do\n      expect { controller._current_user }.not_to raise_error\n    end\n  end\n\n  describe '#rails_admin_controller?' do\n    it 'returns true' do\n      expect(controller.send(:rails_admin_controller?)).to be true\n    end\n  end\nend\n"
  },
  {
    "path": "spec/controllers/rails_admin/main_controller_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::MainController, type: :controller do\n  routes { RailsAdmin::Engine.routes }\n\n  def get(action, params)\n    super action, params: params\n  end\n\n  before do\n    controller.instance_variable_set :@action, RailsAdmin::Config::Actions.find(:index)\n  end\n\n  describe '#check_for_cancel' do\n    before do\n      allow(controller).to receive(:back_or_index) { raise StandardError.new('redirected back') }\n    end\n\n    it 'redirects to back if params[:bulk_ids] is nil when params[:bulk_action] is present' do\n      expect { get :bulk_delete, model_name: 'player', bulk_action: 'bulk_delete' }.to raise_error('redirected back')\n    end\n\n    it 'does not redirect to back if params[:bulk_ids] and params[:bulk_action] is present' do\n      expect { get :bulk_delete, model_name: 'player', bulk_action: 'bulk_delete', bulk_ids: [1] }.not_to raise_error\n    end\n  end\n\n  describe '#get_sort_hash' do\n    context 'options sortable is a hash' do\n      before do\n        RailsAdmin.config('Player') do\n          configure :team do\n            sortable do\n              :'team.name'\n            end\n          end\n        end\n      end\n\n      it 'returns the option with no changes' do\n        controller.params = {sort: 'team', model_name: 'players'}\n        expect(controller.send(:get_sort_hash, RailsAdmin.config(Player))).to eq(sort: :'team.name', sort_reverse: true)\n      end\n    end\n\n    context 'when default sort_by points to a field with a table reference for sortable' do\n      before do\n        RailsAdmin.config('Player') do\n          base do\n            field :name do\n              sortable 'teams.name'\n            end\n          end\n\n          list do\n            sort_by :name\n          end\n        end\n      end\n\n      it 'returns the query referenced in the sortable' do\n        expect(controller.send(:get_sort_hash, RailsAdmin.config(Player))).to eq(sort: 'teams.name', sort_reverse: true)\n      end\n    end\n\n    context 'with a virtual field' do\n      before do\n        RailsAdmin.config('Player') do\n          base do\n            field :virtual do\n              sortable :name\n            end\n          end\n\n          list do\n            sort_by :virtual\n          end\n        end\n      end\n\n      it 'returns the query referenced in the sortable' do\n        expect(controller.send(:get_sort_hash, RailsAdmin.config(Player))).to match(sort: /[\"`]?players[\"`]?\\.[\"`]?name[\"`]?/, sort_reverse: true)\n      end\n    end\n\n    it 'works with belongs_to associations with label method virtual' do\n      controller.params = {sort: 'parent_category', model_name: 'categories'}\n      expect(controller.send(:get_sort_hash, RailsAdmin.config(Category))).to eq(sort: 'categories.parent_category_id', sort_reverse: true)\n    end\n\n    context 'using mongoid', mongoid: true do\n      it 'gives back the remote table with label name, as it does not support joins' do\n        controller.params = {sort: 'team', model_name: 'players'}\n        expect(controller.send(:get_sort_hash, RailsAdmin.config(Player))).to match(sort: 'players.team_id', sort_reverse: true)\n      end\n    end\n\n    context 'using active_record', active_record: true do\n      let(:connection_config) do\n        if ActiveRecord::Base.respond_to?(:connection_db_config)\n          ActiveRecord::Base.connection_db_config.configuration_hash\n        else\n          ActiveRecord::Base.connection_config\n        end\n      end\n\n      it 'gives back the local column' do\n        controller.params = {sort: 'team', model_name: 'players'}\n        expect(controller.send(:get_sort_hash, RailsAdmin.config(Player))).to match(sort: /^[\"`]teams[\"`]\\.[\"`]name[\"`]$/, sort_reverse: true)\n      end\n\n      it 'quotes the table and column names it returns as :sort' do\n        controller.params = {sort: 'team', model_name: 'players'}\n        case connection_config[:adapter]\n        when 'mysql2'\n          expect(controller.send(:get_sort_hash, RailsAdmin.config(Player))[:sort]).to eq '`teams`.`name`'\n        else\n          expect(controller.send(:get_sort_hash, RailsAdmin.config(Player))[:sort]).to eq '\"teams\".\"name\"'\n        end\n      end\n    end\n  end\n\n  describe '#bulk_action' do\n    before do\n      RailsAdmin.config do |config|\n        config.actions do\n          dashboard\n          index do\n            visible do\n              raise # This shouldn't be invoked\n            end\n          end\n          bulk_delete\n        end\n      end\n    end\n\n    it 'retrieves actions using :bulkable scope' do\n      expect { post :bulk_action, params: {model_name: 'player', bulk_action: 'bulk_delete', bulk_ids: [1]} }.not_to raise_error\n    end\n  end\n\n  describe '#list_entries called from view' do\n    before do\n      @teams = FactoryBot.create_list(:team, 21)\n      controller.params = {model_name: 'teams'}\n    end\n\n    it 'paginates' do\n      expect(controller.list_entries(RailsAdmin.config(Team), :index, nil, false).to_a.length).to eq(21)\n      expect(controller.list_entries(RailsAdmin.config(Team), :index, nil, true).to_a.length).to eq(20)\n    end\n  end\n\n  describe '#list_entries called from view with kaminari custom param_name' do\n    before do\n      @teams = FactoryBot.create_list(:team, 21)\n      controller.params = {model_name: 'teams'}\n      Kaminari.config.param_name = :pagina\n    end\n\n    after do\n      Kaminari.config.param_name = :page\n    end\n\n    it 'paginates' do\n      expect(controller.list_entries(RailsAdmin.config(Team), :index, nil, false).to_a.length).to eq(21)\n      expect(controller.list_entries(RailsAdmin.config(Team), :index, nil, true).to_a.length).to eq(20)\n    end\n  end\n\n  describe '#list_entries called with bulk_ids' do\n    before do\n      @teams = FactoryBot.create_list(:team, 21)\n      controller.params = {model_name: 'teams', bulk_action: 'bulk_delete', bulk_ids: @teams.collect(&:id)}\n    end\n\n    it 'does not paginate' do\n      expect(controller.list_entries(RailsAdmin.config(Team), :bulk_delete).to_a.length).to eq(21)\n    end\n  end\n\n  describe '#list_entries for associated_collection' do\n    before do\n      @team = FactoryBot.create :team\n      controller.params = {associated_collection: 'players', current_action: 'update', source_abstract_model: 'team', source_object_id: @team.id, model_name: 'player', action: 'index'}\n      controller.get_model # set @model_config for Team\n    end\n\n    it \"doesn't scope associated collection records when associated_collection_scope is nil\" do\n      @players = FactoryBot.create_list(:player, 2)\n\n      RailsAdmin.config Team do\n        field :players do\n          associated_collection_scope false\n        end\n      end\n\n      expect(controller.list_entries.to_a.length).to eq(@players.size)\n    end\n\n    it 'scopes associated collection records according to associated_collection_scope' do\n      @players = FactoryBot.create_list(:player, 4)\n\n      RailsAdmin.config Team do\n        field :players do\n          associated_collection_scope do\n            proc { |scope| scope.limit(3) }\n          end\n        end\n      end\n\n      expect(controller.list_entries.to_a.length).to eq(3)\n    end\n\n    it 'scopes associated collection records according to bindings' do\n      @team.revenue = BigDecimal('3')\n      @team.save\n\n      @players = FactoryBot.create_list(:player, 5)\n\n      RailsAdmin.config Team do\n        field :players do\n          associated_collection_scope do\n            team = bindings[:object]\n            proc do |scope|\n              scope.limit(team.revenue)\n            end\n          end\n        end\n      end\n\n      expect(controller.list_entries.to_a.length).to eq(@team.revenue.to_i)\n    end\n\n    it 'limits associated collection records number to 30 if cache_all is false' do\n      @players = FactoryBot.create_list(:player, 40)\n\n      RailsAdmin.config Team do\n        field :players do\n          associated_collection_cache_all false\n        end\n      end\n      expect(controller.list_entries.to_a.length).to eq(30)\n    end\n\n    it \"doesn't limit associated collection records number to 30 if cache_all is true\" do\n      @players = FactoryBot.create_list(:player, 40)\n\n      RailsAdmin.config Team do\n        field :players do\n          associated_collection_cache_all true\n        end\n      end\n      expect(controller.list_entries.length).to eq(@players.size)\n    end\n\n    it 'orders associated collection records by id, descending' do\n      @players = FactoryBot.create_list(:player, 3)\n\n      expect(controller.list_entries.to_a).to eq(@players.sort_by(&:id).reverse)\n    end\n  end\n\n  describe '#action_missing' do\n    it 'raises error when action is not found' do\n      expect(RailsAdmin::Config::Actions).to receive(:find).and_return(nil)\n      expect { get :index, model_name: 'player' }.to raise_error AbstractController::ActionNotFound\n    end\n  end\n\n  describe '#respond_to_missing?' do\n    it 'returns the result based on existence of action' do\n      expect(controller.send(:respond_to_missing?, :index, false)).to be true\n      expect(controller.send(:respond_to_missing?, :invalid_action, false)).to be false\n    end\n  end\n\n  describe '#get_collection' do\n    let(:team) { FactoryBot.create :team }\n    let!(:player) { FactoryBot.create :player, team: team }\n    let(:model_config) { RailsAdmin.config(Team) }\n    let(:abstract_model) { model_config.abstract_model }\n    before do\n      controller.params = {model_name: 'team'}\n    end\n\n    it 'performs eager-loading with `eager_load true`' do\n      RailsAdmin.config Team do\n        field :players do\n          eager_load true\n        end\n      end\n      expect(abstract_model).to receive(:all).with(hash_including(include: [:players]), nil).once.and_call_original\n      controller.send(:get_collection, model_config, nil, false).to_a\n    end\n\n    it 'performs eager-loading with custom eager_load value' do\n      RailsAdmin.config Team do\n        field :players do\n          eager_load players: :draft\n        end\n      end\n      expect(abstract_model).to receive(:all).with(hash_including(include: [{players: :draft}]), nil).once.and_call_original\n      controller.send(:get_collection, model_config, nil, false).to_a\n    end\n\n    context 'on export' do\n      before do\n        controller.instance_variable_set :@action, RailsAdmin::Config::Actions.find(:export)\n      end\n\n      it 'uses the export section' do\n        RailsAdmin.config Team do\n          export do\n            field :players do\n              eager_load true\n            end\n          end\n        end\n        expect(abstract_model).to receive(:all).with(hash_including(include: [:players]), nil).once.and_call_original\n        controller.send(:get_collection, model_config, nil, false).to_a\n      end\n    end\n  end\n\n  describe 'index' do\n    it \"uses target model's primary key\" do\n      @user = FactoryBot.create :managing_user\n      @team = FactoryBot.create :managed_team, user: @user\n      get :index, model_name: 'managed_team', source_object_id: @user.id, source_abstract_model: 'managing_user', associated_collection: 'teams', current_action: :create, compact: true, format: :json\n      expect(response.body).to match(/\"id\":\"#{@team.id}\"/)\n    end\n\n    context 'as JSON' do\n      it 'returns strings' do\n        FactoryBot.create :player, team: (FactoryBot.create :team)\n        get :index, model_name: 'player', source_object_id: Team.first.id, source_abstract_model: 'team', associated_collection: 'players', current_action: :create, compact: true, format: :json\n        expect(JSON.parse(response.body).first['id']).to be_a_kind_of String\n      end\n    end\n\n    context 'when authorizing requests with pundit' do\n      if defined?(Devise::Test)\n        include Devise::Test::ControllerHelpers\n      else\n        include Devise::TestHelpers\n      end\n\n      controller(RailsAdmin::MainController) do\n        include defined?(::Pundit::Authorization) ? ::Pundit::Authorization : ::Pundit\n        after_action :verify_authorized\n      end\n\n      it 'performs authorization' do\n        RailsAdmin.config do |c|\n          c.authorize_with(:pundit)\n          c.authenticate_with { warden.authenticate! scope: :user }\n          c.current_user_method(&:current_user)\n        end\n        login_as FactoryBot.create :user, roles: [:admin]\n        player = FactoryBot.create :player, team: (FactoryBot.create :team)\n        expect { get :show, model_name: 'player', id: player.id }.not_to raise_error\n      end\n    end\n  end\n\n  describe 'sanitize_params_for!' do\n    context 'with datetime' do\n      before do\n        ActionController::Parameters.permit_all_parameters = false\n\n        RailsAdmin.config Comment do\n          configure :created_at do\n            show\n          end\n        end\n\n        RailsAdmin.config NestedFieldTest do\n          configure :created_at do\n            show\n          end\n        end\n\n        controller.params = ActionController::Parameters.new(\n          'field_test' => {\n            'unallowed_field' => \"I shouldn't be here\",\n            'datetime_field' => '2010-08-01T00:00:00',\n            'nested_field_tests_attributes' => {\n              'new_1330520162002' => {\n                'comment_attributes' => {\n                  'unallowed_field' => \"I shouldn't be here\",\n                  'created_at' => '2010-08-02T00:00:00',\n                },\n                'created_at' => '2010-08-03T00:00:00',\n              },\n            },\n            'comment_attributes' => {\n              'unallowed_field' => \"I shouldn't be here\",\n              'created_at' => '2010-08-04T00:00:00',\n            },\n          },\n        )\n        controller.send(:sanitize_params_for!, :create, RailsAdmin.config(FieldTest), controller.params['field_test'])\n      end\n\n      after do\n        ActionController::Parameters.permit_all_parameters = true\n      end\n\n      it 'sanitize params recursively in nested forms' do\n        expect(controller.params[:field_test].to_h).to eq(\n          'datetime_field' => ::Time.zone.parse('Sun, 01 Aug 2010 00:00:00 UTC +00:00'),\n          'nested_field_tests_attributes' => {\n            'new_1330520162002' => {\n              'comment_attributes' => {\n                'created_at' => ::Time.zone.parse('Mon, 02 Aug 2010 00:00:00 UTC +00:00'),\n              },\n              'created_at' => ::Time.zone.parse('Tue, 03 Aug 2010 00:00:00 UTC +00:00'),\n            },\n          },\n          'comment_attributes' => {\n            'created_at' => ::Time.zone.parse('Wed, 04 Aug 2010 00:00:00 UTC +00:00'),\n          },\n        )\n      end\n\n      it 'enforces permit!' do\n        expect(controller.params['field_test'].permitted?).to be_truthy\n        expect(controller.params['field_test']['nested_field_tests_attributes'].values.first.permitted?).to be_truthy\n        expect(controller.params['field_test']['comment_attributes'].permitted?).to be_truthy\n      end\n    end\n\n    it 'allows for delete method with Carrierwave' do\n      RailsAdmin.config FieldTest do\n        field :carrierwave_asset\n        field :carrierwave_assets\n        field :dragonfly_asset\n        field :paperclip_asset do\n          delete_method :delete_paperclip_asset\n        end\n        if defined?(ActiveStorage)\n          field :active_storage_asset do\n            delete_method :remove_active_storage_asset\n          end\n        end\n        if defined?(ActiveStorage)\n          field :active_storage_assets do\n            delete_method :remove_active_storage_assets\n          end\n        end\n        if defined?(Shrine)\n          field :shrine_asset do\n            delete_method :remove_shrine_asset\n          end\n        end\n      end\n      controller.params = HashWithIndifferentAccess.new(\n        'field_test' => {\n          'carrierwave_asset' => 'test',\n          'carrierwave_asset_cache' => 'test',\n          'remove_carrierwave_asset' => 'test',\n          'carrierwave_assets' => 'test',\n          'dragonfly_asset' => 'test',\n          'remove_dragonfly_asset' => 'test',\n          'retained_dragonfly_asset' => 'test',\n          'paperclip_asset' => 'test',\n          'delete_paperclip_asset' => 'test',\n          'should_not_be_here' => 'test',\n        }.merge(defined?(ActiveStorage) ? {'active_storage_asset' => 'test', 'remove_active_storage_asset' => 'test', 'active_storage_assets' => 'test', 'remove_active_storage_assets' => 'test'} : {}).\n          merge(defined?(Shrine) ? {'shrine_asset' => 'test', 'remove_shrine_asset' => 'test'} : {}),\n      )\n\n      controller.send(:sanitize_params_for!, :create, RailsAdmin.config(FieldTest), controller.params['field_test'])\n      expect(controller.params[:field_test].to_h).to eq({\n        'carrierwave_asset' => 'test',\n        'remove_carrierwave_asset' => 'test',\n        'carrierwave_asset_cache' => 'test',\n        'carrierwave_assets' => 'test',\n        'dragonfly_asset' => 'test',\n        'remove_dragonfly_asset' => 'test',\n        'retained_dragonfly_asset' => 'test',\n        'paperclip_asset' => 'test',\n        'delete_paperclip_asset' => 'test',\n      }.merge(defined?(ActiveStorage) ? {'active_storage_asset' => 'test', 'remove_active_storage_asset' => 'test', 'active_storage_assets' => 'test', 'remove_active_storage_assets' => 'test'} : {}).\n        merge(defined?(Shrine) ? {'shrine_asset' => 'test', 'remove_shrine_asset' => 'test'} : {}))\n    end\n\n    it 'allows for polymorphic associations parameters' do\n      RailsAdmin.config Comment do\n        field :commentable\n      end\n\n      controller.params = HashWithIndifferentAccess.new(\n        'comment' => {\n          'commentable_id' => 'test',\n          'commentable_type' => 'test',\n        },\n      )\n      controller.send(:sanitize_params_for!, :create, RailsAdmin.config(Comment), controller.params['comment'])\n      expect(controller.params[:comment].to_h).to eq(\n        'commentable_id' => 'test',\n        'commentable_type' => 'test',\n      )\n    end\n  end\n\n  describe 'back_or_index' do\n    before do\n      allow(controller).to receive(:index_path).and_return(index_path)\n    end\n\n    let(:index_path) { '/' }\n\n    it 'returns back to index when return_to is not defined' do\n      controller.params = {}\n      expect(controller.send(:back_or_index)).to eq(index_path)\n    end\n\n    it 'returns back to return_to url when it starts with same protocol and host' do\n      return_to_url = \"http://#{request.host}/teams\"\n      controller.params = {return_to: return_to_url}\n      expect(controller.send(:back_or_index)).to eq(return_to_url)\n    end\n\n    it 'returns back to return_to url when it contains a path' do\n      return_to_url = '/teams'\n      controller.params = {return_to: return_to_url}\n      expect(controller.send(:back_or_index)).to eq(return_to_url)\n    end\n\n    it 'returns back to index path when return_to path does not start with slash' do\n      return_to_url = 'teams'\n      controller.params = {return_to: return_to_url}\n      expect(controller.send(:back_or_index)).to eq(index_path)\n    end\n\n    it 'returns back to index path when return_to url does not start with full protocol' do\n      return_to_url = \"#{request.host}/teams\"\n      controller.params = {return_to: return_to_url}\n      expect(controller.send(:back_or_index)).to eq(index_path)\n    end\n\n    it 'returns back to index path when return_to url starts with double slash' do\n      return_to_url = \"//#{request.host}/teams\"\n      controller.params = {return_to: return_to_url}\n      expect(controller.send(:back_or_index)).to eq(index_path)\n    end\n\n    it 'returns back to index path when return_to url starts with triple slash' do\n      return_to_url = \"///#{request.host}/teams\"\n      controller.params = {return_to: return_to_url}\n      expect(controller.send(:back_or_index)).to eq(index_path)\n    end\n\n    it 'returns back to index path when return_to url does not have host' do\n      return_to_url = 'http:///teams'\n      controller.params = {return_to: return_to_url}\n      expect(controller.send(:back_or_index)).to eq(index_path)\n    end\n\n    it 'returns back to index path when return_to url starts with different protocol' do\n      return_to_url = \"other://#{request.host}/teams\"\n      controller.params = {return_to: return_to_url}\n      expect(controller.send(:back_or_index)).to eq(index_path)\n    end\n\n    it 'returns back to index path when return_to does not start with the same protocol and host' do\n      controller.params = {return_to: \"http://google.com?#{request.host}\"}\n      expect(controller.send(:back_or_index)).to eq(index_path)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/.browserslistrc",
    "content": "defaults\n"
  },
  {
    "path": "spec/dummy_app/.dockerignore",
    "content": "# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.\n\n# Ignore git directory.\n/.git/\n\n# Ignore bundler config and Gemfile.lock.\n/.bundle\n/Gemfile.lock\n\n# Ignore all default key files.\n/config/master.key\n/config/credentials/*.key\n\n# Ignore all environment files.\n/.env*\n!/.env.example\n\n# Ignore all logfiles and tempfiles.\n/log/*\n/tmp/*\n!/log/.keep\n!/tmp/.keep\n\n# Ignore pidfiles, but keep the directory.\n/tmp/pids/*\n!/tmp/pids/\n!/tmp/pids/.keep\n\n# Ignore storage (uploaded files in development and any SQLite databases).\n/db/*.sqlite3\n/public/system\n/public/uploads\n/public/vite\n/storage/*\n!/storage/.keep\n/tmp/storage/*\n!/tmp/storage/\n!/tmp/storage/.keep\n\n# Ignore assets.\n/node_modules/\n/app/assets/builds/*\n!/app/assets/builds/.keep\n/public/assets\n"
  },
  {
    "path": "spec/dummy_app/.gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n#\n# If you find yourself ignoring temporary files generated by your text editor\n# or operating system, you probably want to add a global ignore instead:\n#   git config --global core.excludesfile ~/.gitignore_global\n\n# Ignore bundler config\n/.bundle\n\n/app/assets/builds/*\n!/app/assets/builds/.keep\n\n# Ignore the default SQLite database.\n/db/*.sqlite3\n\n# Ignore all logfiles and tempfiles.\n/log/*.log\n/tmp\n\n/public/system\n\n/public/assets\n/public/packs\n/public/packs-test\n/public/vite*\n/node_modules\n/yarn-error.log\n/yarn.lock\nyarn-debug.log*\n.yarn-integrity\n"
  },
  {
    "path": "spec/dummy_app/Dockerfile",
    "content": "# syntax = docker/dockerfile:1\n\n# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile\nARG RUBY_VERSION=3.1\nFROM ruby:$RUBY_VERSION-slim AS base\n\nLABEL fly_launch_runtime=\"rails\"\n\n# Rails app lives here\nWORKDIR /rails\n\n# Set production environment\nENV RAILS_ENV=\"production\" \\\n    BUNDLE_WITHOUT=\"development:test\"\n\n# Update gems and bundler\nRUN gem update --system --no-document && \\\n    gem install -N bundler\n\n# Install packages needed to install nodejs\nRUN apt-get update -qq && \\\n    apt-get install --no-install-recommends -y curl && \\\n    rm -rf /var/lib/apt/lists /var/cache/apt/archives\n\n# Install Node.js\n# ARG NODE_VERSION=18.16.0\n# ENV PATH=/usr/local/node/bin:$PATH\n# RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \\\n#     /tmp/node-build-master/bin/node-build \"${NODE_VERSION}\" /usr/local/node && \\\n#     rm -rf /tmp/node-build-master\n\n# Throw-away build stage to reduce size of final image\nFROM base AS build\n\n# Install packages needed to build gems and node modules\nRUN apt-get update -qq && \\\n    apt-get install --no-install-recommends -y build-essential default-libmysqlclient-dev git libpq-dev libvips libyaml-dev node-gyp pkg-config python-is-python3\n\n# Build options\nENV PATH=\"/usr/local/node/bin:$PATH\"\n\n# Copy application code\nCOPY --link . .\n\nRUN sed -i \"s/, path: '..\\/..\\/'//\" Gemfile\nRUN bundle install && \\\n    rm -rf ~/.bundle/ $BUNDLE_PATH/ruby/*/cache $BUNDLE_PATH/ruby/*/bundler/gems/*/.git\n\n# Install node modules\n# COPY --link package.json ./\n# RUN npm install\n\n# Precompiling assets for production without requiring secret RAILS_MASTER_KEY\nRUN sed -i \"/link_tree ..\\/..\\/..\\//d\" app/assets/config/manifest.js\nRUN SECRET_KEY_BASE=DUMMY ./bin/rails assets:precompile db:setup\n\n# Final stage for app image\nFROM base\n\n# Install packages needed for deployment\nRUN apt-get update -qq && \\\n    apt-get install --no-install-recommends -y curl imagemagick libsqlite3-0 libvips && \\\n    rm -rf /var/lib/apt/lists /var/cache/apt/archives\n\n# Copy built artifacts: gems, application\nCOPY --from=build /usr/local/bundle /usr/local/bundle\nCOPY --from=build /rails /rails\n\n# Run and own only the runtime files as a non-root user for security\nRUN useradd rails --create-home --shell /bin/bash && \\\n    mkdir public/system public/uploads && \\\n    chown -R rails:rails db log tmp public/system public/uploads\nUSER rails:rails\n\n# Deployment options\nENV RAILS_LOG_TO_STDOUT=\"1\" \\\n    RAILS_SERVE_STATIC_FILES=\"true\" \\\n    RAILS_MAX_THREADS=\"1\"\n\n# Entrypoint prepares the database.\nENTRYPOINT [\"/rails/bin/docker-entrypoint\"]\n\n# Start the server by default, this can be overwritten at runtime\nEXPOSE 3000\nCMD [\"./bin/rails\", \"server\"]\n"
  },
  {
    "path": "spec/dummy_app/Gemfile",
    "content": "# frozen_string_literal: true\n\nsource 'https://rubygems.org'\n\ngem 'rails', '>= 7.0.0'\n\ngroup :active_record do\n  platforms :jruby do\n    gem 'activerecord-jdbcmysql-adapter', '>= 1.2' if ENV['CI_DB_ADAPTER'] == 'mysql2'\n    gem 'activerecord-jdbcpostgresql-adapter', '>= 1.2' if ENV['CI_DB_ADAPTER'] == 'postgresql'\n    gem 'activerecord-jdbcsqlite3-adapter', '>= 1.2'\n  end\n\n  platforms :ruby, :mswin, :mingw do\n    gem 'mysql2', '>= 0.3.14' if ENV['CI_DB_ADAPTER'] == 'mysql2'\n    gem 'pg', '>= 0.14' if ENV['CI_DB_ADAPTER'] == 'postgresql'\n    gem 'sqlite3', '>= 1.3.0'\n  end\n\n  gem 'paper_trail', '>= 12.0'\nend\n\ngem 'carrierwave', '>= 2.0.0.rc', '< 3.0'\ngem 'devise', '>= 3.2'\ngem 'dragonfly', '~> 1.0'\ngem 'mini_magick', '>= 3.4'\ngem 'mlb', '>= 0.7'\ngem 'paperclip', '>= 3.4'\ngem 'puma'\ngem 'rails_admin', path: '../../'\ngem 'shrine', '~> 3.0'\n\ngroup :development, :test do\n  gem 'cssbundling-rails', require: false\n  gem 'importmap-rails', require: false\n  gem 'vite_rails', require: false\n  gem 'webpacker', require: false\nend\n\n# Gems used only for assets and not required\n# in production environments by default.\ngroup :assets do\n  gem 'sassc-rails', '~> 2.1'\n\n  # See https://github.com/sstephenson/execjs#readme for more supported runtimes\n  # gem 'therubyracer'\n\n  gem 'uglifier', '>= 1.3'\nend\n"
  },
  {
    "path": "spec/dummy_app/Procfile.dev",
    "content": "web: bin/rails server -p 3000\ncss: yarn build:css --watch\nvite: bin/vite dev\n"
  },
  {
    "path": "spec/dummy_app/Rakefile",
    "content": "# frozen_string_literal: true\n\n# Add your own tasks in files placed in lib/tasks ending in .rake,\n# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.\n\nrequire File.expand_path('config/application', __dir__)\n\nDummyApp::Application.load_tasks\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/.gitkeep",
    "content": ""
  },
  {
    "path": "spec/dummy_app/app/active_record/abstract.rb",
    "content": "# frozen_string_literal: true\n\nclass Abstract < ActiveRecord::Base\n  self.abstract_class = true\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/another_field_test.rb",
    "content": "# frozen_string_literal: true\n\nclass AnotherFieldTest < ActiveRecord::Base\n  has_many :nested_field_tests, inverse_of: :another_field_test\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/ball.rb",
    "content": "# frozen_string_literal: true\n\nclass Ball < ActiveRecord::Base\n  has_one :comment, as: :commentable\n\n  validates_presence_of :color, on: :create\n\n  def to_param\n    color.present? ? color.downcase.tr(' ', '-') : id\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/carrierwave_uploader.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'mini_magick'\nclass CarrierwaveUploader < CarrierWave::Uploader::Base\n  # Include RMagick or ImageScience support:\n  # include CarrierWave::RMagick\n  include CarrierWave::MiniMagick\n  # include CarrierWave::ImageScience\n\n  # Choose what kind of storage to use for this uploader:\n  storage :file\n  # storage :fog\n\n  # Override the directory where uploaded files will be stored.\n  # This is a sensible default for uploaders that are meant to be mounted:\n  def store_dir\n    \"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}\"\n  end\n\n  version :thumb do\n    process resize_to_fill: [100, 100]\n  end\n\n  # Provide a default URL as a default if there hasn't been a file uploaded:\n  # def default_url\n  #   \"/images/fallback/\" + [version_name, \"default.png\"].compact.join('_')\n  # end\n\n  # Process files as they are uploaded:\n  # process scale: [200, 300]\n  #\n  # def scale(width, height)\n  #   # do something\n  # end\n\n  # Create different versions of your uploaded files:\n  # version :thumb do\n  #   process scale: [50, 50]\n  # end\n\n  # Add an allowlist of extensions which are allowed to be uploaded.\n  # For images you might use something like this:\n  # def extension_allowlist\n  #   %w(jpg jpeg gif png)\n  # end\n\n  # Override the filename of the uploaded files:\n  # Avoid using model.id or version_name here, see uploader/store.rb for details.\n  # def filename\n  #   \"something.jpg\" if original_filename\n  # end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/category.rb",
    "content": "# frozen_string_literal: true\n\nclass Category < ActiveRecord::Base\n  belongs_to :parent_category, class_name: 'Category', optional: true\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/cms/basic_page.rb",
    "content": "# frozen_string_literal: true\n\nmodule Cms\n  class BasicPage < ActiveRecord::Base\n    self.table_name = :cms_basic_pages\n\n    validates :title, :content, presence: true\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/cms.rb",
    "content": "# frozen_string_literal: true\n\nmodule Cms\n  def self.table_name_prefix\n    'cms_'\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/comment/confirmed.rb",
    "content": "# frozen_string_literal: true\n\nclass Comment\n  class Confirmed < Comment\n    default_scope { where(content: 'something') }\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/comment.rb",
    "content": "# frozen_string_literal: true\n\nclass Comment < ActiveRecord::Base\n  include Taggable\n  belongs_to :commentable, polymorphic: true, optional: true\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/concerns/taggable.rb",
    "content": "# frozen_string_literal: true\n\nmodule Taggable\n  extend ActiveSupport::Concern\n  # dummy\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/deeply_nested_field_test.rb",
    "content": "# frozen_string_literal: true\n\nclass DeeplyNestedFieldTest < ActiveRecord::Base\n  belongs_to :nested_field_test, inverse_of: :deeply_nested_field_tests\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/division.rb",
    "content": "# frozen_string_literal: true\n\nclass Division < ActiveRecord::Base\n  self.primary_key = :custom_id\n\n  belongs_to :league, foreign_key: 'custom_league_id', optional: true\n  has_many :teams\n\n  validates_numericality_of(:custom_league_id, only_integer: true)\n  validates_presence_of(:name)\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/draft.rb",
    "content": "# frozen_string_literal: true\n\nclass Draft < ActiveRecord::Base\n  belongs_to :team\n  belongs_to :player\n\n  validates_numericality_of(:player_id, only_integer: true)\n  validates_numericality_of(:team_id, only_integer: true)\n  validates_presence_of(:date)\n  validates_numericality_of(:round, only_integer: true)\n  validates_numericality_of(:pick, only_integer: true)\n  validates_numericality_of(:overall, only_integer: true)\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/fan.rb",
    "content": "# frozen_string_literal: true\n\nclass Fan < ActiveRecord::Base\n  has_and_belongs_to_many :teams\n\n  if ActiveRecord.gem_version >= Gem::Version.new('7.1') || defined?(CompositePrimaryKeys)\n    has_many :fanships, inverse_of: :fan\n    has_one :fanship, inverse_of: :fan\n  end\n\n  validates_presence_of(:name)\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/fanship.rb",
    "content": "# frozen_string_literal: true\n\nif ActiveRecord.gem_version >= Gem::Version.new('7.1') || defined?(CompositePrimaryKeys)\n  class Fanship < ActiveRecord::Base\n    self.table_name = :fans_teams\n    if defined?(CompositePrimaryKeys)\n      self.primary_keys = :fan_id, :team_id\n    else\n      self.primary_key = :fan_id, :team_id\n    end\n    if defined?(CompositePrimaryKeys) || ActiveRecord.gem_version >= Gem::Version.new('7.2')\n      has_many :favorite_players, foreign_key: %i[fan_id team_id], inverse_of: :fanship\n    else\n      has_many :favorite_players, query_constraints: %i[fan_id team_id], inverse_of: :fanship\n    end\n\n    belongs_to :fan, inverse_of: :fanships, optional: true\n    belongs_to :team, optional: true\n  end\nelse\n  class Fanship; end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/favorite_player.rb",
    "content": "# frozen_string_literal: true\n\nif ActiveRecord.gem_version >= Gem::Version.new('7.1') || defined?(CompositePrimaryKeys)\n  class FavoritePlayer < ActiveRecord::Base\n    if defined?(CompositePrimaryKeys)\n      self.primary_keys = :fan_id, :team_id, :player_id\n    else\n      self.primary_key = :fan_id, :team_id, :player_id\n    end\n    if defined?(CompositePrimaryKeys) || ActiveRecord.gem_version >= Gem::Version.new('7.2')\n      belongs_to :fanship, foreign_key: %i[fan_id team_id], inverse_of: :favorite_players\n    else\n      belongs_to :fanship, query_constraints: %i[fan_id team_id], inverse_of: :favorite_players\n    end\n\n    belongs_to :player\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/field_test.rb",
    "content": "# frozen_string_literal: true\n\nclass FieldTest < ActiveRecord::Base\n  has_many :nested_field_tests, dependent: :destroy, inverse_of: :field_test\n  accepts_nested_attributes_for :nested_field_tests, allow_destroy: true\n\n  has_one :comment, as: :commentable\n  accepts_nested_attributes_for :comment, allow_destroy: true\n\n  has_attached_file :paperclip_asset, styles: {thumb: '100x100>'}\n  attr_accessor :delete_paperclip_asset\n\n  before_validation { self.paperclip_asset = nil if delete_paperclip_asset == '1' }\n\n  ActiveRecord::Base.extend Dragonfly::Model\n  ActiveRecord::Base.extend Dragonfly::Model::Validations\n  dragonfly_accessor :dragonfly_asset\n\n  mount_uploader :carrierwave_asset, CarrierwaveUploader\n  mount_uploaders :carrierwave_assets, CarrierwaveUploader\n  if ActiveRecord.gem_version < Gem::Version.new('7.1')\n    serialize :carrierwave_assets, JSON\n  else\n    serialize :carrierwave_assets, coder: JSON\n  end\n\n  if defined?(ActiveStorage)\n    has_one_attached :active_storage_asset\n    attr_accessor :remove_active_storage_asset\n\n    after_save { active_storage_asset.purge if remove_active_storage_asset == '1' }\n\n    has_many_attached :active_storage_assets\n    attr_accessor :remove_active_storage_assets\n\n    after_save do\n      Array(remove_active_storage_assets).each { |id| active_storage_assets.find_by_id(id)&.purge }\n    end\n  end\n\n  include ShrineUploader.attachment(:shrine_asset)\n  include ShrineVersioningUploader.attachment(:shrine_versioning_asset)\n\n  has_rich_text :action_text_field if defined?(ActionText)\n\n  if ActiveRecord.gem_version >= Gem::Version.new('7.0')\n    enum :string_enum_field, {S: 's', M: 'm', L: 'l'}\n    enum :integer_enum_field, %i[small medium large]\n  else\n    enum string_enum_field: {S: 's', M: 'm', L: 'l'}\n    enum integer_enum_field: %i[small medium large]\n  end\n\n  validates :string_field, exclusion: {in: ['Invalid']} # to test file upload caching\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/hardball.rb",
    "content": "# frozen_string_literal: true\n\nclass Hardball < Ball\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/image.rb",
    "content": "# frozen_string_literal: true\n\nclass Image < ActiveRecord::Base\n  has_attached_file :file, styles: {medium: '300x300>', thumb: '100x100>'}\n  validates_attachment_presence :file\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/league.rb",
    "content": "# frozen_string_literal: true\n\nclass League < ActiveRecord::Base\n  has_many :divisions, foreign_key: 'custom_league_id'\n  has_many :teams, -> { readonly }, through: :divisions\n  has_many :players, through: :teams\n  has_one :division, foreign_key: 'custom_league_id'\n\n  validates_presence_of(:name)\n\n  def custom_name\n    \"League '#{name}'\"\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/managed_team.rb",
    "content": "# frozen_string_literal: true\n\nclass ManagedTeam < Team\n  belongs_to :user, class_name: 'ManagingUser', foreign_key: :manager, primary_key: :email, optional: true, inverse_of: :teams\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/managing_user.rb",
    "content": "# frozen_string_literal: true\n\nclass ManagingUser < User\n  has_one :team, class_name: 'ManagedTeam', foreign_key: :manager, primary_key: :email, inverse_of: :user\n  has_many :teams, class_name: 'ManagedTeam', foreign_key: :manager, primary_key: :email, inverse_of: :user\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/nested_fan.rb",
    "content": "# frozen_string_literal: true\n\nif ActiveRecord.gem_version >= Gem::Version.new('7.1') || defined?(CompositePrimaryKeys)\n  class NestedFan < Fan\n    accepts_nested_attributes_for :fanships\n    accepts_nested_attributes_for :fanship\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/nested_favorite_player.rb",
    "content": "# frozen_string_literal: true\n\nif ActiveRecord.gem_version >= Gem::Version.new('7.1') || defined?(CompositePrimaryKeys)\n  class NestedFavoritePlayer < FavoritePlayer\n    accepts_nested_attributes_for :fanship\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/nested_field_test.rb",
    "content": "# frozen_string_literal: true\n\nclass NestedFieldTest < ActiveRecord::Base\n  belongs_to :field_test, optional: true, inverse_of: :nested_field_tests\n  belongs_to :another_field_test, optional: true, inverse_of: :nested_field_tests\n  has_one :comment, as: :commentable\n  has_many :deeply_nested_field_tests, inverse_of: :nested_field_test\n  accepts_nested_attributes_for :comment, allow_destroy: true, reject_if: proc { |attributes| attributes['content'].blank? }\n  accepts_nested_attributes_for :deeply_nested_field_tests, allow_destroy: true\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/paper_trail_test/subclass_in_namespace.rb",
    "content": "# frozen_string_literal: true\n\nclass PaperTrailTest < ActiveRecord::Base\n  class SubclassInNamespace < self\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/paper_trail_test.rb",
    "content": "# frozen_string_literal: true\n\nclass PaperTrailTest < ActiveRecord::Base\n  has_paper_trail\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/paper_trail_test_subclass.rb",
    "content": "# frozen_string_literal: true\n\nclass PaperTrailTestSubclass < PaperTrailTest\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/paper_trail_test_with_custom_association.rb",
    "content": "# frozen_string_literal: true\n\nclass PaperTrailTestWithCustomAssociation < ActiveRecord::Base\n  self.table_name = :paper_trail_tests\n  has_paper_trail versions: {class_name: 'Trail'}\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/player.rb",
    "content": "# frozen_string_literal: true\n\nclass Player < ActiveRecord::Base\n  belongs_to :team, optional: true, inverse_of: :players\n  has_one :draft, dependent: :destroy\n  has_many :comments, as: :commentable\n\n  validates_presence_of(:name)\n  validates_numericality_of(:number, only_integer: true)\n  validates_uniqueness_of(:number, scope: :team_id, message: 'There is already a player with that number on this team')\n  validates_each :name do |record, _attr, value|\n    record.errors.add(:base, 'Player is cheating') if /on steroids/.match?(value.to_s)\n  end\n\n  if ActiveRecord.gem_version >= Gem::Version.new('7.0')\n    enum :formation, {start: 'start', substitute: 'substitute'}\n  else\n    enum formation: {start: 'start', substitute: 'substitute'}\n  end\n\n  before_destroy :destroy_hook\n\n  scope :rails_admin_search, ->(query) { where(name: query.reverse) }\n\n  def destroy_hook; end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/read_only_comment.rb",
    "content": "# frozen_string_literal: true\n\nclass ReadOnlyComment < Comment\n  def readonly?\n    true\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/restricted_team.rb",
    "content": "# frozen_string_literal: true\n\nclass RestrictedTeam < Team\n  has_many :players, foreign_key: :team_id, dependent: :restrict_with_error\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/shrine_uploader.rb",
    "content": "# frozen_string_literal: true\n\nclass ShrineUploader < Shrine\n  plugin :activerecord\n\n  plugin :cached_attachment_data\n  plugin :determine_mime_type\n  plugin :pretty_location\n  plugin :remove_attachment\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/shrine_versioning_uploader.rb",
    "content": "# frozen_string_literal: true\n\nclass ShrineVersioningUploader < Shrine\n  plugin :activerecord\n\n  plugin :cached_attachment_data\n  plugin :determine_mime_type\n  plugin :pretty_location\n  plugin :remove_attachment\n\n  if Gem.loaded_specs['shrine'].version >= Gem::Version.create('3')\n    plugin :derivatives\n\n    Attacher.derivatives_processor do |original|\n      {\n        thumb: FakeIO.new('', filename: File.basename(original.path), content_type: File.extname(original.path)),\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/team.rb",
    "content": "# frozen_string_literal: true\n\nclass Team < ActiveRecord::Base\n  has_many :players, -> { order :id }, inverse_of: :team\n  has_and_belongs_to_many :fans\n  has_many :comments, as: :commentable\n\n  validates_numericality_of :division_id, only_integer: true\n  validates_presence_of :manager\n  validates_numericality_of :founded, only_integer: true, allow_blank: true\n  validates_numericality_of :wins, only_integer: true\n  validates_numericality_of :losses, only_integer: true\n  validates_numericality_of :win_percentage\n  validates_numericality_of :revenue, allow_nil: true\n  belongs_to :division, optional: true\n\n  if ActiveRecord.gem_version >= Gem::Version.new('7.0')\n    enum :main_sponsor, %i[no_sponsor food_factory transportation_company bank energy_producer]\n  else\n    enum main_sponsor: %i[no_sponsor food_factory transportation_company bank energy_producer]\n  end\n\n  def player_names_truncated\n    players.collect(&:name).join(', ')[0..32]\n  end\n\n  def color_enum\n    ['white', 'black', 'red', 'green', 'blu<e>é']\n  end\n\n  scope :green, -> { where(color: 'red') }\n  scope :red, -> { where(color: 'red') }\n  scope :white, -> { where(color: 'white') }\n\n  rails_admin do\n    field :color, :color\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/trail.rb",
    "content": "# frozen_string_literal: true\n\nclass Trail < PaperTrail::Version\n  self.table_name = :custom_versions\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/two_level/namespaced/polymorphic_association_test.rb",
    "content": "# frozen_string_literal: true\n\nmodule TwoLevel\n  module Namespaced\n    class PolymorphicAssociationTest < ActiveRecord::Base\n      has_many :comments, as: :commentable\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/two_level/namespaced.rb",
    "content": "# frozen_string_literal: true\n\nmodule TwoLevel\n  module Namespaced\n    def self.table_name_prefix\n      'two_level_namespaced_'\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/user/confirmed.rb",
    "content": "# frozen_string_literal: true\n\nclass User\n  class Confirmed < User\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/user.rb",
    "content": "# frozen_string_literal: true\n\nclass User < ActiveRecord::Base\n  # Include default devise modules. Others available are:\n  # :token_authenticatable, :confirmable, :lockable and :timeoutable\n  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable\n\n  if ActiveRecord.gem_version < Gem::Version.new('7.1')\n    serialize :roles, Array\n  else\n    serialize :roles, coder: YAML, type: Array\n  end\n\n  # Add Paperclip support for avatars\n  has_attached_file :avatar, styles: {medium: '300x300>', thumb: '100x100>'}\n\n  attr_accessor :delete_avatar\n\n  before_validation { self.avatar = nil if delete_avatar == '1' }\n\n  def attr_accessible_role\n    :custom_role\n  end\n\n  def roles_enum\n    %i[admin user]\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/active_record/without_table.rb",
    "content": "# frozen_string_literal: true\n\nclass WithoutTable < ActiveRecord::Base\nend\n"
  },
  {
    "path": "spec/dummy_app/app/assets/builds/.keep",
    "content": ""
  },
  {
    "path": "spec/dummy_app/app/assets/config/manifest.js",
    "content": "//= link_tree ../images\n//= link_tree ../../../../../src .js\n//= link application.js\n//= link application.css\n"
  },
  {
    "path": "spec/dummy_app/app/assets/javascripts/application.js",
    "content": "// This is a manifest file that'll be compiled into application.js, which will include all the files\n// listed below.\n//\n// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,\n// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.\n//\n// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the\n// the compiled file.\n//\n// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD\n// GO AFTER THE REQUIRES BELOW.\n//\n//= require rails-ujs.esm\n//= require turbo\n"
  },
  {
    "path": "spec/dummy_app/app/assets/javascripts/rails-ujs.esm.js.erb",
    "content": "<%= depend_on_asset('rails-ujs').to_s.gsub(/context = this/, 'context = (this || globalThis)') %>"
  },
  {
    "path": "spec/dummy_app/app/assets/javascripts/rails_admin/custom/ui.js",
    "content": "window.domReadyTriggered = [];\n\ndocument.addEventListener(\"rails_admin.dom_ready\", function () {\n  window.domReadyTriggered.push(\"plainjs/dot\");\n});\n\n$(document).on(\"rails_admin.dom_ready\", function () {\n  window.domReadyTriggered.push(\"jquery/dot\");\n});\n"
  },
  {
    "path": "spec/dummy_app/app/assets/stylesheets/application.css",
    "content": "/*\n * This is a manifest file that'll be compiled into application.css, which will include all the files\n * listed below.\n *\n * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,\n * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.\n *\n * You're free to add application-wide styles to this file and they'll appear at the top of the\n * compiled file, but it's generally better to create a new file per style scope.\n *\n *= require_self\n*/\n"
  },
  {
    "path": "spec/dummy_app/app/assets/stylesheets/rails_admin/custom/theming.scss",
    "content": ".navbar-brand small {\n  opacity: 0.99;\n}\n"
  },
  {
    "path": "spec/dummy_app/app/assets/stylesheets/rails_admin.scss",
    "content": "$fa-font-path: \".\";\n@import \"rails_admin/src/rails_admin/styles/base.scss\";\n@import \"trix/dist/trix\";\n"
  },
  {
    "path": "spec/dummy_app/app/controllers/application_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass ApplicationController < ActionController::Base\n  protect_from_forgery\nend\n"
  },
  {
    "path": "spec/dummy_app/app/controllers/players_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass PlayersController < ApplicationController\n  def show\n    @player = Player.find(params[:id])\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/eager_loaded/basketball.rb",
    "content": "# frozen_string_literal: true\n\nclass Basketball < Ball\nend\n"
  },
  {
    "path": "spec/dummy_app/app/frontend/entrypoints/application.js",
    "content": "import \"@rails/ujs\";\nimport \"@hotwired/turbo-rails\";\n"
  },
  {
    "path": "spec/dummy_app/app/frontend/entrypoints/rails_admin.js",
    "content": "import \"~/stylesheets/rails_admin.scss\";\nimport \"rails_admin/src/rails_admin/base\";\nimport \"flatpickr/dist/l10n/fr.js\";\nimport \"trix\";\nimport \"@rails/actiontext\";\nimport * as ActiveStorage from \"@rails/activestorage\";\nActiveStorage.start();\n\nwindow.domReadyTriggered = [];\n\ndocument.addEventListener(\"rails_admin.dom_ready\", function () {\n  window.domReadyTriggered.push(\"plainjs/dot\");\n});\n\n$(document).on(\"rails_admin.dom_ready\", function () {\n  window.domReadyTriggered.push(\"jquery/dot\");\n});\n"
  },
  {
    "path": "spec/dummy_app/app/frontend/stylesheets/rails_admin.scss",
    "content": "$fa-font-path: \"@fortawesome/fontawesome-free/webfonts\";\n@import \"rails_admin/src/rails_admin/styles/base\";\n"
  },
  {
    "path": "spec/dummy_app/app/javascript/application.js",
    "content": "import Rails from \"@rails/ujs\";\nimport \"@hotwired/turbo-rails\";\n\nRails.start();\n"
  },
  {
    "path": "spec/dummy_app/app/javascript/rails_admin.js",
    "content": "import \"rails_admin/src/rails_admin/base\";\nimport \"flatpickr/dist/l10n/fr.js\";\nimport \"trix\";\nimport \"@rails/actiontext\";\nimport * as ActiveStorage from \"@rails/activestorage\";\nActiveStorage.start();\n\nwindow.domReadyTriggered = [];\n\ndocument.addEventListener(\"rails_admin.dom_ready\", function () {\n  window.domReadyTriggered.push(\"plainjs/dot\");\n});\n\n$(document).on(\"rails_admin.dom_ready\", function () {\n  window.domReadyTriggered.push(\"jquery/dot\");\n});\n"
  },
  {
    "path": "spec/dummy_app/app/javascript/rails_admin.scss",
    "content": "@import \"rails_admin/src/rails_admin/styles/base.scss\";\n"
  },
  {
    "path": "spec/dummy_app/app/jobs/application_job.rb",
    "content": "# frozen_string_literal: true\n\nclass ApplicationJob < ActiveJob::Base\n  # Automatically retry jobs that encountered a deadlock\n  # retry_on ActiveRecord::Deadlocked\n\n  # Most jobs are safe to ignore if the underlying records are no longer available\n  # discard_on ActiveJob::DeserializationError\nend\n"
  },
  {
    "path": "spec/dummy_app/app/jobs/null_job.rb",
    "content": "# frozen_string_literal: true\n\nclass NullJob < ApplicationJob\n  queue_as :default\n\n  def perform(*args)\n    # Do nothing\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/locales/models.en.yml",
    "content": "en:\n  activerecord: &en_attributes\n    attributes:\n      fan:\n        name: Their Name\n      team:\n        manager: Team Manager\n        main_sponsor: Main Sponsor\n        fans: Some Fans\n  mongoid: *en_attributes\nfr:\n  activerecord: &fr_attributes\n    attributes:\n      fan:\n        name: Son nom\n      team:\n        manager: Manager de l'équipe\n        fans: Quelques fans\n  mongoid: *fr_attributes\n"
  },
  {
    "path": "spec/dummy_app/app/mailers/.gitkeep",
    "content": ""
  },
  {
    "path": "spec/dummy_app/app/mongoid/another_field_test.rb",
    "content": "# frozen_string_literal: true\n\nclass AnotherFieldTest\n  include Mongoid::Document\n\n  has_many :nested_field_tests, inverse_of: :another_field_test\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/ball.rb",
    "content": "# frozen_string_literal: true\n\nclass Ball\n  include Mongoid::Document\n  include Mongoid::Timestamps\n\n  field :color, type: String\n\n  has_one :comment, as: :commentable\n\n  validates_presence_of :color, on: :create\n\n  def to_param\n    color.present? ? color.downcase.tr(' ', '-') : id\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/carrierwave_uploader.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'mini_magick'\nclass CarrierwaveUploader < CarrierWave::Uploader::Base\n  # Include RMagick or ImageScience support:\n  # include CarrierWave::RMagick\n  include CarrierWave::MiniMagick\n  # include CarrierWave::ImageScience\n\n  # Choose what kind of storage to use for this uploader:\n  storage :file\n  # storage :fog\n\n  # Override the directory where uploaded files will be stored.\n  # This is a sensible default for uploaders that are meant to be mounted:\n  def store_dir\n    \"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}\"\n  end\n\n  version :thumb do\n    process resize_to_fill: [100, 100]\n  end\n\n  # Provide a default URL as a default if there hasn't been a file uploaded:\n  # def default_url\n  #   \"/images/fallback/\" + [version_name, \"default.png\"].compact.join('_')\n  # end\n\n  # Process files as they are uploaded:\n  # process scale: [200, 300]\n  #\n  # def scale(width, height)\n  #   # do something\n  # end\n\n  # Create different versions of your uploaded files:\n  # version :thumb do\n  #   process scale: [50, 50]\n  # end\n\n  # Add an allowlist of extensions which are allowed to be uploaded.\n  # For images you might use something like this:\n  # def extension_allowlist\n  #   %w(jpg jpeg gif png)\n  # end\n\n  # Override the filename of the uploaded files:\n  # Avoid using model.id or version_name here, see uploader/store.rb for details.\n  # def filename\n  #   \"something.jpg\" if original_filename\n  # end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/category.rb",
    "content": "# frozen_string_literal: true\n\nclass Category\n  include Mongoid::Document\n\n  belongs_to :parent_category, class_name: 'Category'\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/cms/basic_page.rb",
    "content": "# frozen_string_literal: true\n\nmodule Cms\n  class BasicPage\n    include Mongoid::Document\n    field :title, type: String\n    field :content, type: String\n    include Mongoid::Timestamps\n\n    validates :title, :content, presence: true\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/cms.rb",
    "content": "# frozen_string_literal: true\n\nmodule Cms\n  def self.table_name_prefix\n    'cms_'\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/comment/confirmed.rb",
    "content": "# frozen_string_literal: true\n\nclass Comment\n  class Confirmed < Comment\n    default_scope -> { where(content: 'something') }\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/comment.rb",
    "content": "# frozen_string_literal: true\n\nclass Comment\n  include Mongoid::Document\n  field :content, type: String\n  include Mongoid::Timestamps\n  include Taggable\n\n  belongs_to :commentable, polymorphic: true\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/concerns/taggable.rb",
    "content": "# frozen_string_literal: true\n\nmodule Taggable\n  extend ActiveSupport::Concern\n  # dummy\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/deeply_nested_field_test.rb",
    "content": "# frozen_string_literal: true\n\nclass DeeplyNestedFieldTest\n  include Mongoid::Document\n  include Mongoid::Timestamps\n\n  field :title, type: String\n  belongs_to :nested_field_test, inverse_of: :deeply_nested_field_tests\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/division.rb",
    "content": "# frozen_string_literal: true\n\nclass Division\n  include Mongoid::Document\n  include Mongoid::Timestamps\n\n  field :name, type: String\n\n  belongs_to :league, foreign_key: 'custom_league_id'\n  has_many :teams\n\n  validates_presence_of(:custom_league_id)\n  validates_presence_of(:name)\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/draft.rb",
    "content": "# frozen_string_literal: true\n\nclass Draft\n  include Mongoid::Document\n  include Mongoid::Timestamps\n\n  belongs_to :player\n  belongs_to :team\n  field :date, type: Date\n  field :round, type: Integer\n  field :pick, type: Integer\n  field :overall, type: Integer\n  field :college, type: String\n  field :notes, type: String\n\n  validates_presence_of(:player_id, only_integer: true)\n  validates_presence_of(:team_id, only_integer: true)\n  validates_presence_of(:date)\n  validates_numericality_of(:round, only_integer: true)\n  validates_numericality_of(:pick, only_integer: true)\n  validates_numericality_of(:overall, only_integer: true)\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/embed.rb",
    "content": "# frozen_string_literal: true\n\nclass Embed\n  include Mongoid::Document\n  field :name, type: String\n\n  embedded_in :field_test\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/fan.rb",
    "content": "# frozen_string_literal: true\n\nclass Fan\n  include Mongoid::Document\n  include Mongoid::Timestamps\n\n  field :name, type: String\n\n  has_and_belongs_to_many :teams\n\n  validates_presence_of(:name)\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/field_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/adapters/mongoid'\n\nclass FieldTest\n  include Mongoid::Document\n  include Mongoid::Paperclip\n  include ActiveModel::ForbiddenAttributesProtection\n  extend Dragonfly::Model\n\n  field :name, type: String\n  field :title, type: String\n  field :subject, type: String\n  field :short_text, type: String\n\n  field :array_field, type: Array\n  field :big_decimal_field, type: BigDecimal\n  field :boolean_field, type: Boolean\n  field :bson_object_id_field, type: RailsAdmin::Adapters::Mongoid::Bson::OBJECT_ID\n  field :bson_binary_field, type: BSON::Binary\n  field :date_field, type: Date\n  field :datetime_field, type: DateTime\n  field :time_with_zone_field, type: ActiveSupport::TimeWithZone\n  field :default_field\n  field :float_field, type: Float\n  field :hash_field, type: Hash\n  field :integer_field, type: Integer\n  field :object_field, type: Object\n  field :range_field, type: Range\n  field :string_field, type: String\n  field :symbol_field, type: Symbol\n  field :text_field, type: String\n  field :time_field, type: Time\n\n  field :format, type: String\n  field :open, type: Boolean\n  field :restricted_field, type: String\n  field :protected_field, type: String\n  field :al, as: :aliased_field, type: String\n  has_mongoid_attached_file :paperclip_asset, styles: {thumb: '100x100>'}\n\n  field :shrine_asset_data, type: String\n  include ShrineUploader::Attachment.new(:shrine_asset)\n  field :shrine_versioning_asset_data, type: String\n  include ShrineVersioningUploader::Attachment.new(:shrine_versioning_asset)\n\n  has_many :nested_field_tests, dependent: :destroy, inverse_of: :field_test, autosave: true\n  accepts_nested_attributes_for :nested_field_tests, allow_destroy: true\n\n  # on creation, comment is not saved without autosave: true\n  has_one :comment, as: :commentable, autosave: true\n  accepts_nested_attributes_for :comment, allow_destroy: true\n\n  embeds_many :embeds\n  accepts_nested_attributes_for :embeds, allow_destroy: true\n\n  attr_accessor :delete_paperclip_asset\n\n  before_validation { self.paperclip_asset = nil if delete_paperclip_asset == '1' }\n\n  field :dragonfly_asset_name\n  field :dragonfly_asset_uid\n  dragonfly_accessor :dragonfly_asset\n\n  mount_uploader :carrierwave_asset, CarrierwaveUploader\n  # carrierwave-mongoid does not support mount_uploaders yet:\n  #   https://github.com/carrierwaveuploader/carrierwave-mongoid/issues/138\n  mount_uploaders :carrierwave_assets, CarrierwaveUploader\n\n  validates :short_text, length: {maximum: 255}\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/hardball.rb",
    "content": "# frozen_string_literal: true\n\nclass Hardball < Ball\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/image.rb",
    "content": "# frozen_string_literal: true\n\nclass Image\n  include Mongoid::Document\n  include Mongoid::Paperclip\n\n  has_mongoid_attached_file :file, styles: {medium: '300x300>', thumb: '100x100>'}\n  validates_attachment_presence :file\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/league.rb",
    "content": "# frozen_string_literal: true\n\nclass League\n  include Mongoid::Document\n\n  field :name, type: String\n  include Mongoid::Timestamps\n\n  has_many :divisions, foreign_key: 'custom_league_id'\n\n  validates_presence_of(:name)\n\n  def custom_name\n    \"League '#{name}'\"\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/managed_team.rb",
    "content": "# frozen_string_literal: true\n\nclass ManagedTeam < Team\n  belongs_to :user, class_name: 'ManagingUser', foreign_key: :manager, primary_key: :email, inverse_of: :teams\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/managing_user.rb",
    "content": "# frozen_string_literal: true\n\nclass ManagingUser < User\n  has_one :team, class_name: 'ManagedTeam', foreign_key: :manager, primary_key: :email, inverse_of: :user\n  has_many :teams, class_name: 'ManagedTeam', foreign_key: :manager, primary_key: :email, inverse_of: :user\n  has_and_belongs_to_many :players, foreign_key: :player_names, primary_key: :name, inverse_of: :nil\n  has_and_belongs_to_many :balls, primary_key: :color, inverse_of: :nil\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/nested_field_test.rb",
    "content": "# frozen_string_literal: true\n\nclass NestedFieldTest\n  include Mongoid::Document\n\n  field :title, type: String\n  belongs_to :field_test, inverse_of: :nested_field_tests\n  belongs_to :another_field_test, inverse_of: :nested_field_tests\n  include Mongoid::Timestamps\n\n  has_many :deeply_nested_field_tests, inverse_of: :nested_field_test\n  accepts_nested_attributes_for :deeply_nested_field_tests, allow_destroy: true\n  has_one :comment, as: :commentable, autosave: true\n  accepts_nested_attributes_for :comment, allow_destroy: true, reject_if: proc { |attributes| attributes['content'].blank? }\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/player.rb",
    "content": "# frozen_string_literal: true\n\nclass Player\n  include Mongoid::Document\n  include Mongoid::Timestamps\n  include ActiveModel::ForbiddenAttributesProtection\n\n  field :deleted_at, type: DateTime\n  belongs_to :team, inverse_of: :players\n  field :name, type: String\n  field :position, type: String\n  field :number, type: Integer\n  field :retired, type: Boolean, default: false\n  field :injured, type: Boolean, default: false\n  field :born_on, type: Date\n  field :notes, type: String\n  field :suspended, type: Boolean, default: false\n  field :formation, type: String\n\n  validates_presence_of(:name)\n  validates_numericality_of(:number, only_integer: true)\n  validates_uniqueness_of(:number, scope: :team_id, message: 'There is already a player with that number on this team')\n\n  validates_each :name do |record, _attr, value|\n    record.errors.add(:base, 'Player is cheating') if /on steroids/.match?(value.to_s)\n  end\n\n  has_one :draft, dependent: :destroy\n  has_many :comments, as: :commentable\n\n  before_destroy :destroy_hook\n\n  scope :rails_admin_search, ->(query) { where(name: query.reverse) }\n\n  def destroy_hook; end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/read_only_comment.rb",
    "content": "# frozen_string_literal: true\n\nclass ReadOnlyComment < Comment\n  def readonly?\n    true\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/restricted_team.rb",
    "content": "# frozen_string_literal: true\n\nclass RestrictedTeam < Team\n  has_many :players, foreign_key: :team_id, dependent: :restrict_with_error\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/shrine_uploader.rb",
    "content": "# frozen_string_literal: true\n\nclass ShrineUploader < Shrine\n  plugin :mongoid\n\n  plugin :cached_attachment_data\n  plugin :determine_mime_type\n  plugin :pretty_location\n  plugin :remove_attachment\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/shrine_versioning_uploader.rb",
    "content": "# frozen_string_literal: true\n\nclass ShrineVersioningUploader < Shrine\n  plugin :mongoid\n\n  plugin :cached_attachment_data\n  plugin :determine_mime_type\n  plugin :pretty_location\n  plugin :remove_attachment\n\n  if Gem.loaded_specs['shrine'].version >= Gem::Version.create('3')\n    plugin :derivatives\n\n    Attacher.derivatives_processor do |original|\n      {\n        thumb: FakeIO.new('', filename: File.basename(original.path), content_type: File.extname(original.path)),\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/team.rb",
    "content": "# frozen_string_literal: true\n\nclass Team\n  include Mongoid::Document\n  include Mongoid::Timestamps\n\n  belongs_to :division\n  field :name, type: String\n  field :logo_url, type: String\n  field :manager, type: String\n  field :ballpark, type: String\n  field :mascot, type: String\n  field :founded, type: Integer\n  field :wins, type: Integer\n  field :losses, type: Integer\n  field :win_percentage, type: Float\n  field :revenue, type: BigDecimal\n  field :color, type: String\n  field :custom_field, type: String\n  field :main_sponsor, type: Integer\n\n  has_many :players, inverse_of: :team, order: :_id.asc\n  has_and_belongs_to_many :fans\n  has_many :comments, as: :commentable\n\n  validates_presence_of :division_id, only_integer: true\n  validates_presence_of :manager\n  validates_numericality_of :founded, only_integer: true, allow_blank: true\n  validates_numericality_of :wins, only_integer: true\n  validates_numericality_of :losses, only_integer: true\n  validates_numericality_of :win_percentage\n  validates_numericality_of :revenue, allow_nil: true\n  # needed to force these attributes to :string type\n  validates_length_of :logo_url, maximum: 255\n  validates_length_of :manager, maximum: 100\n  validates_length_of :ballpark, maximum: 100\n  validates_length_of :mascot, maximum: 100\n\n  def player_names_truncated\n    players.collect(&:name).join(', ')[0..32]\n  end\n\n  def color_enum\n    ['white', 'black', 'red', 'green', 'blu<e>é']\n  end\n\n  scope :green, -> { where(color: 'red') }\n  scope :red, -> { where(color: 'red') }\n  scope :white, -> { where(color: 'white') }\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/two_level/namespaced/polymorphic_association_test.rb",
    "content": "# frozen_string_literal: true\n\nmodule TwoLevel\n  module Namespaced\n    class PolymorphicAssociationTest\n      include Mongoid::Document\n\n      field :name, type: String\n\n      has_many :comments, as: :commentable\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/user/confirmed.rb",
    "content": "# frozen_string_literal: true\n\nclass User\n  class Confirmed < User\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/app/mongoid/user.rb",
    "content": "# frozen_string_literal: true\n\nclass User\n  include Mongoid::Document\n  include Mongoid::Paperclip\n  include ActiveModel::ForbiddenAttributesProtection\n  # Include default devise modules. Others available are:\n  # :token_authenticatable, :confirmable, :lockable and :timeoutable\n  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable\n\n  ## Database authenticatable\n  field :email,              type: String\n  field :encrypted_password, type: String\n\n  ## Recoverable\n  field :reset_password_token,   type: String\n  field :reset_password_sent_at, type: Time\n\n  ## Rememberable\n  field :remember_created_at, type: Time\n\n  ## Trackable\n  field :sign_in_count,      type: Integer\n  field :current_sign_in_at, type: Time\n  field :last_sign_in_at,    type: Time\n  field :current_sign_in_ip, type: String\n  field :last_sign_in_ip,    type: String\n\n  ## Encryptable\n  # field :password_salt, type: String\n\n  ## Confirmable\n  # field :confirmation_token,   type: String\n  # field :confirmed_at,         type: Time\n  # field :confirmation_sent_at, type: Time\n  # field :unconfirmed_email,    type: String # Only if using reconfirmable\n\n  ## Lockable\n  # field :failed_attempts, type: Integer # Only if lock strategy is :failed_attempts\n  # field :unlock_token,    type: String # Only if unlock strategy is :email or :both\n  # field :locked_at,       type: Time\n\n  # Token authenticatable\n  # field :authentication_token, type: String\n\n  ## Invitable\n  # field :invitation_token, type: String\n\n  include Mongoid::Timestamps\n\n  # Add Paperclip support for avatars\n  has_mongoid_attached_file :avatar, styles: {medium: '300x300>', thumb: '100x100>'}\n\n  field :roles, type: Array\n\n  def attr_accessible_role\n    :custom_role\n  end\n\n  attr_accessor :delete_avatar\n\n  before_validation { self.avatar = nil if delete_avatar == '1' }\nend\n"
  },
  {
    "path": "spec/dummy_app/app/views/layouts/application.html.erb",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <title>DummyApp</title>\n  <% case CI_ASSET %>\n  <% when :webpacker %>\n    <%= javascript_pack_tag \"application\" %>\n  <% when :importmap %>\n    <%= javascript_importmap_tags %>\n  <% when :vite %>\n    <%= vite_client_tag %>\n    <%= vite_javascript_tag 'application' %>\n  <% else %>\n    <%= stylesheet_link_tag    \"application\", media: \"all\" %>\n    <%= javascript_include_tag \"application\", type: 'module' %>\n  <% end %>\n  <%= csrf_meta_tags %>\n</head>\n<body>\n\n<%= yield %>\n\n</body>\n</html>\n"
  },
  {
    "path": "spec/dummy_app/app/views/players/show.html.erb",
    "content": "<h1><%= @player.name %></h1>\n<%= link_to 'Back to admin', rails_admin.show_path(model_name: 'player', id: @player.id)  %>"
  },
  {
    "path": "spec/dummy_app/babel.config.js",
    "content": "module.exports = function (api) {\n  var validEnv = [\"development\", \"test\", \"production\"];\n  var currentEnv = api.env();\n  var isDevelopmentEnv = api.env(\"development\");\n  var isProductionEnv = api.env(\"production\");\n  var isTestEnv = api.env(\"test\");\n\n  if (!validEnv.includes(currentEnv)) {\n    throw new Error(\n      \"Please specify a valid `NODE_ENV` or \" +\n        '`BABEL_ENV` environment variables. Valid values are \"development\", ' +\n        '\"test\", and \"production\". Instead, received: ' +\n        JSON.stringify(currentEnv) +\n        \".\"\n    );\n  }\n\n  return {\n    presets: [\n      isTestEnv && [\n        \"@babel/preset-env\",\n        {\n          targets: {\n            node: \"current\",\n          },\n        },\n      ],\n      (isProductionEnv || isDevelopmentEnv) && [\n        \"@babel/preset-env\",\n        {\n          forceAllTransforms: true,\n          useBuiltIns: \"entry\",\n          corejs: 3,\n          modules: false,\n          exclude: [\"transform-typeof-symbol\"],\n        },\n      ],\n    ].filter(Boolean),\n    plugins: [\n      \"babel-plugin-macros\",\n      \"@babel/plugin-syntax-dynamic-import\",\n      isTestEnv && \"babel-plugin-dynamic-import-node\",\n      \"@babel/plugin-transform-destructuring\",\n      [\n        \"@babel/plugin-proposal-class-properties\",\n        {\n          loose: true,\n        },\n      ],\n      [\n        \"@babel/plugin-proposal-object-rest-spread\",\n        {\n          useBuiltIns: true,\n        },\n      ],\n      [\n        \"@babel/plugin-proposal-private-methods\",\n        {\n          loose: true,\n        },\n      ],\n      [\n        \"@babel/plugin-proposal-private-property-in-object\",\n        {\n          loose: true,\n        },\n      ],\n      [\n        \"@babel/plugin-transform-runtime\",\n        {\n          helpers: false,\n        },\n      ],\n      [\n        \"@babel/plugin-transform-regenerator\",\n        {\n          async: false,\n        },\n      ],\n    ].filter(Boolean),\n  };\n};\n"
  },
  {
    "path": "spec/dummy_app/bin/bundle",
    "content": "#!/usr/bin/env ruby\n# frozen_string_literal: true\n\n#\n# This file was generated by Bundler.\n#\n# The application 'bundle' is installed as part of a gem, and\n# this file is here to facilitate running it.\n#\n\nrequire \"rubygems\"\n\nm = Module.new do\n  module_function\n\n  def invoked_as_script?\n    File.expand_path($0) == File.expand_path(__FILE__)\n  end\n\n  def env_var_version\n    ENV[\"BUNDLER_VERSION\"]\n  end\n\n  def cli_arg_version\n    return unless invoked_as_script? # don't want to hijack other binstubs\n    return unless \"update\".start_with?(ARGV.first || \" \") # must be running `bundle update`\n    bundler_version = nil\n    update_index = nil\n    ARGV.each_with_index do |a, i|\n      if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN\n        bundler_version = a\n      end\n      next unless a =~ /\\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\\z/\n      bundler_version = $1\n      update_index = i\n    end\n    bundler_version\n  end\n\n  def gemfile\n    gemfile = ENV[\"BUNDLE_GEMFILE\"]\n    return gemfile if gemfile && !gemfile.empty?\n\n    File.expand_path(\"../Gemfile\", __dir__)\n  end\n\n  def lockfile\n    lockfile =\n      case File.basename(gemfile)\n      when \"gems.rb\" then gemfile.sub(/\\.rb$/, gemfile)\n      else \"#{gemfile}.lock\"\n      end\n    File.expand_path(lockfile)\n  end\n\n  def lockfile_version\n    return unless File.file?(lockfile)\n    lockfile_contents = File.read(lockfile)\n    return unless lockfile_contents =~ /\\n\\nBUNDLED WITH\\n\\s{2,}(#{Gem::Version::VERSION_PATTERN})\\n/\n    Regexp.last_match(1)\n  end\n\n  def bundler_requirement\n    @bundler_requirement ||=\n      env_var_version || cli_arg_version ||\n        bundler_requirement_for(lockfile_version)\n  end\n\n  def bundler_requirement_for(version)\n    return \"#{Gem::Requirement.default}.a\" unless version\n\n    bundler_gem_version = Gem::Version.new(version)\n\n    requirement = bundler_gem_version.approximate_recommendation\n\n    return requirement unless Gem.rubygems_version < Gem::Version.new(\"2.7.0\")\n\n    requirement += \".a\" if bundler_gem_version.prerelease?\n\n    requirement\n  end\n\n  def load_bundler!\n    ENV[\"BUNDLE_GEMFILE\"] ||= gemfile\n\n    activate_bundler\n  end\n\n  def activate_bundler\n    gem_error = activation_error_handling do\n      gem \"bundler\", bundler_requirement\n    end\n    return if gem_error.nil?\n    require_error = activation_error_handling do\n      require \"bundler/version\"\n    end\n    return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))\n    warn \"Activating bundler (#{bundler_requirement}) failed:\\n#{gem_error.message}\\n\\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`\"\n    exit 42\n  end\n\n  def activation_error_handling\n    yield\n    nil\n  rescue StandardError, LoadError => e\n    e\n  end\nend\n\nm.load_bundler!\n\nif m.invoked_as_script?\n  load Gem.bin_path(\"bundler\", \"bundle\")\nend\n"
  },
  {
    "path": "spec/dummy_app/bin/dev",
    "content": "#!/usr/bin/env bash\n\nif ! command -v foreman &> /dev/null\nthen\n  echo \"Installing foreman...\"\n  gem install foreman\nfi\n\nforeman start -f Procfile.dev \"$@\"\n"
  },
  {
    "path": "spec/dummy_app/bin/docker-entrypoint",
    "content": "#!/bin/bash -e\n\nexec \"${@}\"\n"
  },
  {
    "path": "spec/dummy_app/bin/importmap",
    "content": "#!/usr/bin/env ruby\n\nrequire_relative \"../config/application\"\nrequire \"importmap/commands\"\n"
  },
  {
    "path": "spec/dummy_app/bin/rails",
    "content": "#!/usr/bin/env ruby\nAPP_PATH = File.expand_path('../../config/application', __FILE__)\nrequire_relative '../config/boot'\nrequire 'rails/commands'\n"
  },
  {
    "path": "spec/dummy_app/bin/rake",
    "content": "#!/usr/bin/env ruby\nrequire_relative '../config/boot'\nrequire 'rake'\nRake.application.run\n"
  },
  {
    "path": "spec/dummy_app/bin/setup",
    "content": "#!/usr/bin/env ruby\nrequire 'pathname'\nrequire 'fileutils'\ninclude FileUtils\n\n# path to your application root.\nAPP_ROOT = Pathname.new File.expand_path('../../', __FILE__)\n\ndef system!(*args)\n  system(*args) || abort(\"\\n== Command #{args} failed ==\")\nend\n\nchdir APP_ROOT do\n  # This script is a starting point to setup your application.\n  # Add necessary setup steps to this file.\n\n  puts '== Installing dependencies =='\n  system! 'gem install bundler --conservative'\n  system('bundle check') or system!('bundle install')\n\n  # puts \"\\n== Copying sample files ==\"\n  # unless File.exist?('config/database.yml')\n  #   cp 'config/database.yml.sample', 'config/database.yml'\n  # end\n\n  puts \"\\n== Preparing database ==\"\n  system! 'bin/rails db:setup'\n\n  puts \"\\n== Removing old logs and tempfiles ==\"\n  system! 'bin/rails log:clear tmp:clear'\n\n  puts \"\\n== Restarting application server ==\"\n  system! 'bin/rails restart'\nend\n"
  },
  {
    "path": "spec/dummy_app/bin/update",
    "content": "#!/usr/bin/env ruby\nrequire 'pathname'\nrequire 'fileutils'\ninclude FileUtils\n\n# path to your application root.\nAPP_ROOT = Pathname.new File.expand_path('../../', __FILE__)\n\ndef system!(*args)\n  system(*args) || abort(\"\\n== Command #{args} failed ==\")\nend\n\nchdir APP_ROOT do\n  # This script is a way to update your development environment automatically.\n  # Add necessary update steps to this file.\n\n  puts '== Installing dependencies =='\n  system! 'gem install bundler --conservative'\n  system 'bundle check' or system! 'bundle install'\n\n  puts \"\\n== Updating database ==\"\n  system! 'bin/rails db:migrate'\n\n  puts \"\\n== Removing old logs and tempfiles ==\"\n  system! 'bin/rails log:clear tmp:clear'\n\n  puts \"\\n== Restarting application server ==\"\n  system! 'bin/rails restart'\nend\n"
  },
  {
    "path": "spec/dummy_app/bin/vite",
    "content": "#!/usr/bin/env ruby\n# frozen_string_literal: true\n\n#\n# This file was generated by Bundler.\n#\n# The application 'vite' is installed as part of a gem, and\n# this file is here to facilitate running it.\n#\n\nENV[\"BUNDLE_GEMFILE\"] ||= File.expand_path(\"../Gemfile\", __dir__)\n\nbundle_binstub = File.expand_path(\"bundle\", __dir__)\n\nif File.file?(bundle_binstub)\n  if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/\n    load(bundle_binstub)\n  else\n    abort(\"Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.\nReplace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.\")\n  end\nend\n\nrequire \"rubygems\"\nrequire \"bundler/setup\"\n\nload Gem.bin_path(\"vite_ruby\", \"vite\")\n"
  },
  {
    "path": "spec/dummy_app/bin/webpack",
    "content": "#!/usr/bin/env ruby\n\nENV[\"RAILS_ENV\"] ||= ENV[\"RACK_ENV\"] || \"development\"\nENV[\"NODE_ENV\"]  ||= \"development\"\n\nrequire \"pathname\"\nENV[\"BUNDLE_GEMFILE\"] ||= File.expand_path(\"../../Gemfile\",\n  Pathname.new(__FILE__).realpath)\n\nrequire \"bundler/setup\"\n\nrequire \"webpacker\"\nrequire \"webpacker/webpack_runner\"\n\nAPP_ROOT = File.expand_path(\"..\", __dir__)\nDir.chdir(APP_ROOT) do\n  Webpacker::WebpackRunner.run(ARGV)\nend\n"
  },
  {
    "path": "spec/dummy_app/bin/webpack-dev-server",
    "content": "#!/usr/bin/env ruby\n\nENV[\"RAILS_ENV\"] ||= ENV[\"RACK_ENV\"] || \"development\"\nENV[\"NODE_ENV\"]  ||= \"development\"\n\nrequire \"pathname\"\nENV[\"BUNDLE_GEMFILE\"] ||= File.expand_path(\"../../Gemfile\",\n  Pathname.new(__FILE__).realpath)\n\nrequire \"bundler/setup\"\n\nrequire \"webpacker\"\nrequire \"webpacker/dev_server_runner\"\n\nAPP_ROOT = File.expand_path(\"..\", __dir__)\nDir.chdir(APP_ROOT) do\n  Webpacker::DevServerRunner.run(ARGV)\nend\n"
  },
  {
    "path": "spec/dummy_app/config/application.rb",
    "content": "# frozen_string_literal: true\n\nrequire File.expand_path('boot', __dir__)\n\nrequire 'action_controller/railtie'\nrequire 'action_mailer/railtie'\n\nbegin\n  require CI_ORM.to_s\n  require \"#{CI_ORM}/railtie\"\nrescue LoadError\n  # ignore errors\nend\n\nrequire 'active_storage/engine' if CI_ORM == :active_record\nrequire 'action_text/engine' if CI_ORM == :active_record\n\ncase CI_ASSET\nwhen :webpacker\n  require 'webpacker'\nwhen :sprockets, :webpack\n  require 'sprockets/railtie'\nwhen :importmap\n  require 'sprockets/railtie'\n  require 'importmap-rails'\nwhen :vite\n  require 'vite_rails'\nend\n\n# Require the gems listed in Gemfile, including any gems\n# you've limited to :test, :development, or :production.\nBundler.require(*Rails.groups, CI_ORM)\n\nmodule DummyApp\n  class Application < Rails::Application\n    # Settings in config/environments/* take precedence over those specified here.\n    # Application configuration should go into files in config/initializers\n    # -- all .rb files in that directory are automatically loaded.\n    config.load_defaults Rails.version[0, 3]\n    (CI_TARGET_ORMS - [CI_ORM]).each { |orm| config.paths.add \"app/#{orm}\", eager_load: false }\n    config.eager_load_paths = (config.try(:all_eager_load_paths) || config.eager_load_paths).reject { |p| p =~ %r{/app/([^/]+)} && !%W[controllers jobs locales mailers #{CI_ORM}].include?(Regexp.last_match[1]) }\n    config.eager_load_paths += %W[#{config.root}/app/eager_loaded]\n    config.autoload_paths += %W[#{config.root}/lib]\n    config.i18n.load_path += Dir[Rails.root.join('app', 'locales', '*.{rb,yml}').to_s]\n    if CI_ORM == :active_record\n      config.active_record.time_zone_aware_types = %i[datetime time]\n      config.active_record.yaml_column_permitted_classes = [Symbol] if [ActiveRecord::Base, ActiveRecord].any? { |klass| klass.respond_to?(:yaml_column_permitted_classes=) }\n    end\n    config.active_storage.service = :local if defined?(ActiveStorage)\n    config.active_storage.replace_on_assign_to_many = false if defined?(ActiveStorage) && ActiveStorage.version < Gem::Version.create('6.1')\n\n    case CI_ASSET\n    when :webpack\n      config.assets.precompile += %w[rails_admin.js rails_admin.css]\n    when :importmap\n      config.assets.paths << RailsAdmin::Engine.root.join('src')\n      config.assets.precompile += %w[rails_admin.js rails_admin.css]\n      config.importmap.cache_sweepers << RailsAdmin::Engine.root.join('src')\n    end\n\n    initializer :ignore_unused_assets_path, after: :append_assets_path, group: :all do |app|\n      case CI_ASSET\n      when :webpack, :importmap\n        app.config.assets.paths.delete(Rails.root.join('app', 'assets', 'javascripts').to_s)\n      when :sprockets\n        app.config.assets.paths.delete(Rails.root.join('app', 'assets', 'builds').to_s)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/config/boot.rb",
    "content": "# frozen_string_literal: true\n\nCI_ORM = (ENV['CI_ORM'] || :active_record).to_sym unless defined?(CI_ORM)\nCI_TARGET_ORMS = %i[active_record mongoid].freeze\nCI_ASSET = (ENV['CI_ASSET'] || :sprockets).to_sym unless defined?(CI_ASSET)\nENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)\n\nrequire 'bundler/setup' # Set up gems listed in the Gemfile.\n"
  },
  {
    "path": "spec/dummy_app/config/database.yml",
    "content": "sqlite: &sqlite\n  adapter: sqlite3\n  pool: 5\n  timeout: 5000\n\npostgresql:\n  adapter: postgresql\n  database: rails_admin\n  username: postgres\n  password:\n  host: 127.0.0.1\n  encoding: utf8\n  pool: 5\n  timeout: 5000\n\nmysql:\n  adapter: mysql2\n  database: rails_admin\n  username: root\n  password:\n  host: 127.0.0.1\n  encoding: utf8\n  pool: 5\n  timeout: 5000\n\ndevelopment:\n  <<: *sqlite\n  database: db/development.sqlite3\n\ntest:\n  <<: *sqlite\n  database: db/test.sqlite3\n\nproduction:\n  <<: *sqlite\n  database: db/production.sqlite3\n"
  },
  {
    "path": "spec/dummy_app/config/dockerfile.yml",
    "content": "# generated by dockerfile-rails\n---\noptions:\n  label:\n    fly_launch_runtime: rails\n  sentry: false\n"
  },
  {
    "path": "spec/dummy_app/config/environment.rb",
    "content": "# frozen_string_literal: true\n\n# Load the Rails application.\nrequire File.expand_path('application', __dir__)\n\n# Initialize the Rails application.\nDummyApp::Application.initialize!\n"
  },
  {
    "path": "spec/dummy_app/config/environments/development.rb",
    "content": "# frozen_string_literal: true\n\nDummyApp::Application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  # In the development environment your application's code is reloaded on\n  # every request. This slows down response time but is perfect for development\n  # since you don't have to restart the web server when you make code changes.\n  config.cache_classes = false\n\n  # Do not eager load code on boot.\n  config.eager_load = false\n\n  # Show full error reports.\n  config.consider_all_requests_local = true\n\n  # Enable/disable caching. By default caching is disabled.\n  if Rails.root.join('tmp/caching-dev.txt').exist?\n    config.action_controller.perform_caching = true\n    config.cache_store = :memory_store\n    config.public_file_server.headers = {'Cache-Control' => 'public, max-age=172800'}\n  else\n    config.action_controller.perform_caching = false\n    config.cache_store = :null_store\n  end\n\n  # Don't care if the mailer can't send.\n  config.action_mailer.raise_delivery_errors = false\n\n  # Print deprecation notices to the Rails logger.\n  config.active_support.deprecation = :log\n\n  # Raise an error on page load if there are pending migrations.\n  config.active_record.migration_error = :page_load if CI_ORM == :active_record\n\n  if config.respond_to?(:assets)\n    # Debug mode disables concatenation and preprocessing of assets.\n    # This option may cause significant delays in view rendering with a large\n    # number of complex assets.\n    config.assets.debug = true\n\n    # Asset digests allow you to set far-future HTTP expiration dates on all assets,\n    # yet still be able to expire them through the digest params.\n    config.assets.digest = true\n\n    # Adds additional error checking when serving assets at runtime.\n    # Checks for improperly declared sprockets dependencies.\n    # Raises helpful error messages.\n    config.assets.raise_runtime_errors = true\n  end\n\n  # Raises error for missing translations\n  # config.action_view.raise_on_missing_translations = true\n\n  # Use an evented file watcher to asynchronously detect changes in source code,\n  # routes, locales, etc. This feature depends on the listen gem.\n  # config.file_watcher = ActiveSupport::EventedFileUpdateChecker\nend\n"
  },
  {
    "path": "spec/dummy_app/config/environments/production.rb",
    "content": "# frozen_string_literal: true\n\nDummyApp::Application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  # Code is not reloaded between requests.\n  config.cache_classes = true\n\n  # Eager load code on boot. This eager loads most of Rails and\n  # your application in memory, allowing both threaded web servers\n  # and those relying on copy on write to perform better.\n  # Rake tasks automatically ignore this option for performance.\n  config.eager_load = true\n\n  # Full error reports are disabled and caching is turned on.\n  config.consider_all_requests_local       = false\n  config.action_controller.perform_caching = true\n\n  # Disable serving static files from the `/public` folder by default since\n  # Apache or NGINX already handles this.\n  config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?\n  config.static_cache_control = 'public, max-age=31536000'\n\n  # Compress JavaScripts and CSS.\n  # config.assets.js_compressor = :uglifier\n  # config.assets.css_compressor = :sass\n\n  # Do not fallback to assets pipeline if a precompiled asset is missed.\n  config.assets.compile = false\n\n  # Asset digests allow you to set far-future HTTP expiration dates on all assets,\n  # yet still be able to expire them through the digest params.\n  config.assets.digest = true\n\n  # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb\n\n  # Enable serving of images, stylesheets, and JavaScripts from an asset server.\n  # config.action_controller.asset_host = 'http://assets.example.com'\n\n  # Specifies the header that your server uses for sending files.\n  # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache\n  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX\n\n  # Action Cable endpoint configuration\n  # config.action_cable.url = 'wss://example.com/cable'\n  # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\\/\\/example.*/ ]\n\n  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.\n  # config.force_ssl = true\n\n  # Use the lowest log level to ensure availability of diagnostic information\n  # when problems arise.\n  config.log_level = :info\n\n  # Prepend all log lines with the following tags.\n  # config.log_tags = [ :subdomain, :request_id ]\n\n  # Use a different logger for distributed setups.\n  # require 'syslog/logger'\n  # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')\n\n  # Use a different cache store in production.\n  # config.cache_store = :mem_cache_store\n\n  # Use a real queuing backend for Active Job (and separate queues per environment)\n  # config.active_job.queue_adapter     = :resque\n  # config.active_job.queue_name_prefix = \"dummy_app_#{Rails.env}\"\n\n  # Ignore bad email addresses and do not raise email delivery errors.\n  # Set this to true and configure the email server for immediate delivery to raise delivery errors.\n  # config.action_mailer.raise_delivery_errors = false\n\n  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to\n  # the I18n.default_locale when a translation cannot be found).\n  config.i18n.fallbacks = true\n\n  # Send deprecation notices to registered listeners.\n  config.active_support.deprecation = :notify\n\n  # Use default logging formatter so that PID and timestamp are not suppressed.\n  config.log_formatter = ::Logger::Formatter.new\n\n  # Do not dump schema after migrations.\n  config.active_record.dump_schema_after_migration = false\n\n  # Disable yjit to save memory.\n  config.yjit = false\nend\n"
  },
  {
    "path": "spec/dummy_app/config/environments/test.rb",
    "content": "# frozen_string_literal: true\n\nDummyApp::Application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  # The test environment is used exclusively to run your application's\n  # test suite. You never need to work with it otherwise. Remember that\n  # your test database is \"scratch space\" for the test suite and is wiped\n  # and recreated between test runs. Don't rely on the data there!\n  config.cache_classes = true\n\n  # Do not eager load code on boot. This avoids loading your whole application\n  # just for the purpose of running a single test. If you are using a tool that\n  # preloads Rails for running tests, you may have to set it to true.\n  config.eager_load = false\n\n  # Configure public file server for tests with Cache-Control for performance.\n  if config.respond_to?(:public_file_server)\n    config.public_file_server.enabled = true\n    config.public_file_server.headers = {'Cache-Control' => 'public, max-age=3600'}\n  else\n    config.serve_static_files   = true\n    config.static_cache_control = 'public, max-age=3600'\n  end\n\n  # Show full error reports and disable caching.\n  config.consider_all_requests_local       = true\n  config.action_controller.perform_caching = false\n\n  # Raise exceptions instead of rendering exception templates.\n  config.action_dispatch.show_exceptions = Rails.gem_version >= Gem::Version.new('7.1') ? :none : false\n\n  # Disable request forgery protection in test environment.\n  config.action_controller.allow_forgery_protection = false\n\n  # Tell Action Mailer not to deliver emails to the real world.\n  # The :test delivery method accumulates sent emails in the\n  # ActionMailer::Base.deliveries array.\n  config.action_mailer.delivery_method = :test\n\n  # Randomize the order test cases are executed.\n  config.active_support.test_order = :random\n\n  # Print deprecation notices to the stderr.\n  config.active_support.deprecation = :stderr\n\n  # Raises error for missing translations\n  # config.action_view.raise_on_missing_translations = true\nend\n"
  },
  {
    "path": "spec/dummy_app/config/importmap.rails_admin.rb",
    "content": "# frozen_string_literal: true\n\n# Pin npm packages by running ./bin/importmap\n\npin 'rails_admin', preload: true\npin 'rails_admin/src/rails_admin/base', to: 'rails_admin/base.js'\npin '@hotwired/turbo', to: 'https://ga.jspm.io/npm:@hotwired/turbo@7.1.0/dist/turbo.es2017-esm.js'\npin '@hotwired/turbo-rails', to: 'https://ga.jspm.io/npm:@hotwired/turbo-rails@7.1.3/app/javascript/turbo/index.js'\npin '@popperjs/core', to: 'https://ga.jspm.io/npm:@popperjs/core@2.11.5/dist/esm/popper.js'\npin '@rails/actioncable/src', to: 'https://ga.jspm.io/npm:@rails/actioncable@7.0.3-1/src/index.js'\npin '@rails/actiontext', to: 'https://ga.jspm.io/npm:@rails/actiontext@7.0.3-1/app/javascript/actiontext/index.js'\npin '@rails/activestorage', to: 'https://ga.jspm.io/npm:@rails/activestorage@7.0.3-1/app/assets/javascripts/activestorage.esm.js'\npin '@rails/ujs', to: 'https://ga.jspm.io/npm:@rails/ujs@7.0.3-1/lib/assets/compiled/rails-ujs.js'\npin 'bootstrap', to: 'https://ga.jspm.io/npm:bootstrap@5.1.3/dist/js/bootstrap.esm.js'\npin 'flatpickr', to: 'https://ga.jspm.io/npm:flatpickr@4.6.13/dist/flatpickr.js'\npin 'flatpickr/', to: 'https://ga.jspm.io/npm:flatpickr@4.6.13/'\npin 'jquery', to: 'https://ga.jspm.io/npm:jquery@3.6.0/dist/jquery.js'\npin 'jquery-ui/', to: 'https://ga.jspm.io/npm:jquery-ui@1.13.1/'\npin 'trix', to: 'https://ga.jspm.io/npm:trix@2.0.0-beta.0/dist/trix.js'\n"
  },
  {
    "path": "spec/dummy_app/config/importmap.rb",
    "content": "# frozen_string_literal: true\n\n# Pin npm packages by running ./bin/importmap\n\npin 'application', preload: true\npin '@hotwired/turbo-rails', to: 'https://ga.jspm.io/npm:@hotwired/turbo-rails@7.1.3/app/javascript/turbo/index.js'\npin '@rails/ujs', to: 'https://ga.jspm.io/npm:@rails/ujs@6.0.5/lib/assets/compiled/rails-ujs.js'\npin '@hotwired/turbo', to: 'https://ga.jspm.io/npm:@hotwired/turbo@7.1.0/dist/turbo.es2017-esm.js'\npin '@rails/actioncable/src', to: 'https://ga.jspm.io/npm:@rails/actioncable@7.0.3/src/index.js'\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/application_controller_renderer.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# ApplicationController.renderer.defaults.merge!(\n#   http_host: 'example.org',\n#   https: false\n# )\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/assets.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# Version of your assets, change this if you want to expire all your assets.\nRails.application.config.assets.version = '1.0' if Rails.application.config.respond_to?(:assets)\n\n# Add additional assets to the asset load path\n# Rails.application.config.assets.paths << Emoji.images_path\nRails.application.config.assets.paths << Rails.root.join('node_modules/@fortawesome/fontawesome-free/webfonts') if Rails.application.config.respond_to?(:assets)\n\n# Precompile additional assets.\n# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.\n# Rails.application.config.assets.precompile += %w( search.js )\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/backtrace_silencers.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.\n# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }\n\n# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.\n# Rails.backtrace_cleaner.remove_silencers!\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/cookies_serializer.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# This is a new Rails 5.0 default, so introduced as a config to ensure apps made with earlier versions of Rails aren't affected when upgrading.\nRails.application.config.action_dispatch.cookies_serializer = :json\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/cors.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# Avoid CORS issues when API is called from the frontend app.\n# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests.\n\n# Read more: https://github.com/cyu/rack-cors\n\n# Rails.application.config.middleware.insert_before 0, Rack::Cors do\n#   allow do\n#     origins 'example.com'\n#\n#     resource '*',\n#       headers: :any,\n#       methods: [:get, :post, :put, :patch, :delete, :options, :head]\n#   end\n# end\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/devise.rb",
    "content": "# frozen_string_literal: true\n\n# Use this hook to configure devise mailer, warden hooks and so forth.\n# Many of these configuration options can be set straight in your model.\nDevise.setup do |config|\n  # The secret key used by Devise. Devise uses this key to generate\n  # random tokens. Changing this key will render invalid all existing\n  # confirmation, reset password and unlock tokens in the database.\n  config.secret_key = '5c72fe9ca98a9862e235c7fb8277e3f6a02d41e0f941beebaa5271a712c46da90f5e4a04fde095d7f2f219cd41ec014c72d995837424164ae7ffc0f44eaa3742'\n\n  # ==> Mailer Configuration\n  # Configure the e-mail address which will be shown in Devise::Mailer,\n  # note that it will be overwritten if you use your own mailer class\n  # with default \"from\" parameter.\n  config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'\n\n  # Configure the class responsible to send e-mails.\n  # config.mailer = 'Devise::Mailer'\n\n  # ==> ORM configuration\n  # Load and configure the ORM. Supports :active_record (default) and\n  # :mongoid (bson_ext recommended) by default. Other ORMs may be\n  # available as additional gems.\n  require \"devise/orm/#{CI_ORM}\"\n\n  # ==> Configuration for any authentication mechanism\n  # Configure which keys are used when authenticating a user. The default is\n  # just :email. You can configure it to use [:username, :subdomain], so for\n  # authenticating a user, both parameters are required. Remember that those\n  # parameters are used only when authenticating and not when retrieving from\n  # session. If you need permissions, you should implement that in a before filter.\n  # You can also supply a hash where the value is a boolean determining whether\n  # or not authentication should be aborted when the value is not present.\n  # config.authentication_keys = [ :email ]\n\n  # Configure parameters from the request object used for authentication. Each entry\n  # given should be a request method and it will automatically be passed to the\n  # find_for_authentication method and considered in your model lookup. For instance,\n  # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.\n  # The same considerations mentioned for authentication_keys also apply to request_keys.\n  # config.request_keys = []\n\n  # Configure which authentication keys should be case-insensitive.\n  # These keys will be downcased upon creating or modifying a user and when used\n  # to authenticate or find a user. Default is :email.\n  config.case_insensitive_keys = [:email]\n\n  # Configure which authentication keys should have whitespace stripped.\n  # These keys will have whitespace before and after removed upon creating or\n  # modifying a user and when used to authenticate or find a user. Default is :email.\n  config.strip_whitespace_keys = [:email]\n\n  # Tell if authentication through request.params is enabled. True by default.\n  # It can be set to an array that will enable params authentication only for the\n  # given strategies, for example, `config.params_authenticatable = [:database]` will\n  # enable it only for database (email + password) authentication.\n  # config.params_authenticatable = true\n\n  # Tell if authentication through HTTP Auth is enabled. False by default.\n  # It can be set to an array that will enable http authentication only for the\n  # given strategies, for example, `config.http_authenticatable = [:token]` will\n  # enable it only for token authentication. The supported strategies are:\n  # :database      = Support basic authentication with authentication key + password\n  # :token         = Support basic authentication with token authentication key\n  # :token_options = Support token authentication with options as defined in\n  #                  http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html\n  # config.http_authenticatable = false\n\n  # If http headers should be returned for AJAX requests. True by default.\n  # config.http_authenticatable_on_xhr = true\n\n  # The realm used in Http Basic Authentication. 'Application' by default.\n  # config.http_authentication_realm = 'Application'\n\n  # It will change confirmation, password recovery and other workflows\n  # to behave the same regardless if the e-mail provided was right or wrong.\n  # Does not affect registerable.\n  # config.paranoid = true\n\n  # By default Devise will store the user in session. You can skip storage for\n  # :http_auth and :token_auth by adding those symbols to the array below.\n  # Notice that if you are skipping storage for all authentication paths, you\n  # may want to disable generating routes to Devise's sessions controller by\n  # passing skip: :sessions to `devise_for` in your config/routes.rb\n  config.skip_session_storage = [:http_auth]\n\n  # By default, Devise cleans up the CSRF token on authentication to\n  # avoid CSRF token fixation attacks. This means that, when using AJAX\n  # requests for sign in and sign up, you need to get a new CSRF token\n  # from the server. You can disable this option at your own risk.\n  # config.clean_up_csrf_token_on_authentication = true\n\n  # ==> Configuration for :database_authenticatable\n  # For bcrypt, this is the cost for hashing the password and defaults to 10. If\n  # using other encryptors, it sets how many times you want the password re-encrypted.\n  #\n  # Limiting the stretches to just one in testing will increase the performance of\n  # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use\n  # a value less than 10 in other environments.\n  config.stretches = Rails.env.test? ? 1 : 10\n\n  # Setup a pepper to generate the encrypted password.\n  # config.pepper = 'db4c2356895fab849584ee71a3467a20720ff9b629f27a0da70bd4176773c5360e25d453f1801c69e2e0e61f3a9b5631cda52d7da99b4ced83ea66940db3ce0e'\n\n  # ==> Configuration for :confirmable\n  # A period that the user is allowed to access the website even without\n  # confirming their account. For instance, if set to 2.days, the user will be\n  # able to access the website for two days without confirming their account,\n  # access will be blocked just in the third day. Default is 0.days, meaning\n  # the user cannot access the website without confirming their account.\n  # config.allow_unconfirmed_access_for = 2.days\n\n  # A period that the user is allowed to confirm their account before their\n  # token becomes invalid. For example, if set to 3.days, the user can confirm\n  # their account within 3 days after the mail was sent, but on the fourth day\n  # their account can't be confirmed with the token any more.\n  # Default is nil, meaning there is no restriction on how long a user can take\n  # before confirming their account.\n  # config.confirm_within = 3.days\n\n  # If true, requires any email changes to be confirmed (exactly the same way as\n  # initial account confirmation) to be applied. Requires additional unconfirmed_email\n  # db field (see migrations). Until confirmed new email is stored in\n  # unconfirmed email column, and copied to email column on successful confirmation.\n  config.reconfirmable = true\n\n  # Defines which key will be used when confirming an account\n  # config.confirmation_keys = [ :email ]\n\n  # ==> Configuration for :rememberable\n  # The time the user will be remembered without asking for credentials again.\n  # config.remember_for = 2.weeks\n\n  # If true, extends the user's remember period when remembered via cookie.\n  # config.extend_remember_period = false\n\n  # Options to be passed to the created cookie. For instance, you can set\n  # secure: true in order to force SSL only cookies.\n  # config.rememberable_options = {}\n\n  # ==> Configuration for :validatable\n  # Range for password length. Default is 8..128.\n  config.password_length = 8..128\n\n  # Email regex used to validate email formats. It simply asserts that\n  # one (and only one) @ exists in the given string. This is mainly\n  # to give user feedback and not to assert the e-mail validity.\n  # config.email_regexp = /\\A[^@]+@[^@]+\\z/\n\n  # ==> Configuration for :timeoutable\n  # The time you want to timeout the user session without activity. After this\n  # time the user will be asked for credentials again. Default is 30 minutes.\n  # config.timeout_in = 30.minutes\n\n  # If true, expires auth token on session timeout.\n  # config.expire_auth_token_on_timeout = false\n\n  # ==> Configuration for :lockable\n  # Defines which strategy will be used to lock an account.\n  # :failed_attempts = Locks an account after a number of failed attempts to sign in.\n  # :none            = No lock strategy. You should handle locking by yourself.\n  # config.lock_strategy = :failed_attempts\n\n  # Defines which key will be used when locking and unlocking an account\n  # config.unlock_keys = [ :email ]\n\n  # Defines which strategy will be used to unlock an account.\n  # :email = Sends an unlock link to the user email\n  # :time  = Re-enables login after a certain amount of time (see :unlock_in below)\n  # :both  = Enables both strategies\n  # :none  = No unlock strategy. You should handle unlocking by yourself.\n  # config.unlock_strategy = :both\n\n  # Number of authentication tries before locking an account if lock_strategy\n  # is failed attempts.\n  # config.maximum_attempts = 20\n\n  # Time interval to unlock the account if :time is enabled as unlock_strategy.\n  # config.unlock_in = 1.hour\n\n  # ==> Configuration for :recoverable\n  #\n  # Defines which key will be used when recovering the password for an account\n  # config.reset_password_keys = [ :email ]\n\n  # Time interval you can reset your password with a reset password key.\n  # Don't put a too small interval or your users won't have the time to\n  # change their passwords.\n  config.reset_password_within = 6.hours\n\n  # ==> Configuration for :encryptable\n  # Allow you to use another encryption algorithm besides bcrypt (default). You can use\n  # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,\n  # :authlogic_sha512 (then you should set stretches above to 20 for default behavior)\n  # and :restful_authentication_sha1 (then you should set stretches to 10, and copy\n  # REST_AUTH_SITE_KEY to pepper).\n  #\n  # Require the `devise-encryptable` gem when using anything other than bcrypt\n  # config.encryptor = :sha512\n\n  # ==> Configuration for :token_authenticatable\n  # Defines name of the authentication token params key\n  # config.token_authentication_key = :auth_token\n\n  # ==> Scopes configuration\n  # Turn scoped views on. Before rendering \"sessions/new\", it will first check for\n  # \"users/sessions/new\". It's turned off by default because it's slower if you\n  # are using only default views.\n  # config.scoped_views = false\n\n  # Configure the default scope given to Warden. By default it's the first\n  # devise role declared in your routes (usually :user).\n  # config.default_scope = :user\n\n  # Set this configuration to false if you want /users/sign_out to sign out\n  # only the current scope. By default, Devise signs out all scopes.\n  # config.sign_out_all_scopes = true\n\n  # ==> Navigation configuration\n  # Lists the formats that should be treated as navigational. Formats like\n  # :html, should redirect to the sign in page when the user does not have\n  # access, but formats like :xml or :json, should return 401.\n  #\n  # If you have any extra navigational formats, like :iphone or :mobile, you\n  # should add them to the navigational formats lists.\n  #\n  # The \"*/*\" below is required to match Internet Explorer requests.\n  # config.navigational_formats = ['*/*', :html]\n\n  # The default HTTP method used to sign out a resource. Default is :delete.\n  config.sign_out_via = :delete\n\n  # ==> OmniAuth\n  # Add a new OmniAuth provider. Check the wiki for more information on setting\n  # up on your models and hooks.\n  # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'\n\n  # ==> Warden configuration\n  # If you want to use other strategies, that are not supported by Devise, or\n  # change the failure app, you can configure them inside the config.warden block.\n  #\n  # config.warden do |manager|\n  #   manager.intercept_401 = false\n  #   manager.default_strategies(scope: :user).unshift :some_external_strategy\n  # end\n\n  # ==> Mountable engine configurations\n  # When using Devise inside an engine, let's call it `MyEngine`, and this engine\n  # is mountable, there are some extra configurations to be taken into account.\n  # The following options are available, assuming the engine is mounted as:\n  #\n  #     mount MyEngine, at: '/my_engine'\n  #\n  # The router that invoked `devise_for`, in the example above, would be:\n  # config.router_name = :my_engine\n  #\n  # When using omniauth, Devise cannot automatically set Omniauth path,\n  # so you need to do it manually. For the users scope, it would be:\n  # config.omniauth_path_prefix = '/my_engine/users/auth'\nend\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/dragonfly.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'dragonfly'\n\n# Logger\nDragonfly.logger = Rails.logger\n\n# Configure\nDragonfly.app.configure do\n  plugin :imagemagick\n\n  protect_from_dos_attacks true\n  secret '904547b2be647f0e11a76933b3220d6bd2fb83f380ac760125e4daa3b9504b4e'\n\n  url_format '/media/:job/:name'\n\n  datastore(:file,\n            root_path: Rails.root.join('public/system/dragonfly', Rails.env),\n            server_root: Rails.root.join('public'))\nend\n\n# Mount as middleware\nRails.application.middleware.use Dragonfly::Middleware\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/filter_parameter_logging.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# Configure sensitive parameters which will be filtered from the log file.\nRails.application.config.filter_parameters += [:password]\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/inflections.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# Add new inflection rules using the following format. Inflections\n# are locale specific, and you may define rules for as many different\n# locales as you wish. All of these examples are active by default:\n# ActiveSupport::Inflector.inflections(:en) do |inflect|\n#   inflect.plural /^(ox)$/i, '\\1en'\n#   inflect.singular /^(ox)en/i, '\\1'\n#   inflect.irregular 'person', 'people'\n#   inflect.uncountable %w( fish sheep )\n# end\n\n# These inflection rules are supported but not enabled by default:\n# ActiveSupport::Inflector.inflections(:en) do |inflect|\n#   inflect.acronym 'RESTful'\n# end\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/mime_types.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# Add new mime types for use in respond_to blocks:\n# Mime::Type.register \"text/richtext\", :rtf\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/mongoid.rb",
    "content": "# frozen_string_literal: true\n\nif CI_ORM == :mongoid\n  filename =\n    if Mongoid.respond_to?(:belongs_to_required_by_default=)\n      'mongoid6.yml'\n    else\n      'mongoid5.yml'\n    end\n  ::Mongoid.load!(Rails.root.join('config', filename))\nend\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/rails_admin.rb",
    "content": "# frozen_string_literal: true\n\nRailsAdmin.config do |c|\n  c.asset_source = CI_ASSET\n  c.model Team do\n    include_all_fields\n    field :color, :hidden\n  end\n\n  if Rails.env.production?\n    # Live demo configuration\n    c.main_app_name = ['RailsAdmin', 'Live Demo']\n    c.included_models = %w[Comment Division Draft Fan FieldTest League NestedFieldTest Player Team User]\n    c.model 'FieldTest' do\n      configure :paperclip_asset do\n        visible false\n      end\n    end\n    c.model 'League' do\n      configure :players do\n        visible false\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/secret_token.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# Your secret key is used for verifying the integrity of signed cookies.\n# If you change this key, all old signed cookies will become invalid!\n\n# Make sure the secret is at least 30 characters and all random,\n# no regular words or you'll be exposed to dictionary attacks.\n# You can use `rake secret` to generate a secure secret key.\n\n# Make sure your secret_key_base is kept private\n# if you're sharing your code publicly.\nDummyApp::Application.config.secret_key_base = '11cefe91820bbc7c4ef81114d5b8e9237bce9c1d5d1b4a2f8b333e151dfa3ff43b3db8d0d3b4dc414f15113f28c5d779e829c3cb3fbcdc7c5a94fe7fdcb2c81c'\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/session_patch.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'action_dispatch/middleware/session/abstract_store'\n\n# When ORM was switched, but another ORM's model class still exists in session\n# (Devise saves User model to session), ActionDispatch raises ActionDispatch::Session::SessionRestoreError\n# and app can't be started unless you delete your browser's cookie data.\n# To prevent this situation, detect this problem here and reset session data\n# so user can make another login via Devise.\n\nActionDispatch::Session::StaleSessionCheck.module_eval do\n  def stale_session_check!\n    yield\n  rescue ArgumentError\n    {}\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/session_store.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\nRails.application.config.session_store :cookie_store, key: '_dummy_app_session'\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/shrine.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'shrine'\nrequire 'shrine/storage/memory'\n\nShrine.storages = {\n  cache: Shrine::Storage::Memory.new,\n  store: Shrine::Storage::Memory.new,\n}\n"
  },
  {
    "path": "spec/dummy_app/config/initializers/wrap_parameters.rb",
    "content": "# frozen_string_literal: true\n\n# Be sure to restart your server when you modify this file.\n\n# This file contains settings for ActionController::ParamsWrapper which\n# is enabled by default.\n\n# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.\nActiveSupport.on_load(:action_controller) do\n  wrap_parameters format: [:json] if respond_to?(:wrap_parameters)\nend\n\n# To enable root element in JSON for ActiveRecord objects.\n# ActiveSupport.on_load(:active_record) do\n#   self.include_root_in_json = true\n# end\n"
  },
  {
    "path": "spec/dummy_app/config/locales/devise.en.yml",
    "content": "# Additional translations at https://github.com/plataformatec/devise/wiki/I18n\n\nen:\n  devise:\n    confirmations:\n      confirmed: \"Your account was successfully confirmed.\"\n      confirmed_and_signed_in: \"Your account was successfully confirmed. You are now signed in.\"\n      send_instructions: \"You will receive an email with instructions about how to confirm your account in a few minutes.\"\n      send_paranoid_instructions: \"If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes.\"\n    failure:\n      already_authenticated: \"You are already signed in.\"\n      inactive: \"Your account is not activated yet.\"\n      invalid: \"Invalid email or password.\"\n      invalid_token: \"Invalid authentication token.\"\n      locked: \"Your account is locked.\"\n      not_found_in_database: \"Invalid email or password.\"\n      timeout: \"Your session expired. Please sign in again to continue.\"\n      unauthenticated: \"You need to sign in or sign up before continuing.\"\n      unconfirmed: \"You have to confirm your account before continuing.\"\n    mailer:\n      confirmation_instructions:\n        subject: \"Confirmation instructions\"\n      reset_password_instructions:\n        subject: \"Reset password instructions\"\n      unlock_instructions:\n        subject: \"Unlock Instructions\"\n    omniauth_callbacks:\n      failure: 'Could not authenticate you from %{kind} because \"%{reason}\".'\n      success: \"Successfully authenticated from %{kind} account.\"\n    passwords:\n      no_token: \"You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided.\"\n      send_instructions: \"You will receive an email with instructions about how to reset your password in a few minutes.\"\n      send_paranoid_instructions: \"If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes.\"\n      updated: \"Your password was changed successfully. You are now signed in.\"\n      updated_not_active: \"Your password was changed successfully.\"\n    registrations:\n      destroyed: \"Bye! Your account was successfully cancelled. We hope to see you again soon.\"\n      signed_up: \"Welcome! You have signed up successfully.\"\n      signed_up_but_inactive: \"You have signed up successfully. However, we could not sign you in because your account is not yet activated.\"\n      signed_up_but_locked: \"You have signed up successfully. However, we could not sign you in because your account is locked.\"\n      signed_up_but_unconfirmed: \"A message with a confirmation link has been sent to your email address. Please open the link to activate your account.\"\n      update_needs_confirmation: \"You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address.\"\n      updated: \"You updated your account successfully.\"\n    sessions:\n      signed_in: \"Signed in successfully.\"\n      signed_out: \"Signed out successfully.\"\n    unlocks:\n      send_instructions: \"You will receive an email with instructions about how to unlock your account in a few minutes.\"\n      send_paranoid_instructions: \"If your account exists, you will receive an email with instructions about how to unlock it in a few minutes.\"\n      unlocked: \"Your account has been unlocked successfully. Please sign in to continue.\"\n  errors:\n    messages:\n      already_confirmed: \"was already confirmed, please try signing in\"\n      confirmation_period_expired: \"needs to be confirmed within %{period}, please request a new one\"\n      expired: \"has expired, please request a new one\"\n      not_found: \"not found\"\n      not_locked: \"was not locked\"\n      not_saved:\n        one: \"1 error prohibited this %{resource} from being saved:\"\n        other: \"%{count} errors prohibited this %{resource} from being saved:\"\n"
  },
  {
    "path": "spec/dummy_app/config/locales/en.yml",
    "content": "en:\n  admin:\n    help:\n      team:\n        name: \"Team Name Help Text.\"\n"
  },
  {
    "path": "spec/dummy_app/config/locales/fr.yml",
    "content": "fr:\n  date:\n    formats:\n      default: \"%d/%m/%Y\"\n      short: \"%e %b\"\n      compact: \"%d/%m/%y\"\n      long: \"%e %B %Y\"\n    day_names: [dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi]\n    abbr_day_names: [dim, lun, mar, mer, jeu, ven, sam]\n    month_names:\n      [\n        ~,\n        janvier,\n        février,\n        mars,\n        avril,\n        mai,\n        juin,\n        juillet,\n        août,\n        septembre,\n        octobre,\n        novembre,\n        décembre,\n      ]\n    abbr_month_names:\n      [\n        ~,\n        jan.,\n        fév.,\n        mar.,\n        avr.,\n        mai,\n        juin,\n        juil.,\n        août,\n        sept.,\n        oct.,\n        nov.,\n        déc.,\n      ]\n    order:\n      - :day\n      - :month\n      - :year\n  time:\n    formats:\n      default: \"%d %B %Y %H:%M:%S\"\n      short: \"%d %b %H:%M\"\n      compact: \"%d/%m/%y %H:%M\"\n      long: \"%A %d %B %Y %H:%M\"\n      verb: \"%d %B %Y\"\n    am: \"am\"\n    pm: \"pm\"\n"
  },
  {
    "path": "spec/dummy_app/config/mongoid5.yml",
    "content": "defaults: &defaults\n  use_utc: false\n  use_activesupport_time_zone: true\n\ndevelopment:\n  <<: *defaults\n  database: dummy_app_development\n  clients:\n    default:\n      database: dummy_app_development\n      hosts:\n        - 127.0.0.1:27017\n\ntest:\n  <<: *defaults\n  clients:\n    default:\n      database: dummy_app_test\n      hosts:\n        - 127.0.0.1:27017\n"
  },
  {
    "path": "spec/dummy_app/config/mongoid6.yml",
    "content": "defaults: &defaults\n  use_utc: false\n  use_activesupport_time_zone: true\n  options:\n    belongs_to_required_by_default: false\n\ndevelopment:\n  <<: *defaults\n  database: dummy_app_development\n  clients:\n    default:\n      database: dummy_app_development\n      hosts:\n        - 127.0.0.1:27017\n\ntest:\n  <<: *defaults\n  clients:\n    default:\n      database: dummy_app_test\n      hosts:\n        - 127.0.0.1:27017\n"
  },
  {
    "path": "spec/dummy_app/config/puma.rb",
    "content": "# frozen_string_literal: true\n\nthreads 0, ENV.fetch('RAILS_MAX_THREADS', 3)\nport ENV.fetch('PORT', 3000)\n"
  },
  {
    "path": "spec/dummy_app/config/routes.rb",
    "content": "# frozen_string_literal: true\n\nDummyApp::Application.routes.draw do\n  # Needed for :show_in_app tests\n  resources :players, only: [:show]\n\n  devise_for :users\n  mount RailsAdmin::Engine => '/admin', as: 'rails_admin'\n  root to: 'rails_admin/main#dashboard'\nend\n"
  },
  {
    "path": "spec/dummy_app/config/secrets.yml",
    "content": "# Be sure to restart your server when you modify this file.\n\n# Your secret key is used for verifying the integrity of signed cookies.\n# If you change this key, all old signed cookies will become invalid!\n\n# Make sure the secret is at least 30 characters and all random,\n# no regular words or you'll be exposed to dictionary attacks.\n# You can use `rake secret` to generate a secure secret key.\n\n# Make sure the secrets in this file are kept private\n# if you're sharing your code publicly.\n\ndevelopment:\n  secret_key_base: fe661de3f58b9d446d992466c6e623394828bb6a0af4853bdef9de6ac17b847f418c2aa5778afa4af7b34906df5075e4d5dc6f4b61def924b7ae58f886608770\n\ntest:\n  secret_key_base: 3bc2c7ebeb21e93fd8cb1166ae0cdb560c2fa8417e5dd016f691765b5e5a455f53841c01906dfd3b779beed3ad5062be664426001cf9e54ec0874c273a8e64eb\n\n# Do not keep production secrets in the repository,\n# instead read values from the environment.\nproduction:\n  secret_key_base: <%= ENV[\"SECRET_KEY_BASE\"] %>\n"
  },
  {
    "path": "spec/dummy_app/config/storage.yml",
    "content": "local:\n  service: Disk\n  root: <%= Rails.root.join('public', 'system') %>\n"
  },
  {
    "path": "spec/dummy_app/config/vite.json",
    "content": "{\n  \"all\": {\n    \"sourceCodeDir\": \"app/frontend\",\n    \"watchAdditionalPaths\": [\"../../src\"]\n  },\n  \"development\": {\n    \"autoBuild\": true,\n    \"publicOutputDir\": \"vite\",\n    \"port\": 3036\n  },\n  \"test\": {\n    \"autoBuild\": false,\n    \"publicOutputDir\": \"vite\"\n  }\n}\n"
  },
  {
    "path": "spec/dummy_app/config/webpack/development.js",
    "content": "process.env.NODE_ENV = process.env.NODE_ENV || \"development\";\n\nconst environment = require(\"./environment\");\n\nmodule.exports = environment.toWebpackConfig();\n"
  },
  {
    "path": "spec/dummy_app/config/webpack/environment.js",
    "content": "const { environment } = require(\"@rails/webpacker\");\n\nmodule.exports = environment;\n"
  },
  {
    "path": "spec/dummy_app/config/webpack/production.js",
    "content": "process.env.NODE_ENV = process.env.NODE_ENV || \"production\";\n\nconst environment = require(\"./environment\");\n\nmodule.exports = environment.toWebpackConfig();\n"
  },
  {
    "path": "spec/dummy_app/config/webpack/test.js",
    "content": "process.env.NODE_ENV = process.env.NODE_ENV || \"development\";\n\nconst environment = require(\"./environment\");\n\nmodule.exports = environment.toWebpackConfig();\n"
  },
  {
    "path": "spec/dummy_app/config/webpacker.yml",
    "content": "# Note: You must restart bin/webpack-dev-server for changes to take effect\n\ndefault: &default\n  source_path: app/javascript\n  source_entry_path: .\n  public_root_path: public\n  public_output_path: packs\n  cache_path: tmp/cache/webpacker\n  webpack_compile_output: true\n\n  # Additional paths webpack should lookup modules\n  # ['app/assets', 'engine/foo/app/assets']\n  additional_paths: [\"node_modules/rails_admin/src\"]\n\n  # Reload manifest.json on all requests so we reload latest compiled packs\n  cache_manifest: false\n\n  # Extract and emit a css file\n  extract_css: true\n\n  static_assets_extensions:\n    - .jpg\n    - .jpeg\n    - .png\n    - .gif\n    - .tiff\n    - .ico\n    - .svg\n    - .eot\n    - .otf\n    - .ttf\n    - .woff\n    - .woff2\n\n  extensions:\n    - .mjs\n    - .js\n    - .sass\n    - .scss\n    - .css\n    - .module.sass\n    - .module.scss\n    - .module.css\n    - .png\n    - .svg\n    - .gif\n    - .jpeg\n    - .jpg\n\ndevelopment:\n  <<: *default\n  compile: true\n\n  # Reference: https://webpack.js.org/configuration/dev-server/\n  dev_server:\n    https: false\n    host: localhost\n    port: 3035\n    public: localhost:3035\n    hmr: false\n    # Inline should be set to true if using HMR\n    inline: true\n    overlay: true\n    compress: true\n    disable_host_check: true\n    use_local_ip: false\n    quiet: false\n    pretty: false\n    headers:\n      \"Access-Control-Allow-Origin\": \"*\"\n    watch_options:\n      ignored: \"**/node_modules/**\"\n\ntest:\n  <<: *default\n  compile: true\n  additional_paths: [\"src\"] # relative from the project root\n\n  # Compile test packs to a separate directory\n  public_output_path: packs-test\n\nproduction:\n  <<: *default\n\n  # Production depends on precompilation of packs prior to booting for performance.\n  compile: false\n\n  # Extract and emit a css file\n  extract_css: true\n\n  # Cache manifest.json for performance\n  cache_manifest: true\n"
  },
  {
    "path": "spec/dummy_app/config.ru",
    "content": "# frozen_string_literal: true\n\n# This file is used by Rack-based servers to start the application.\n\nrequire ::File.expand_path('config/environment', __dir__)\nrun DummyApp::Application\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000001_create_divisions_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateDivisionsMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :divisions do |t|\n      t.timestamps null: false\n      t.integer :league_id\n      t.string :name, limit: 50, null: false\n    end\n  end\n\n  def self.down\n    drop_table(:divisions)\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000002_create_drafts_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateDraftsMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :drafts do |t|\n      t.timestamps null: false\n      t.integer :player_id\n      t.integer :team_id\n      t.date :date\n      t.integer :round\n      t.integer :pick\n      t.integer :overall\n      t.string :college, limit: 100\n      t.text :notes\n    end\n  end\n\n  def self.down\n    drop_table :drafts\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000003_create_leagues_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateLeaguesMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :leagues do |t|\n      t.timestamps null: false\n      t.string :name, limit: 50, null: false\n    end\n  end\n\n  def self.down\n    drop_table :leagues\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000004_create_players_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass CreatePlayersMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :players do |t|\n      t.timestamps null: false\n      t.datetime :deleted_at\n      t.integer :team_id\n      t.string :name, limit: 100, null: false\n      t.string :position, limit: 50\n      t.integer :number, null: false\n      t.boolean :retired, default: false\n      t.boolean :injured, default: false\n      t.date :born_on\n      t.text :notes\n    end\n  end\n\n  def self.down\n    drop_table :players\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000005_create_teams_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateTeamsMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :teams do |t|\n      t.timestamps null: false\n      t.integer :league_id\n      t.integer :division_id\n      t.string :name, limit: 50\n      t.string :logo_url, limit: 255\n      t.string :manager, limit: 100, null: false\n      t.string :ballpark, limit: 100\n      t.string :mascot, limit: 100\n      t.integer :founded\n      t.integer :wins\n      t.integer :losses\n      t.float :win_percentage\n    end\n  end\n\n  def self.down\n    drop_table :teams\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000006_devise_create_users.rb",
    "content": "# frozen_string_literal: true\n\nclass DeviseCreateUsers < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :users do |t|\n      ## Database authenticatable\n      t.string :email,              null: false, default: ''\n      t.string :encrypted_password, null: false, default: ''\n\n      ## Recoverable\n      t.string :reset_password_token\n      t.datetime :reset_password_sent_at\n\n      ## Rememberable\n      t.datetime :remember_created_at\n\n      ## Trackable\n      t.integer :sign_in_count, default: 0\n      t.datetime :current_sign_in_at\n      t.datetime :last_sign_in_at\n      t.string :current_sign_in_ip\n      t.string :last_sign_in_ip\n\n      ## Encryptable\n      t.string :password_salt\n\n      ## Confirmable\n      # t.string   :confirmation_token\n      # t.datetime :confirmed_at\n      # t.datetime :confirmation_sent_at\n      # t.string   :unconfirmed_email # Only if using reconfirmable\n\n      ## Lockable\n      # t.integer  :failed_attempts, default: 0 # Only if lock strategy is :failed_attempts\n      # t.string   :unlock_token # Only if unlock strategy is :email or :both\n      # t.datetime :locked_at\n\n      # Token authenticatable\n      # t.string :authentication_token\n\n      t.timestamps null: false\n    end\n\n    add_index :users, :email, unique: true\n    add_index :users, :reset_password_token, unique: true\n  end\n\n  def self.down\n    drop_table :users\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000007_create_histories_table.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateHistoriesTable < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :histories do |t|\n      t.string :message # title, name, or object_id\n      t.string :username\n      t.integer :item\n      t.string :table\n      t.timestamps null: false\n    end\n    add_index(:histories, %i[item table])\n  end\n\n  def self.down\n    drop_table :histories\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000008_create_fans_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateFansMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :fans do |t|\n      t.timestamps null: false\n      t.string :name, limit: 100, null: false\n    end\n  end\n\n  def self.down\n    drop_table :fans\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000009_create_fans_teams_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateFansTeamsMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :fans_teams, id: false do |t|\n      t.integer :fan_id, :team_id\n    end\n  end\n\n  def self.down\n    drop_table :fans_teams\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000010_add_revenue_to_team_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass AddRevenueToTeamMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    add_column :teams, :revenue, :decimal, precision: 18, scale: 2\n  end\n\n  def self.down\n    remove_column :teams, :revenue\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000011_add_suspended_to_player_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass AddSuspendedToPlayerMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    add_column :players, :suspended, :boolean, default: false\n  end\n\n  def self.down\n    remove_column :players, :suspended\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000012_add_avatar_columns_to_user.rb",
    "content": "# frozen_string_literal: true\n\nclass AddAvatarColumnsToUser < ActiveRecord::Migration[5.0]\n  def self.up\n    add_column :users, :avatar_file_name,    :string\n    add_column :users, :avatar_content_type, :string\n    add_column :users, :avatar_file_size,    :integer\n    add_column :users, :avatar_updated_at,   :datetime\n  end\n\n  def self.down\n    remove_column :users, :avatar_file_name\n    remove_column :users, :avatar_content_type\n    remove_column :users, :avatar_file_size\n    remove_column :users, :avatar_updated_at\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000013_add_roles_to_user.rb",
    "content": "# frozen_string_literal: true\n\nclass AddRolesToUser < ActiveRecord::Migration[5.0]\n  def self.up\n    add_column :users, :roles, :string\n  end\n\n  def self.down\n    remove_column :users, :roles\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/00000000000014_add_color_to_team_migration.rb",
    "content": "# frozen_string_literal: true\n\nclass AddColorToTeamMigration < ActiveRecord::Migration[5.0]\n  def self.up\n    add_column :teams, :color, :string\n  end\n\n  def self.down\n    remove_column :teams, :color\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20101223222233_create_rel_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateRelTests < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :rel_tests do |t|\n      t.integer :league_id\n      t.integer :division_id, null: false\n      t.integer :player_id\n\n      t.timestamps null: false\n    end\n  end\n\n  def self.down\n    drop_table :rel_tests\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110103205808_create_comments.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateComments < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :comments do |t|\n      t.integer :commentable_id\n      t.string :commentable_type\n      t.text :content\n\n      t.timestamps null: false\n    end\n  end\n\n  def self.down\n    drop_table :comments\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110123042530_rename_histories_to_rails_admin_histories.rb",
    "content": "# frozen_string_literal: true\n\nclass RenameHistoriesToRailsAdminHistories < ActiveRecord::Migration[5.0]\n  def self.up\n    rename_table :histories, :rails_admin_histories\n  end\n\n  def self.down\n    rename_table :rails_admin_histories, :histories\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110224184303_create_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateFieldTests < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :field_tests do |t|\n      t.string :string_field\n      t.text :text_field\n      t.integer :integer_field\n      t.float :float_field\n      t.decimal :decimal_field\n      t.datetime :datetime_field\n      t.timestamp :timestamp_field\n      t.time :time_field\n      t.date :date_field\n      t.boolean :boolean_field\n\n      t.timestamps null: false\n    end\n  end\n\n  def self.down\n    drop_table :field_tests\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110328193014_create_cms_basic_pages.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateCmsBasicPages < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :cms_basic_pages do |t|\n      t.string :title\n      t.text :content\n\n      t.timestamps null: false\n    end\n  end\n\n  def self.down\n    drop_table :cms_basic_pages\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110329183136_remove_league_id_from_teams.rb",
    "content": "# frozen_string_literal: true\n\nclass RemoveLeagueIdFromTeams < ActiveRecord::Migration[5.0]\n  def self.up\n    remove_column :teams, :league_id\n  end\n\n  def self.down\n    add_column :teams, :league_id, :integer\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110607152842_add_format_to_field_test.rb",
    "content": "# frozen_string_literal: true\n\nclass AddFormatToFieldTest < ActiveRecord::Migration[5.0]\n  def self.up\n    add_column :field_tests, :format, :string\n  end\n\n  def self.down\n    remove_column :field_tests, :format\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110714095433_create_balls.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateBalls < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :balls, force: true do |t|\n      t.string :color\n      t.timestamps null: false\n    end\n  end\n\n  def self.down\n    drop_table :balls\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110831090841_add_protected_field_and_restricted_field_to_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass AddProtectedFieldAndRestrictedFieldToFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    add_column :field_tests, :restricted_field, :string\n    add_column :field_tests, :protected_field, :string\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110901131551_change_division_primary_key.rb",
    "content": "# frozen_string_literal: true\n\nclass ChangeDivisionPrimaryKey < ActiveRecord::Migration[5.0]\n  def up\n    drop_table :divisions\n    create_table :divisions, primary_key: 'custom_id' do |t|\n      t.timestamps null: false\n      t.integer :league_id\n      t.string :name, limit: 50, null: false\n    end\n  end\n\n  def down\n    drop_table :divisions\n    create_table :divisions do |t|\n      t.timestamps null: false\n      t.integer :league_id\n      t.string :name, limit: 50, null: false\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110901142530_rename_league_id_foreign_key_on_divisions.rb",
    "content": "# frozen_string_literal: true\n\nclass RenameLeagueIdForeignKeyOnDivisions < ActiveRecord::Migration[5.0]\n  def change\n    rename_column :divisions, :league_id, :custom_league_id\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110901150912_set_primary_key_not_null_for_divisions.rb",
    "content": "# frozen_string_literal: true\n\nclass SetPrimaryKeyNotNullForDivisions < ActiveRecord::Migration[5.0]\n  def up\n    drop_table :divisions\n    create_table :divisions, id: false do |t|\n      t.timestamps null: false\n      t.primary_key :custom_id\n      t.integer :custom_league_id\n      t.string :name, limit: 50, null: false\n    end\n  end\n\n  def down\n    drop_table :divisions\n    create_table :divisions, primary_key: :custom_id do |t|\n      t.timestamps null: false\n      t.integer :custom_league_id\n      t.string :name, limit: 50, null: false\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20110901154834_change_length_for_rails_admin_histories.rb",
    "content": "# frozen_string_literal: true\n\nclass ChangeLengthForRailsAdminHistories < ActiveRecord::Migration[5.0]\n  def up\n    change_column :rails_admin_histories, :message, :text\n  end\n\n  def down\n    change_column :rails_admin_histories, :message, :string\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20111108143642_add_dragonfly_and_carrierwave_to_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass AddDragonflyAndCarrierwaveToFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    add_column :field_tests, :paperclip_asset_file_name, :string\n    add_column :field_tests, :dragonfly_asset_uid, :string\n    add_column :field_tests, :carrierwave_asset, :string\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20111115041025_add_type_to_balls.rb",
    "content": "# frozen_string_literal: true\n\nclass AddTypeToBalls < ActiveRecord::Migration[5.0]\n  def change\n    add_column :balls, :type, :string\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20111123092549_create_nested_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateNestedFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    create_table :nested_field_tests do |t|\n      t.string :title\n      t.integer :field_test_id\n\n      t.timestamps null: false\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20111130075338_add_dragonfly_asset_name_to_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass AddDragonflyAssetNameToFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    add_column :field_tests, :dragonfly_asset_name, :string\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20111215083258_create_foo_bars.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateFooBars < ActiveRecord::Migration[5.0]\n  def change\n    create_table :foo_bars do |t|\n      t.string :title\n      t.timestamps null: false\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20120117151733_add_custom_field_to_teams.rb",
    "content": "# frozen_string_literal: true\n\nclass AddCustomFieldToTeams < ActiveRecord::Migration[5.0]\n  def change\n    add_column :teams, :custom_field, :string\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20120118122004_add_categories.rb",
    "content": "# frozen_string_literal: true\n\nclass AddCategories < ActiveRecord::Migration[5.0]\n  def change\n    create_table :categories do |t|\n      t.integer :parent_category_id\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20120319041705_drop_rel_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass DropRelTests < ActiveRecord::Migration[5.0]\n  def self.up\n    drop_table :rel_tests\n  end\n\n  def self.down\n    create_table :rel_tests do |t|\n      t.integer :league_id\n      t.integer :division_id, null: false\n      t.integer :player_id\n\n      t.timestamps null: false\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20120720075608_create_another_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateAnotherFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    create_table :another_field_tests do |t|\n      t.timestamps null: false\n    end\n    add_column :nested_field_tests, :another_field_test_id, :integer\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20120928075608_create_images.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateImages < ActiveRecord::Migration[5.0]\n  def change\n    create_table :images do |t|\n      t.string :file_file_name\n      t.string :file_content_type\n      t.bigint :file_file_size\n      t.datetime :file_updated_at\n      t.timestamps null: false\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20140412075608_create_deeply_nested_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateDeeplyNestedFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    create_table :deeply_nested_field_tests do |t|\n      t.belongs_to :nested_field_test\n      t.string :title\n      t.timestamps null: false\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20140826093220_create_paper_trail_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass CreatePaperTrailTests < ActiveRecord::Migration[5.0]\n  def change\n    create_table :paper_trail_tests do |t|\n      t.string :name\n\n      t.timestamps null: false\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20140826093552_create_versions.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateVersions < ActiveRecord::Migration[5.0]\n  def change\n    create_table :versions do |t|\n      t.string :item_type, null: false\n      t.integer :item_id, null: false\n      t.string :event, null: false\n      t.string :whodunnit\n      t.text :object\n      t.datetime :created_at\n    end\n    add_index :versions, %i[item_type item_id]\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20150815102450_add_refile_to_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass AddRefileToFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    add_column :field_tests, :refile_asset_id, :string\n    add_column :field_tests, :refile_asset_filename, :string\n    add_column :field_tests, :refile_asset_size, :string\n    add_column :field_tests, :refile_asset_content_type, :string\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20151027181550_change_field_test_id_to_nested_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass ChangeFieldTestIdToNestedFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    change_column :nested_field_tests, :field_test_id, :integer, null: false\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20160728152942_add_main_sponsor_to_teams.rb",
    "content": "# frozen_string_literal: true\n\nclass AddMainSponsorToTeams < ActiveRecord::Migration[5.0]\n  def change\n    add_column :teams, :main_sponsor, :integer, default: 0, null: false\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20160728153058_add_formation_to_players.rb",
    "content": "# frozen_string_literal: true\n\nclass AddFormationToPlayers < ActiveRecord::Migration[5.0]\n  def change\n    add_column :players, :formation, :string, default: 'substitute', null: false\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20171229220713_add_enum_fields_to_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass AddEnumFieldsToFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    add_column :field_tests, :string_enum_field,  :string\n    add_column :field_tests, :integer_enum_field, :integer\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20180701084251_create_active_storage_tables.active_storage.rb",
    "content": "# frozen_string_literal: true\n\n# This migration comes from active_storage (originally 20170806125915)\nclass CreateActiveStorageTables < ActiveRecord::Migration[5.0]\n  def change\n    create_table :active_storage_blobs do |t|\n      t.string   :key,        null: false\n      t.string   :filename,   null: false\n      t.string   :content_type\n      t.text     :metadata\n      if t.respond_to? :bigint\n        t.bigint   :byte_size,  null: false\n      else\n        t.integer  :byte_size,  null: false\n      end\n      t.string   :checksum,   null: false\n      t.datetime :created_at, null: false\n\n      t.index [:key], unique: true\n    end\n\n    create_table :active_storage_attachments do |t|\n      t.string     :name,     null: false\n      t.references :record,   null: false, polymorphic: true, index: false\n      t.references :blob,     null: false\n\n      t.datetime :created_at, null: false\n\n      t.index %i[record_type record_id name blob_id], name: 'index_active_storage_attachments_uniqueness', unique: true\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20180707101855_add_carrierwave_assets_to_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass AddCarrierwaveAssetsToFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    add_column :field_tests, :carrierwave_assets, :string, after: :carrierwave_asset\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20181029101829_add_shrine_data_to_field_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass AddShrineDataToFieldTests < ActiveRecord::Migration[5.0]\n  def change\n    add_column :field_tests, :shrine_asset_data, :text\n    add_column :field_tests, :shrine_versioning_asset_data, :text\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20190531065324_create_action_text_tables.action_text.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateActionTextTables < ActiveRecord::Migration[5.0]\n  def change\n    create_table :action_text_rich_texts do |t|\n      t.string     :name, null: false\n      t.text       :body, size: :long\n      t.references :record, null: false, polymorphic: true, index: false\n\n      t.timestamps\n\n      t.index %i[record_type record_id name], name: 'index_action_text_rich_texts_uniqueness', unique: true\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20201127111952_update_active_storage_tables.rb",
    "content": "# frozen_string_literal: true\n\nclass UpdateActiveStorageTables < ActiveRecord::Migration[5.0]\n  def change\n    add_column :active_storage_blobs, :service_name, :string, null: false, default: 'local'\n    create_table :active_storage_variant_records do |t|\n      t.belongs_to :blob, null: false, index: false\n      t.string :variation_digest, null: false\n\n      t.index %i[blob_id variation_digest], name: 'index_active_storage_variant_records_uniqueness', unique: true\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20210811121027_create_two_level_namespaced_polymorphic_association_tests.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateTwoLevelNamespacedPolymorphicAssociationTests < ActiveRecord::Migration[5.0]\n  def change\n    create_table :two_level_namespaced_polymorphic_association_tests do |t|\n      t.string :name\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20210812115908_create_custom_versions.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateCustomVersions < ActiveRecord::Migration[5.0]\n  def change\n    create_table :custom_versions do |t|\n      t.string :item_type, null: false\n      t.integer :item_id, null: false\n      t.string :event, null: false\n      t.string :whodunnit\n      t.text :object\n      t.datetime :created_at\n    end\n    add_index :custom_versions, %i[item_type item_id]\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20211011235734_add_bool_field_open.rb",
    "content": "# frozen_string_literal: true\n\nclass AddBoolFieldOpen < ActiveRecord::Migration[6.0]\n  def change\n    add_column :field_tests, :open, :boolean\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20220416102741_create_composite_key_tables.rb",
    "content": "# frozen_string_literal: true\n\nclass CreateCompositeKeyTables < ActiveRecord::Migration[6.0]\n  def change\n    add_column :fans_teams, :since, :date\n\n    create_table :favorite_players, primary_key: %i[fan_id team_id player_id] do |t|\n      t.integer :fan_id, null: false\n      t.integer :team_id, null: false\n      t.integer :player_id, null: false\n      t.string :reason\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/migrate/20240921171953_add_non_nullable_boolean_field.rb",
    "content": "# frozen_string_literal: true\n\nclass AddNonNullableBooleanField < ActiveRecord::Migration[6.0]\n  def change\n    add_column :field_tests, :non_nullable_boolean_field, :boolean, null: false, default: false\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/schema.rb",
    "content": "# This file is auto-generated from the current state of the database. Instead\n# of editing this file, please use the migrations feature of Active Record to\n# incrementally modify your database, and then regenerate this schema definition.\n#\n# This file is the source Rails uses to define your schema when running `bin/rails\n# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to\n# be faster and is potentially less error prone than running all of your\n# migrations from scratch. Old migrations may fail to apply correctly if those\n# migrations use external dependencies or application code.\n#\n# It's strongly recommended that you check this file into your version control system.\n\nActiveRecord::Schema.define(version: 2024_09_21_171953) do\n  create_table \"action_text_rich_texts\", force: :cascade do |t|\n    t.string \"name\", null: false\n    t.text \"body\"\n    t.string \"record_type\", null: false\n    t.integer \"record_id\", null: false\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.index [\"record_type\", \"record_id\", \"name\"], name: \"index_action_text_rich_texts_uniqueness\", unique: true\n  end\n\n  create_table \"active_storage_attachments\", force: :cascade do |t|\n    t.string \"name\", null: false\n    t.string \"record_type\", null: false\n    t.integer \"record_id\", null: false\n    t.integer \"blob_id\", null: false\n    t.datetime \"created_at\", precision: nil, null: false\n    t.index [\"blob_id\"], name: \"index_active_storage_attachments_on_blob_id\"\n    t.index [\"record_type\", \"record_id\", \"name\", \"blob_id\"], name: \"index_active_storage_attachments_uniqueness\", unique: true\n  end\n\n  create_table \"active_storage_blobs\", force: :cascade do |t|\n    t.string \"key\", null: false\n    t.string \"filename\", null: false\n    t.string \"content_type\"\n    t.text \"metadata\"\n    t.bigint \"byte_size\", null: false\n    t.string \"checksum\", null: false\n    t.datetime \"created_at\", precision: nil, null: false\n    t.string \"service_name\", default: \"local\", null: false\n    t.index [\"key\"], name: \"index_active_storage_blobs_on_key\", unique: true\n  end\n\n  create_table \"active_storage_variant_records\", force: :cascade do |t|\n    t.integer \"blob_id\", null: false\n    t.string \"variation_digest\", null: false\n    t.index [\"blob_id\", \"variation_digest\"], name: \"index_active_storage_variant_records_uniqueness\", unique: true\n  end\n\n  create_table \"another_field_tests\", force: :cascade do |t|\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n  end\n\n  create_table \"balls\", force: :cascade do |t|\n    t.string \"color\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.string \"type\"\n  end\n\n  create_table \"categories\", force: :cascade do |t|\n    t.integer \"parent_category_id\"\n  end\n\n  create_table \"cms_basic_pages\", force: :cascade do |t|\n    t.string \"title\"\n    t.text \"content\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n  end\n\n  create_table \"comments\", force: :cascade do |t|\n    t.integer \"commentable_id\"\n    t.string \"commentable_type\"\n    t.text \"content\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n  end\n\n  create_table \"custom_versions\", force: :cascade do |t|\n    t.string \"item_type\", null: false\n    t.integer \"item_id\", null: false\n    t.string \"event\", null: false\n    t.string \"whodunnit\"\n    t.text \"object\"\n    t.datetime \"created_at\", precision: nil\n    t.index [\"item_type\", \"item_id\"], name: \"index_custom_versions_on_item_type_and_item_id\"\n  end\n\n  create_table \"deeply_nested_field_tests\", force: :cascade do |t|\n    t.integer \"nested_field_test_id\"\n    t.string \"title\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.index [\"nested_field_test_id\"], name: \"index_deeply_nested_field_tests_on_nested_field_test_id\"\n  end\n\n  create_table \"divisions\", primary_key: \"custom_id\", force: :cascade do |t|\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.integer \"custom_league_id\"\n    t.string \"name\", limit: 50, null: false\n  end\n\n  create_table \"drafts\", force: :cascade do |t|\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.integer \"player_id\"\n    t.integer \"team_id\"\n    t.date \"date\"\n    t.integer \"round\"\n    t.integer \"pick\"\n    t.integer \"overall\"\n    t.string \"college\", limit: 100\n    t.text \"notes\"\n  end\n\n  create_table \"fans\", force: :cascade do |t|\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.string \"name\", limit: 100, null: false\n  end\n\n  create_table \"fans_teams\", id: false, force: :cascade do |t|\n    t.integer \"fan_id\"\n    t.integer \"team_id\"\n    t.date \"since\"\n  end\n\n  create_table \"favorite_players\", primary_key: [\"fan_id\", \"team_id\", \"player_id\"], force: :cascade do |t|\n    t.integer \"fan_id\", null: false\n    t.integer \"team_id\", null: false\n    t.integer \"player_id\", null: false\n    t.string \"reason\"\n    t.datetime \"created_at\", null: false\n    t.datetime \"updated_at\", null: false\n  end\n\n  create_table \"field_tests\", force: :cascade do |t|\n    t.string \"string_field\"\n    t.text \"text_field\"\n    t.integer \"integer_field\"\n    t.float \"float_field\"\n    t.decimal \"decimal_field\"\n    t.datetime \"datetime_field\", precision: nil\n    t.datetime \"timestamp_field\", precision: nil\n    t.time \"time_field\"\n    t.date \"date_field\"\n    t.boolean \"boolean_field\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.string \"format\"\n    t.string \"restricted_field\"\n    t.string \"protected_field\"\n    t.string \"paperclip_asset_file_name\"\n    t.string \"dragonfly_asset_uid\"\n    t.string \"carrierwave_asset\"\n    t.string \"dragonfly_asset_name\"\n    t.string \"refile_asset_id\"\n    t.string \"refile_asset_filename\"\n    t.string \"refile_asset_size\"\n    t.string \"refile_asset_content_type\"\n    t.string \"string_enum_field\"\n    t.integer \"integer_enum_field\"\n    t.string \"carrierwave_assets\"\n    t.text \"shrine_asset_data\"\n    t.text \"shrine_versioning_asset_data\"\n    t.boolean \"open\"\n    t.boolean \"non_nullable_boolean_field\", default: false, null: false\n  end\n\n  create_table \"foo_bars\", force: :cascade do |t|\n    t.string \"title\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n  end\n\n  create_table \"images\", force: :cascade do |t|\n    t.string \"file_file_name\"\n    t.string \"file_content_type\"\n    t.bigint \"file_file_size\"\n    t.datetime \"file_updated_at\", precision: nil\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n  end\n\n  create_table \"leagues\", force: :cascade do |t|\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.string \"name\", limit: 50, null: false\n  end\n\n  create_table \"nested_field_tests\", force: :cascade do |t|\n    t.string \"title\"\n    t.integer \"field_test_id\", null: false\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.integer \"another_field_test_id\"\n  end\n\n  create_table \"paper_trail_tests\", force: :cascade do |t|\n    t.string \"name\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n  end\n\n  create_table \"players\", force: :cascade do |t|\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.datetime \"deleted_at\", precision: nil\n    t.integer \"team_id\"\n    t.string \"name\", limit: 100, null: false\n    t.string \"position\", limit: 50\n    t.integer \"number\", null: false\n    t.boolean \"retired\", default: false\n    t.boolean \"injured\", default: false\n    t.date \"born_on\"\n    t.text \"notes\"\n    t.boolean \"suspended\", default: false\n    t.string \"formation\", default: \"substitute\", null: false\n  end\n\n  create_table \"rails_admin_histories\", force: :cascade do |t|\n    t.text \"message\"\n    t.string \"username\"\n    t.integer \"item\"\n    t.string \"table\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.index [\"item\", \"table\"], name: \"index_rails_admin_histories_on_item_and_table\"\n  end\n\n  create_table \"teams\", force: :cascade do |t|\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.integer \"division_id\"\n    t.string \"name\", limit: 50\n    t.string \"logo_url\", limit: 255\n    t.string \"manager\", limit: 100, null: false\n    t.string \"ballpark\", limit: 100\n    t.string \"mascot\", limit: 100\n    t.integer \"founded\"\n    t.integer \"wins\"\n    t.integer \"losses\"\n    t.float \"win_percentage\"\n    t.decimal \"revenue\", precision: 18, scale: 2\n    t.string \"color\"\n    t.string \"custom_field\"\n    t.integer \"main_sponsor\", default: 0, null: false\n  end\n\n  create_table \"two_level_namespaced_polymorphic_association_tests\", force: :cascade do |t|\n    t.string \"name\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n  end\n\n  create_table \"users\", force: :cascade do |t|\n    t.string \"email\", default: \"\", null: false\n    t.string \"encrypted_password\", default: \"\", null: false\n    t.string \"reset_password_token\"\n    t.datetime \"reset_password_sent_at\", precision: nil\n    t.datetime \"remember_created_at\", precision: nil\n    t.integer \"sign_in_count\", default: 0\n    t.datetime \"current_sign_in_at\", precision: nil\n    t.datetime \"last_sign_in_at\", precision: nil\n    t.string \"current_sign_in_ip\"\n    t.string \"last_sign_in_ip\"\n    t.string \"password_salt\"\n    t.datetime \"created_at\", precision: nil, null: false\n    t.datetime \"updated_at\", precision: nil, null: false\n    t.string \"avatar_file_name\"\n    t.string \"avatar_content_type\"\n    t.integer \"avatar_file_size\"\n    t.datetime \"avatar_updated_at\", precision: nil\n    t.string \"roles\"\n    t.index [\"email\"], name: \"index_users_on_email\", unique: true\n    t.index [\"reset_password_token\"], name: \"index_users_on_reset_password_token\", unique: true\n  end\n\n  create_table \"versions\", force: :cascade do |t|\n    t.string \"item_type\", null: false\n    t.integer \"item_id\", null: false\n    t.string \"event\", null: false\n    t.string \"whodunnit\"\n    t.text \"object\"\n    t.datetime \"created_at\", precision: nil\n    t.index [\"item_type\", \"item_id\"], name: \"index_versions_on_item_type_and_item_id\"\n  end\nend\n"
  },
  {
    "path": "spec/dummy_app/db/seeds.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'mlb'\n\nuser_model     = RailsAdmin::AbstractModel.new(User)\nleague_model   = RailsAdmin::AbstractModel.new(League)\ndivision_model = RailsAdmin::AbstractModel.new(Division)\nteam_model     = RailsAdmin::AbstractModel.new(Team)\nplayer_model   = RailsAdmin::AbstractModel.new(Player)\n\nuser_model.new(email: 'username@example.com', password: 'password', password_confirmation: 'password').save\n\nMLB::Teams.all(season: Time.now.year).each do |mlb_team|\n  league = league_model.where(name: mlb_team.league.name).first\n  unless league\n    league = league_model.model.new(name: mlb_team.league.name)\n    league.save!\n  end\n  division = division_model.where(name: mlb_team.division.name).first\n  unless division\n    division = division_model.model.new(name: mlb_team.division.name, league: league)\n    division.save!\n  end\n  team = team_model.where(name: mlb_team.name).first\n  unless team\n    team = team_model.model.new(name: mlb_team.name, logo_url: mlb_team.link, manager: 'None', ballpark: mlb_team.venue.name, founded: mlb_team.first_year_of_play, wins: 0, losses: 0, win_percentage: 0.0, division: division)\n    team.save!\n  end\n  mlb_team.roster.reject { |roster| roster.jersey_number.nil? }.each do |roster|\n    player_model.model.new(name: roster.player.full_name, number: roster.jersey_number, position: roster.position.name, team: team).save\n  end\nend\n\nputs \"Seeded #{league_model.count} leagues, #{division_model.count} divisions, #{team_model.count} teams and #{player_model.count} players\"\n"
  },
  {
    "path": "spec/dummy_app/doc/README_FOR_APP",
    "content": "Use this README file to introduce your application and point to useful places in the API for learning more.\nRun \"rake doc:app\" to generate API documentation for your models, controllers, helpers, and libraries.\n"
  },
  {
    "path": "spec/dummy_app/fly.toml",
    "content": "# fly.toml app configuration file generated for rails-admin on 2023-08-06T18:22:31+09:00\n#\n# See https://fly.io/docs/reference/configuration/ for information about how to use this file.\n#\n\napp = \"rails-admin\"\nprimary_region = \"iad\"\nconsole_command = \"/rails/bin/rails console\"\n\n[build]\n\n[http_service]\n  internal_port = 3000\n  force_https = true\n  auto_stop_machines = true\n  auto_start_machines = true\n  min_machines_running = 0\n  processes = [\"app\"]\n\n[[statics]]\n  guest_path = \"/rails/public\"\n  url_prefix = \"/\"\n"
  },
  {
    "path": "spec/dummy_app/lib/assets/.gitkeep",
    "content": ""
  },
  {
    "path": "spec/dummy_app/lib/does_not_load_autoload_paths_not_in_eager_load.rb",
    "content": "# frozen_string_literal: true\n\nmodule DoesNotLoadAutoloadPathsNotInEagerLoad\n  raise 'This file is in app.paths.autoload but not app.paths.eager_load and ' \\\n        ' should not be autoloaded by rails_admin'\nend\n"
  },
  {
    "path": "spec/dummy_app/lib/tasks/.gitkeep",
    "content": ""
  },
  {
    "path": "spec/dummy_app/package.json",
    "content": "{\n  \"name\": \"dummy_app\",\n  \"private\": true,\n  \"version\": \"0.1.0\",\n  \"dependencies\": {\n    \"@babel/plugin-proposal-private-methods\": \"^7.18.6\",\n    \"@babel/plugin-proposal-private-property-in-object\": \"^7.21.11\",\n    \"@rails/actiontext\": \"^7.0.3-1\",\n    \"@rails/activestorage\": \"^7.0.3-1\",\n    \"@rails/webpacker\": \"5.4.3\",\n    \"rails_admin\": \"file:../..\",\n    \"trix\": \"^2.0.0-beta.0\",\n    \"webpack\": \"^4.46.0\",\n    \"webpack-cli\": \"^3.3.12\"\n  },\n  \"devDependencies\": {\n    \"vite\": \"^5.0\",\n    \"vite-plugin-ruby\": \">=5.0 <6\",\n    \"webpack-dev-server\": \"^3\"\n  },\n  \"scripts\": {\n    \"build\": \"webpack --config webpack.config.js\",\n    \"build:css\": \"sass ./app/assets/stylesheets/rails_admin.scss:./app/assets/builds/rails_admin.css --no-source-map --load-path=node_modules\"\n  }\n}\n"
  },
  {
    "path": "spec/dummy_app/postcss.config.js",
    "content": "module.exports = {\n  plugins: [\n    require(\"postcss-import\"),\n    require(\"postcss-flexbugs-fixes\"),\n    require(\"postcss-preset-env\")({\n      autoprefixer: {\n        flexbox: \"no-2009\",\n      },\n      stage: 3,\n    }),\n  ],\n};\n"
  },
  {
    "path": "spec/dummy_app/public/404.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>The page you were looking for doesn't exist (404)</title>\n    <style type=\"text/css\">\n      body {\n        background-color: #fff;\n        color: #666;\n        text-align: center;\n        font-family: arial, sans-serif;\n      }\n      div.dialog {\n        width: 25em;\n        padding: 0 4em;\n        margin: 4em auto 0 auto;\n        border: 1px solid #ccc;\n        border-right-color: #999;\n        border-bottom-color: #999;\n      }\n      h1 {\n        font-size: 100%;\n        color: #f00;\n        line-height: 1.5em;\n      }\n    </style>\n  </head>\n\n  <body>\n    <!-- This file lives in public/404.html -->\n    <div class=\"dialog\">\n      <h1>The page you were looking for doesn't exist.</h1>\n      <p>You may have mistyped the address or the page may have moved.</p>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "spec/dummy_app/public/422.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>The change you wanted was rejected (422)</title>\n    <style type=\"text/css\">\n      body {\n        background-color: #fff;\n        color: #666;\n        text-align: center;\n        font-family: arial, sans-serif;\n      }\n      div.dialog {\n        width: 25em;\n        padding: 0 4em;\n        margin: 4em auto 0 auto;\n        border: 1px solid #ccc;\n        border-right-color: #999;\n        border-bottom-color: #999;\n      }\n      h1 {\n        font-size: 100%;\n        color: #f00;\n        line-height: 1.5em;\n      }\n    </style>\n  </head>\n\n  <body>\n    <!-- This file lives in public/422.html -->\n    <div class=\"dialog\">\n      <h1>The change you wanted was rejected.</h1>\n      <p>Maybe you tried to change something you didn't have access to.</p>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "spec/dummy_app/public/500.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>We're sorry, but something went wrong (500)</title>\n    <style type=\"text/css\">\n      body {\n        background-color: #fff;\n        color: #666;\n        text-align: center;\n        font-family: arial, sans-serif;\n      }\n      div.dialog {\n        width: 25em;\n        padding: 0 4em;\n        margin: 4em auto 0 auto;\n        border: 1px solid #ccc;\n        border-right-color: #999;\n        border-bottom-color: #999;\n      }\n      h1 {\n        font-size: 100%;\n        color: #f00;\n        line-height: 1.5em;\n      }\n    </style>\n  </head>\n\n  <body>\n    <!-- This file lives in public/500.html -->\n    <div class=\"dialog\">\n      <h1>We're sorry, but something went wrong.</h1>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "spec/dummy_app/public/robots.txt",
    "content": "# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file\n#\n# To ban all spiders from the entire site uncomment the next two lines:\n# User-Agent: *\n# Disallow: /\n"
  },
  {
    "path": "spec/dummy_app/public/system/dragonfly/development/2011/11/24/10_36_27_888_Pensive_Parakeet.jpg.meta",
    "content": "\u0004\b{\b:\tnameI\"\u0019Pensive Parakeet.jpg\u0006:\u0006ET:\u0010model_classI\"\u000eFieldTest\u0006;\u0006F:\u0015model_attachment:\u0014dragonfly_asset"
  },
  {
    "path": "spec/dummy_app/public/system/dragonfly/development/2011/11/30/08_54_39_906_Costa_Rican_Frog.jpg.meta",
    "content": "\u0004\b{\b:\tnameI\"\u0019Costa Rican Frog.jpg\u0006:\u0006ET:\u0010model_classI\"\u000eFieldTest\u0006;\u0006F:\u0015model_attachment:\u0014dragonfly_asset"
  },
  {
    "path": "spec/dummy_app/vendor/javascript/.keep",
    "content": ""
  },
  {
    "path": "spec/dummy_app/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport RubyPlugin from \"vite-plugin-ruby\";\n\nexport default defineConfig({\n  plugins: [RubyPlugin()],\n});\n"
  },
  {
    "path": "spec/dummy_app/webpack.config.js",
    "content": "const path = require(\"path\");\nconst webpack = require(\"webpack\");\n\nmodule.exports = {\n  mode: \"production\",\n  devtool: \"source-map\",\n  entry: {\n    application: \"./app/javascript/application.js\",\n    rails_admin: \"./app/javascript/rails_admin.js\",\n  },\n  output: {\n    filename: \"[name].js\",\n    sourceMapFilename: \"[name].js.map\",\n    path: path.resolve(__dirname, \"app/assets/builds\"),\n  },\n  plugins: [\n    new webpack.optimize.LimitChunkCountPlugin({\n      maxChunks: 1,\n    }),\n  ],\n};\n"
  },
  {
    "path": "spec/factories.rb",
    "content": "# frozen_string_literal: true\n\nFactoryBot.define do\n  factory :player do\n    sequence(:name) { |n| \"Player #{n}\" }\n    sequence(:number) { |n| n }\n    sequence(:position) { |n| \"Position #{n}\" }\n  end\n\n  factory :draft do\n    date { 1.week.ago }\n    sequence(:round)\n    sequence(:pick)\n    sequence(:overall)\n    sequence(:college) { |n| \"College #{n}\" }\n    association :team\n    association :player\n  end\n\n  factory :team do\n    sequence(:division_id)\n    sequence(:name) { |n| \"Team #{n}\" }\n    sequence(:manager) { |n| \"Manager #{n}\" }\n    sequence(:founded)\n    sequence(:wins)\n    sequence(:losses)\n    sequence(:win_percentage)\n\n    factory :managed_team, class: ManagedTeam\n    factory :restricted_team, class: RestrictedTeam\n  end\n\n  factory :league do\n    sequence(:name) { |n| \"League #{n}\" }\n  end\n\n  factory :division do\n    sequence(:custom_league_id)\n    sequence(:name) { |n| \"Division #{n}\" }\n  end\n\n  factory :fan do\n    sequence(:name) { |n| \"Fan #{n}\" }\n  end\n\n  factory :fanship do\n    association :fan\n    association :team\n  end\n\n  factory :favorite_player do\n    association :fanship\n    association :player\n  end\n\n  factory :user do\n    sequence(:email) { |n| \"username_#{n}@example.com\" }\n    sequence(:password) { |_n| 'password' }\n\n    factory :user_confirmed, class: User::Confirmed\n    factory :managing_user, class: ManagingUser\n  end\n\n  factory :field_test do\n  end\n\n  factory :comment do\n    sequence(:content) do |n|\n      <<-LOREM_IPSUM\n        Lorém --#{n}-- ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\n        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\n        quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n        consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\n        cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\n        proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\"\n      LOREM_IPSUM\n    end\n\n    factory :comment_confirmed, class: Comment::Confirmed do\n      content { 'something' }\n    end\n  end\n\n  factory :ball do\n    color { %w[red blue green yellow purple brown black white].sample }\n  end\n\n  factory :hardball do\n    color { 'blue' }\n  end\n\n  factory :image do\n    file { File.open(Rails.root.join('public', 'robots.txt')) }\n  end\n\n  factory :paper_trail_test do\n    sequence(:name) { |n| \"name #{n}\" }\n\n    factory :paper_trail_test_subclass,\n            parent: :paper_trail_test,\n            class: 'PaperTrailTestSubclass'\n\n    factory :paper_trail_test_subclass_in_namespace,\n            parent: :paper_trail_test,\n            class: 'PaperTrailTest::SubclassInNamespace'\n\n    factory :paper_trail_test_with_custom_association,\n            parent: :paper_trail_test,\n            class: 'PaperTrailTestWithCustomAssociation'\n  end\n\n  factory :two_level_namespaced_polymorphic_association_test, class: 'TwoLevel::Namespaced::PolymorphicAssociationTest' do\n    sequence(:name) { |n| \"name #{n}\" }\n  end\nend\n"
  },
  {
    "path": "spec/fixtures/test.txt",
    "content": "test"
  },
  {
    "path": "spec/helpers/rails_admin/application_helper_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::ApplicationHelper, type: :helper do\n  describe '#authorized?' do\n    let(:abstract_model) { RailsAdmin.config(FieldTest).abstract_model }\n\n    it 'doesn\\'t use unpersisted objects' do\n      expect(helper).to receive(:action).with(:edit, abstract_model, nil).and_call_original\n      helper.authorized?(:edit, abstract_model, FactoryBot.build(:field_test))\n    end\n  end\n\n  describe 'with #authorized? stubbed' do\n    before do\n      allow(controller).to receive(:authorized?).and_return(true)\n    end\n\n    describe '#current_action?' do\n      it 'returns true if current_action, false otherwise' do\n        @action = RailsAdmin::Config::Actions.find(:index)\n\n        expect(helper.current_action?(RailsAdmin::Config::Actions.find(:index))).to be_truthy\n        expect(helper.current_action?(RailsAdmin::Config::Actions.find(:show))).not_to be_truthy\n      end\n    end\n\n    describe '#action' do\n      it 'returns action by :custom_key' do\n        RailsAdmin.config do |config|\n          config.actions do\n            dashboard do\n              custom_key :my_custom_dashboard_key\n            end\n          end\n        end\n        expect(helper.action(:my_custom_dashboard_key)).to be\n      end\n\n      it 'returns only visible actions' do\n        RailsAdmin.config do |config|\n          config.actions do\n            dashboard do\n              visible false\n            end\n          end\n        end\n\n        expect(helper.action(:dashboard)).to be_nil\n      end\n\n      it 'returns only visible actions, passing all bindings' do\n        RailsAdmin.config do |config|\n          config.actions do\n            member :test_bindings do\n              visible do\n                bindings[:controller].is_a?(ActionView::TestCase::TestController) &&\n                  bindings[:abstract_model].model == Team &&\n                  bindings[:object].is_a?(Team)\n              end\n            end\n          end\n        end\n        expect(helper.action(:test_bindings, RailsAdmin::AbstractModel.new(Team), Team.new)).to be\n        expect(helper.action(:test_bindings, RailsAdmin::AbstractModel.new(Team), Player.new)).to be_nil\n        expect(helper.action(:test_bindings, RailsAdmin::AbstractModel.new(Player), Team.new)).to be_nil\n      end\n    end\n\n    describe '#actions' do\n      it 'returns actions by type' do\n        abstract_model = RailsAdmin::AbstractModel.new(Player)\n        object = FactoryBot.create :player\n        expect(helper.actions(:all, abstract_model, object).collect(&:custom_key)).to eq(%i[dashboard index show new edit export delete bulk_delete history_show history_index show_in_app])\n        expect(helper.actions(:root, abstract_model, object).collect(&:custom_key)).to eq([:dashboard])\n        expect(helper.actions(:collection, abstract_model, object).collect(&:custom_key)).to eq(%i[index new export bulk_delete history_index])\n        expect(helper.actions(:member, abstract_model, object).collect(&:custom_key)).to eq(%i[show edit delete history_show show_in_app])\n      end\n\n      it 'only returns visible actions, passing bindings correctly' do\n        RailsAdmin.config do |config|\n          config.actions do\n            member :test_bindings do\n              visible do\n                bindings[:controller].is_a?(ActionView::TestCase::TestController) &&\n                  bindings[:abstract_model].model == Team &&\n                  bindings[:object].is_a?(Team)\n              end\n            end\n          end\n        end\n\n        expect(helper.actions(:all, RailsAdmin::AbstractModel.new(Team), Team.new).collect(&:custom_key)).to eq([:test_bindings])\n        expect(helper.actions(:all, RailsAdmin::AbstractModel.new(Team), Player.new).collect(&:custom_key)).to eq([])\n        expect(helper.actions(:all, RailsAdmin::AbstractModel.new(Player), Team.new).collect(&:custom_key)).to eq([])\n      end\n    end\n\n    describe '#logout_method' do\n      it 'defaults to :delete when Devise is not defined' do\n        allow(Object).to receive(:defined?).with(Devise).and_return(false)\n\n        expect(helper.logout_method).to eq(:delete)\n      end\n\n      it 'uses first sign out method from Devise when it is defined' do\n        allow(Object).to receive(:defined?).with(Devise).and_return(true)\n\n        expect(Devise).to receive(:sign_out_via).and_return(%i[whatever_defined_on_devise something_ignored])\n        expect(helper.logout_method).to eq(:whatever_defined_on_devise)\n      end\n    end\n\n    describe '#wording_for' do\n      it 'gives correct wording even if action is not visible' do\n        RailsAdmin.config do |config|\n          config.actions do\n            index do\n              visible false\n            end\n          end\n        end\n\n        expect(helper.wording_for(:menu, :index)).to eq('List')\n      end\n\n      it 'passes correct bindings' do\n        expect(helper.wording_for(:title, :edit, RailsAdmin::AbstractModel.new(Team), Team.new(name: 'the avengers'))).to eq(\"Edit Team 'the avengers'\")\n      end\n\n      it 'defaults correct bindings' do\n        @action = RailsAdmin::Config::Actions.find :edit\n        @abstract_model = RailsAdmin::AbstractModel.new(Team)\n        @object = Team.new(name: 'the avengers')\n        expect(helper.wording_for(:title)).to eq(\"Edit Team 'the avengers'\")\n      end\n\n      it 'does not try to use the wrong :label_metod' do\n        @abstract_model = RailsAdmin::AbstractModel.new(Draft)\n        @object = Draft.new\n\n        expect(helper.wording_for(:link, :new, RailsAdmin::AbstractModel.new(Team))).to eq('Add a new Team')\n      end\n    end\n\n    describe '#breadcrumb' do\n      it 'gives us a breadcrumb' do\n        @action = RailsAdmin::Config::Actions.find(:edit, abstract_model: RailsAdmin::AbstractModel.new(Team), object: FactoryBot.create(:team, name: 'the avengers'))\n        bc = helper.breadcrumb\n        expect(bc).to match(/Dashboard/) # dashboard\n        expect(bc).to match(/Teams/) # list\n        expect(bc).to match(/the avengers/) # show\n        expect(bc).to match(/Edit/) # current (edit)\n      end\n    end\n\n    describe '#menu_for' do\n      it 'passes model and object as bindings and generates a menu, excluding non-get actions' do\n        RailsAdmin.config do |config|\n          config.actions do\n            dashboard\n            index do\n              visible do\n                bindings[:abstract_model].model == Team\n              end\n            end\n            show do\n              visible do\n                bindings[:object].instance_of?(Team)\n              end\n            end\n            delete do\n              http_methods %i[post put delete]\n            end\n          end\n        end\n\n        @action = RailsAdmin::Config::Actions.find :show\n        @abstract_model = RailsAdmin::AbstractModel.new(Team)\n        @object = FactoryBot.create(:team, name: 'the avengers')\n\n        expect(helper.menu_for(:root)).to match(/Dashboard/)\n        expect(helper.menu_for(:collection, @abstract_model)).to match(/List/)\n        expect(helper.menu_for(:member, @abstract_model, @object)).to match(/Show/)\n\n        @abstract_model = RailsAdmin::AbstractModel.new(Player)\n        @object = Player.new\n        expect(helper.menu_for(:collection, @abstract_model)).not_to match(/List/)\n        expect(helper.menu_for(:member, @abstract_model, @object)).not_to match(/Show/)\n      end\n\n      it 'excludes non-get actions' do\n        RailsAdmin.config do |config|\n          config.actions do\n            dashboard do\n              http_methods %i[post put delete]\n            end\n          end\n        end\n\n        @action = RailsAdmin::Config::Actions.find :dashboard\n        expect(helper.menu_for(:root)).not_to match(/Dashboard/)\n      end\n\n      it 'shows actions which are marked as show_in_menu' do\n        I18n.backend.store_translations(\n          :en, admin: {actions: {\n            shown_in_menu: {menu: 'Look this'},\n          }}\n        )\n        RailsAdmin.config do |config|\n          config.actions do\n            dashboard do\n              show_in_menu false\n            end\n            root :shown_in_menu, :dashboard do\n              action_name :dashboard\n              show_in_menu true\n            end\n          end\n        end\n\n        @action = RailsAdmin::Config::Actions.find :dashboard\n        expect(helper.menu_for(:root)).not_to match(/Dashboard/)\n        expect(helper.menu_for(:root)).to match(/Look this/)\n      end\n\n      it 'should render allow an action to have link_target as config' do\n        RailsAdmin.config do |config|\n          config.actions do\n            dashboard\n            index\n            show do\n              link_target :_blank\n            end\n          end\n        end\n\n        @action = RailsAdmin::Config::Actions.find :show\n        @abstract_model = RailsAdmin::AbstractModel.new(Team)\n        @object = FactoryBot.create(:team, name: 'the avengers')\n\n        expect(helper.menu_for(:member, @abstract_model, @object)).to match(/_blank/)\n      end\n    end\n\n    describe '#main_navigation' do\n      it 'shows included models' do\n        RailsAdmin.config do |config|\n          config.included_models = [Ball, Comment]\n        end\n        expect(helper.main_navigation).to match(/(btn-toggle).*(Navigation).*(Balls).*(Comments)/m)\n      end\n\n      it 'does not draw empty navigation labels' do\n        RailsAdmin.config do |config|\n          config.included_models = [Ball, Comment, Comment::Confirmed]\n          config.model Comment do\n            navigation_label 'Commentz'\n          end\n          config.model Comment::Confirmed do\n            label_plural 'Confirmed'\n          end\n        end\n        expect(helper.main_navigation).to match(/(btn-toggle).*(Navigation).*(Balls).*(Commentz).*(Confirmed)/m)\n        expect(helper.main_navigation).not_to match(/(btn-toggle).*(Navigation).*(Balls).*(Commentz).*(Confirmed).*(Comment)/m)\n      end\n\n      it 'does not show unvisible models' do\n        RailsAdmin.config do |config|\n          config.included_models = [Ball, Comment]\n          config.model Comment do\n            hide\n          end\n        end\n        result = helper.main_navigation\n        expect(result).to match(/(btn-toggle).*(Navigation).*(Balls)/m)\n        expect(result).not_to match('Comments')\n      end\n\n      it 'shows children of hidden models' do # https://github.com/railsadminteam/rails_admin/issues/978\n        RailsAdmin.config do |config|\n          config.included_models = [Ball, Hardball]\n          config.model Ball do\n            hide\n          end\n        end\n        expect(helper.main_navigation).to match(/(btn-toggle).*(Navigation).*(Hardballs)/m)\n      end\n\n      it 'shows children of excluded models' do\n        RailsAdmin.config do |config|\n          config.included_models = [Hardball]\n        end\n        expect(helper.main_navigation).to match(/(btn-toggle).*(Navigation).*(Hardballs)/m)\n      end\n\n      it 'nests in navigation label' do\n        RailsAdmin.config do |config|\n          config.included_models = [Comment]\n          config.model Comment do\n            navigation_label 'commentable'\n          end\n        end\n        expect(helper.main_navigation).to match(/(btn-toggle).*(commentable).*(Comments)/m)\n      end\n\n      it 'nests in parent model' do\n        RailsAdmin.config do |config|\n          config.included_models = [Player, Comment]\n          config.model Comment do\n            parent Player\n          end\n        end\n        expect(helper.main_navigation).to match(/(Players).* (nav-level-1).*(Comments)/m)\n      end\n\n      it 'orders' do\n        RailsAdmin.config do |config|\n          config.included_models = [Player, Comment]\n        end\n        expect(helper.main_navigation).to match(/(Comments).*(Players)/m)\n\n        RailsAdmin.config(Comment) do\n          weight 1\n        end\n        expect(helper.main_navigation).to match(/(Players).*(Comments)/m)\n      end\n    end\n\n    describe '#root_navigation' do\n      it 'shows actions which are marked as show_in_sidebar' do\n        I18n.backend.store_translations(\n          :en, admin: {actions: {\n            shown_in_sidebar: {menu: 'Look this'},\n          }}\n        )\n        RailsAdmin.config do |config|\n          config.actions do\n            dashboard do\n              show_in_sidebar false\n            end\n            root :shown_in_sidebar, :dashboard do\n              action_name :dashboard\n              show_in_sidebar true\n            end\n          end\n        end\n\n        expect(helper.root_navigation).not_to match(/Dashboard/)\n        expect(helper.root_navigation).to match(/Look this/)\n      end\n\n      it 'allows grouping by sidebar_label' do\n        I18n.backend.store_translations(\n          :en, admin: {\n            actions: {\n              foo: {menu: 'Foo'},\n              bar: {menu: 'Bar'},\n            },\n          }\n        )\n        RailsAdmin.config do |config|\n          config.actions do\n            dashboard do\n              show_in_sidebar true\n              sidebar_label 'One'\n            end\n            root :foo, :dashboard do\n              action_name :dashboard\n              show_in_sidebar true\n              sidebar_label 'Two'\n            end\n            root :bar, :dashboard do\n              action_name :dashboard\n              show_in_sidebar true\n              sidebar_label 'Two'\n            end\n          end\n        end\n\n        expect(helper.strip_tags(helper.root_navigation).delete(' ')).to eq 'OneDashboardTwoFooBar'\n      end\n    end\n\n    describe '#static_navigation' do\n      it 'shows not show static nav if no static links defined' do\n        RailsAdmin.config do |config|\n          config.navigation_static_links = {}\n        end\n        expect(helper.static_navigation).to be_empty\n      end\n\n      it 'shows links if defined' do\n        RailsAdmin.config do |config|\n          config.navigation_static_links = {\n            'Test Link' => 'http://www.google.com',\n          }\n        end\n        expect(helper.static_navigation).to match(/Test Link/)\n      end\n\n      it 'shows default header if navigation_static_label not defined in config' do\n        RailsAdmin.config do |config|\n          config.navigation_static_links = {\n            'Test Link' => 'http://www.google.com',\n          }\n        end\n        expect(helper.static_navigation).to match(I18n.t('admin.misc.navigation_static_label'))\n      end\n\n      it 'shows custom header if defined' do\n        RailsAdmin.config do |config|\n          config.navigation_static_label = 'Test Header'\n          config.navigation_static_links = {\n            'Test Link' => 'http://www.google.com',\n          }\n        end\n        expect(helper.static_navigation).to match(/Test Header/)\n      end\n    end\n\n    describe '#bulk_menu' do\n      it 'includes all visible bulkable actions' do\n        RailsAdmin.config do |config|\n          config.actions do\n            index\n            collection :zorg do\n              bulkable true\n              action_name :zorg_action\n            end\n            collection :blub do\n              bulkable true\n              visible do\n                bindings[:abstract_model].model == Team\n              end\n            end\n          end\n        end\n        # Preload all models to prevent I18n being cleared in Mongoid builds\n        RailsAdmin::AbstractModel.all\n        en = {admin: {actions: {\n          zorg: {bulk_link: 'Zorg all these %{model_label_plural}'},\n          blub: {bulk_link: 'Blub all these %{model_label_plural}'},\n        }}}\n        I18n.backend.store_translations(:en, en)\n\n        @abstract_model = RailsAdmin::AbstractModel.new(Team)\n        result = helper.bulk_menu\n\n        expect(result).to match('zorg_action')\n        expect(result).to match('Zorg all these Teams')\n        expect(result).to match('blub')\n        expect(result).to match('Blub all these Teams')\n\n        result_2 = helper.bulk_menu(RailsAdmin::AbstractModel.new(Player))\n        expect(result_2).to match('zorg_action')\n        expect(result_2).to match('Zorg all these Players')\n        expect(result_2).not_to match('blub')\n        expect(result_2).not_to match('Blub all these Players')\n      end\n    end\n\n    describe '#edit_user_link' do\n      subject { helper.edit_user_link }\n      let(:user) { FactoryBot.create(:user) }\n      before { allow(helper).to receive(:_current_user).and_return(user) }\n\n      it 'shows the edit action link of the user' do\n        is_expected.to match(%r{href=\"[^\"]+/admin/user/#{user.id}/edit\"})\n      end\n\n      it 'shows the gravatar icon' do\n        is_expected.to include('gravatar')\n      end\n\n      context \"when the user doesn't have the email column\" do\n        let(:user) { FactoryBot.create(:player) }\n\n        it 'shows nothing' do\n          is_expected.to be nil\n        end\n      end\n\n      context 'when gravatar is disabled' do\n        before { RailsAdmin.config.show_gravatar = false }\n\n        it \"doesn't show the gravatar icon\" do\n          is_expected.not_to include('gravatar')\n        end\n      end\n\n      context 'when the user is not authorized to perform edit' do\n        before do\n          allow_any_instance_of(RailsAdmin::Config::Actions::Edit).to receive(:authorized?).and_return(false)\n        end\n\n        it 'shows gravatar and email without a link' do\n          is_expected.to include('gravatar')\n          is_expected.to include(user.email)\n          is_expected.not_to match('href')\n        end\n\n        it 'shows only email without a link when gravatar is disabled' do\n          RailsAdmin.config do |config|\n            config.show_gravatar = false\n          end\n\n          is_expected.not_to include('gravatar')\n          is_expected.not_to match('href')\n          is_expected.to include(user.email)\n          is_expected.to match(\"<span class=\\\"nav-link\\\"><span>#{user.email}</span></span>\")\n        end\n      end\n    end\n  end\n\n  describe '#flash_alert_class' do\n    it 'makes errors red with alert-danger' do\n      expect(helper.flash_alert_class('error')).to eq('alert-danger')\n    end\n    it 'makes alerts yellow with alert-warning' do\n      expect(helper.flash_alert_class('alert')).to eq('alert-warning')\n    end\n    it 'makes notices blue with alert-info' do\n      expect(helper.flash_alert_class('notice')).to eq('alert-info')\n    end\n    it 'prefixes others with \"alert-\"' do\n      expect(helper.flash_alert_class('foo')).to eq('alert-foo')\n    end\n  end\nend\n"
  },
  {
    "path": "spec/helpers/rails_admin/form_builder_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin::FormBuilder', type: :helper do\n  describe '#generate' do\n    before do\n      RailsAdmin.config Player do\n        create do\n          include_all_fields\n          field :number, :hidden\n        end\n      end\n      allow(helper).to receive(:authorized?).and_return(true)\n      (@object = Player.new).save\n      @builder = RailsAdmin::FormBuilder.new(:player, @object, helper, {})\n      allow(@builder).to receive(:field_for).and_return('field')\n      action = double\n      allow(action).to receive(:enabled?).and_return true\n      helper.instance_variable_set :@action, action\n    end\n\n    it 'does not add additional error div from default ActionView::Base.field_error_proc' do\n      expect(@builder.generate(action: :create, model_config: RailsAdmin.config(Player))).not_to have_css('.field_with_errors')\n      expect(@builder.generate(action: :create, model_config: RailsAdmin.config(Player))).to have_css('.control-group.error')\n    end\n\n    it 'hidden fields should be wrapper' do\n      expect(@builder.generate(action: :create, model_config: RailsAdmin.config(Player))).to match('control-group row mb-3 hidden_type number_field')\n    end\n  end\n\n  describe '#object_infos' do\n    before do\n      allow(helper).to receive(:authorized?).and_return(true)\n      @object = Fan.create!(name: 'foo')\n      @builder = RailsAdmin::FormBuilder.new(:fan, @object, helper, {})\n    end\n\n    it 'returns a tag with infos' do\n      expect(@builder.object_infos).to eql '<span style=\"display:none\" class=\"object-infos\" data-model-label=\"Fan\" data-object-label=\"foo\"></span>'\n    end\n\n    context 'when object_label\\'s type is symbol' do\n      before { @object.name = :foo }\n\n      it 'does not break' do\n        expect(@builder.object_infos).to eql '<span style=\"display:none\" class=\"object-infos\" data-model-label=\"Fan\" data-object-label=\"foo\"></span>'\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/helpers/rails_admin/main_helper_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::MainHelper, type: :helper do\n  describe '#rails_admin_form_for' do\n    let(:html_form) do\n      helper.rails_admin_form_for(FieldTest.new, url: new_path(model_name: 'field_test')) {}\n    end\n\n    let(:html_form_with_attrs) do\n      helper.rails_admin_form_for(FieldTest.new, url: new_path(model_name: 'field_test'), html: {class: 'example'}) {}\n    end\n\n    context 'with html5 browser_validations enabled' do\n      before do\n        RailsAdmin.config.browser_validations = true\n        RailsAdmin.config FieldTest do\n          field :address, :string do\n            required true\n          end\n        end\n      end\n\n      it 'should not add novalidate attribute to the html form tag' do\n        expect(html_form).to_not include 'novalidate'\n      end\n    end\n\n    context 'with html5 browser_validations disabled' do\n      before do\n        RailsAdmin.config.browser_validations = false\n        RailsAdmin.config FieldTest do\n          field :address, :string do\n            required true\n          end\n        end\n      end\n\n      it 'should add novalidate attribute to the html form tag' do\n        expect(html_form).to include 'novalidate=\"novalidate\"'\n      end\n\n      it 'should add novalidate attribute to the html form tag with html attributes' do\n        expect(html_form_with_attrs).to include 'novalidate=\"novalidate\"'\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/base_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Base action', type: :request do\n  subject { page }\n\n  describe '#enabled?' do\n    it 'prevents the access to unauthorized actions' do\n      RailsAdmin.config do |config|\n        config.actions do\n          index do\n            except %w[FieldTest]\n          end\n        end\n      end\n      expect { visit index_path(model_name: 'field_test') }.to raise_error 'RailsAdmin::ActionNotAllowed'\n    end\n\n    describe 'in form action' do\n      before do\n        RailsAdmin.config do |config|\n          config.actions do\n            index\n            new\n            edit do\n              except %w[Player Team]\n            end\n          end\n        end\n      end\n\n      describe 'for filterling-select widget' do\n        it 'hides modal links to disabled actions' do\n          visit new_path(model_name: 'player')\n          expect(page).to have_link 'Add a new Team'\n          expect(page).not_to have_link 'Edit this Team'\n        end\n      end\n\n      describe 'for filterling-multiselect widget' do\n        it 'hides edit link to another model' do\n          visit new_path(model_name: 'team')\n          expect(page).to have_link 'Add a new Player'\n          expect(page).not_to have_link 'Edit this Player'\n        end\n      end\n    end\n\n    context 'when used with #visible?' do\n      let!(:player) { FactoryBot.create(:player) }\n      before do\n        RailsAdmin.config do |config|\n          config.actions do\n            index\n            show\n            edit do\n              enabled false\n              visible true\n            end\n          end\n        end\n      end\n\n      it 'allows disabled links to be shown' do\n        visit index_path(model_name: 'player')\n        is_expected.to have_css('.edit_member_link.disabled span', text: /Edit/, visible: false)\n        visit show_path(model_name: 'player', id: player.id)\n        is_expected.to have_css('.edit_member_link.disabled a[href*=\"void(0)\"]')\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/bulk_delete_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'BulkDelete action', type: :request do\n  subject { page }\n\n  describe 'confirmation page' do\n    before do\n      @players = FactoryBot.create_list(:player, 2)\n    end\n\n    it 'shows names of to-be-deleted players' do\n      post(bulk_action_path(bulk_action: 'bulk_delete', model_name: 'player', bulk_ids: @players.collect(&:id)))\n      @players.each { |player| expect(response.body).to include(player.name) }\n    end\n\n    it 'redirects to list when all of the records is already deleted' do\n      expect(Player.count).to eq @players.length\n      player_ids = [@players.first.id]\n      @players.first.destroy # delete selected object before send request to show bulk_delete confirmation.\n\n      post(bulk_action_path(bulk_action: 'bulk_delete', model_name: 'player', bulk_ids: player_ids))\n      expect(response.response_code).to eq 302\n\n      index_url = response.headers['Location']\n      expect(URI.parse(index_url).path).to eq(index_path(model_name: 'player'))\n      visit index_url\n\n      is_expected.to have_no_content(@players.first.name)\n      is_expected.to have_content(@players.last.name)\n    end\n\n    it 'returns error message for DELETE request if the records are already deleted' do\n      expect(Player.count).to eq @players.length\n      player_ids = [@players.first.id]\n      @players.first.destroy # delete selected object before send request to delete it.\n\n      delete(bulk_delete_path(bulk_action: 'bulk_delete', model_name: 'player', bulk_ids: player_ids))\n      expect(response.response_code).to eq 302\n      expect(flash[:error]).to match(/0 players failed to be deleted/i)\n    end\n\n    it 'returns error message for DELETE request without bulk_ids' do\n      expect(Player.count).to eq @players.length\n      delete(bulk_delete_path(bulk_action: 'bulk_delete', model_name: 'player', bulk_ids: ''))\n      expect(response.response_code).to eq 302\n      expect(flash[:error]).to match(/0 players failed to be deleted/i)\n    end\n  end\n\n  context 'on destroy' do\n    before do\n      @players = Array.new(3) { FactoryBot.create(:player) }\n      @delete_ids = @players[0..1].collect(&:id)\n\n      # NOTE: This uses an internal, unsupported capybara API which could break at any moment. We\n      # should refactor this test so that it either A) uses capybara's supported API (only GET\n      # requests via visit) or B) just uses Rack::Test (and doesn't use capybara for browser\n      # interaction like click_button).\n      page.driver.browser.reset_host!\n      page.driver.browser.process :post, bulk_action_path(bulk_action: 'bulk_delete', model_name: 'player', bulk_ids: @delete_ids, '_method' => 'post')\n      click_button \"Yes, I'm sure\"\n    end\n\n    it 'does not contain deleted records' do\n      expect(RailsAdmin::AbstractModel.new('Player').all.pluck(:id)).to eq([@players[2].id])\n      expect(page).to have_selector('.alert-success', text: '2 Players successfully deleted')\n    end\n  end\n\n  context 'on cancel' do\n    before do\n      @players = Array.new(3) { FactoryBot.create(:player) }\n      @delete_ids = @players[0..1].collect(&:id)\n\n      visit index_path(model_name: 'player')\n      @delete_ids.each { |id| find(%(input[name=\"bulk_ids[]\"][value=\"#{id}\"])).click }\n      click_link 'Selected items'\n      click_link 'Delete selected Players'\n    end\n\n    it 'does not delete records', js: true do\n      find_button('Cancel').trigger('click')\n      is_expected.to have_text 'No actions were taken'\n      expect(RailsAdmin::AbstractModel.new('Player').count).to eq(3)\n    end\n  end\n\n  context 'with composite primary keys', composite_primary_keys: true do\n    let!(:fanships) { FactoryBot.create_list(:fanship, 3) }\n\n    it 'provides check boxes for bulk operation' do\n      visit index_path(model_name: 'fanship')\n      fanships.each { |fanship| is_expected.to have_css(%(input[name=\"bulk_ids[]\"][value=\"#{fanship.id}\"])) }\n    end\n\n    it 'deletes selected records' do\n      delete(bulk_delete_path(bulk_action: 'bulk_delete', model_name: 'fanship', bulk_ids: fanships[0..1].map { |fanship| RailsAdmin::Support::CompositeKeysSerializer.serialize(fanship.id) }))\n      expect(flash[:success]).to match(/2 Fanships successfully deleted/)\n      expect(Fanship.all).to eq fanships[2..2]\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/dashboard_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Dashboard action', type: :request do\n  subject { page }\n\n  it 'shows statistics by default' do\n    allow(RailsAdmin.config(Player).abstract_model).to receive(:count).and_return(0)\n    expect(RailsAdmin.config(Player).abstract_model).to receive(:count)\n    visit dashboard_path\n  end\n\n  it 'does not show statistics if turned off' do\n    RailsAdmin.config do |c|\n      c.included_models = [Player]\n      c.actions do\n        dashboard do\n          statistics false\n        end\n        index # mandatory\n      end\n    end\n\n    expect(RailsAdmin.config(Player).abstract_model).not_to receive(:count)\n    visit dashboard_path\n  end\n\n  it 'does not show history if turned off', active_record: true do\n    RailsAdmin.config do |c|\n      c.audit_with :paper_trail, 'User', 'PaperTrail::Version'\n      c.included_models = [PaperTrailTest]\n      c.actions do\n        dashboard do\n          history false\n        end\n        index # mandatory\n        new\n        history_index\n      end\n    end\n    with_versioning do\n      visit new_path(model_name: 'paper_trail_test')\n      fill_in 'paper_trail_test[name]', with: 'Jackie Robinson'\n      click_button 'Save'\n    end\n    visit dashboard_path\n    is_expected.not_to have_content 'Jackie Robinson'\n  end\n\n  it 'counts are different for same-named models in different modules' do\n    allow(RailsAdmin.config(User::Confirmed).abstract_model).to receive(:count).and_return(10)\n    allow(RailsAdmin.config(Comment::Confirmed).abstract_model).to receive(:count).and_return(0)\n\n    visit dashboard_path\n    expect(find('tr.user_confirmed_links .progress').text).to eq '10'\n    expect(find('tr.comment_confirmed_links .progress').text).to eq '0'\n  end\n\n  it 'most recent change dates are different for same-named models in different modules' do\n    user_create = 10.days.ago\n    comment_create = 20.days.ago\n    FactoryBot.create(:user_confirmed, created_at: user_create)\n    FactoryBot.create(:comment_confirmed, created_at: comment_create)\n\n    visit dashboard_path\n    expect(find('tr.user_confirmed_links')).to have_content '10 days ago'\n    expect(find('tr.comment_confirmed_links')).to have_content '20 days ago'\n  end\n\n  describe 'I18n' do\n    around do |example|\n      I18n.config.available_locales = I18n.config.available_locales + [:xx]\n      I18n.backend.class.send(:include, I18n::Backend::Pluralization)\n      I18n.backend.store_translations :xx,\n                                      admin: {\n                                        misc: {\n                                          ago: 'back',\n                                        },\n                                      },\n                                      datetime: {\n                                        distance_in_words: {\n                                          x_days: {\n                                            one: '1 day',\n                                          },\n                                        },\n                                      }\n\n      I18n.locale = :xx\n\n      example.run\n\n      I18n.locale = :en\n      I18n.config.available_locales = I18n.config.available_locales - [:xx]\n    end\n\n    it \"fallbacks to 'ago' when 'time_ago' is not available\" do\n      FactoryBot.create(:player, created_at: 1.day.ago)\n\n      visit dashboard_path\n      expect(page).to have_content '1 day back'\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/delete_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Delete action', type: :request do\n  subject { page }\n\n  it 'shows \"Delete model\"' do\n    @draft = FactoryBot.create :draft\n    @player = @draft.player\n    @comment = @player.comments.create\n    visit delete_path(model_name: 'player', id: @player.id)\n    is_expected.to have_content('delete this player')\n    is_expected.to have_link(@player.name, href: \"/admin/player/#{@player.id}\")\n    is_expected.to have_link(\"Draft ##{@draft.id}\", href: \"/admin/draft/#{@draft.id}\")\n    is_expected.to have_link(\"Comment ##{@comment.id}\", href: \"/admin/comment/#{@comment.id}\")\n  end\n\n  context 'with missing object' do\n    before do\n      visit delete_path(model_name: 'player', id: 1)\n    end\n\n    it 'raises NotFound' do\n      expect(page.driver.status_code).to eq(404)\n    end\n  end\n\n  context 'with show action disabled' do\n    before do\n      RailsAdmin.config.actions do\n        dashboard\n        index\n        delete\n      end\n      @draft = FactoryBot.create :draft\n      @player = @draft.player\n      @comment = @player.comments.create\n      visit delete_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'shows \"Delete model\"' do\n      is_expected.to have_content('delete this player')\n      is_expected.not_to have_selector(\"a[href=\\\"/admin/player/#{@player.id}\\\"]\")\n      is_expected.not_to have_selector(\"a[href=\\\"/admin/draft/#{@draft.id}\\\"]\")\n      is_expected.not_to have_selector(\"a[href=\\\"/admin/comment/#{@comment.id}\\\"]\")\n    end\n  end\n\n  context 'on deleting an object which has an associated item without id' do\n    before do\n      @player = FactoryBot.create :player\n      allow_any_instance_of(Player).to receive(:draft).and_return(Draft.new)\n      visit delete_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'shows \"Delete model\"' do\n      is_expected.not_to have_content('Routing Error')\n      is_expected.to have_content('delete this player')\n      is_expected.to have_link(@player.name, href: \"/admin/player/#{@player.id}\")\n    end\n  end\n\n  context 'on deleting an object which has many associated item' do\n    before do\n      comments = FactoryBot.create_list :comment, 20\n      @player = FactoryBot.create :player, comments: comments\n      visit delete_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'shows only ten first plus x mores', skip_mongoid: true do\n      is_expected.to have_selector('.comment', count: 10)\n      is_expected.to have_content('Plus 10 more Comments')\n    end\n  end\n\n  context 'on destroy' do\n    before do\n      @player = FactoryBot.create :player\n      visit delete_path(model_name: 'player', id: @player.id)\n      click_button \"Yes, I'm sure\"\n      @player = RailsAdmin::AbstractModel.new('Player').first\n    end\n\n    it 'destroys an object' do\n      expect(@player).to be_nil\n    end\n\n    it 'shows success message' do\n      is_expected.to have_content('Player successfully deleted')\n    end\n  end\n\n  context 'with destroy errors' do\n    before do\n      allow_any_instance_of(Player).to receive(:destroy_hook) { throw :abort }\n      @player = FactoryBot.create :player\n      visit delete_path(model_name: 'player', id: @player.id)\n      click_button \"Yes, I'm sure\"\n    end\n\n    it 'does not destroy an object' do\n      expect(@player.reload).to be\n    end\n\n    it 'shows error message' do\n      is_expected.to have_content('Player failed to be deleted')\n    end\n\n    it 'returns status code 406' do\n      expect(page.status_code).to eq(406)\n    end\n  end\n\n  context 'on destroy error by dependent: :restrict_with_error' do\n    let!(:player) { FactoryBot.create :player, team: FactoryBot.create(:restricted_team) }\n    before do\n      visit delete_path(model_name: 'restricted_team', id: player.team.id)\n      click_button \"Yes, I'm sure\"\n      is_expected.to have_content('Restricted team failed to be deleted')\n    end\n\n    it 'shows error message', active_record: true do\n      is_expected.to have_content('Cannot delete record because dependent players exist')\n    end\n\n    it 'shows error message', mongoid: true do\n      is_expected.to have_content('Players is not empty and prevents the document from being destroyed')\n    end\n  end\n\n  context 'on cancel' do\n    before do\n      @player = FactoryBot.create :player\n      visit delete_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'does not destroy an object', js: true do\n      find_button('Cancel').trigger('click')\n      is_expected.to have_text 'No actions were taken'\n      expect(RailsAdmin::AbstractModel.new('Player').first).to be\n    end\n  end\n\n  context 'with missing object' do\n    before do\n      delete delete_path(model_name: 'player', id: 1)\n    end\n\n    it 'raises NotFound' do\n      expect(response.code).to eq('404')\n    end\n  end\n\n  context 'when navigated to delete from show page' do\n    it 'redirects to the index instead of trying to show the deleted object' do\n      @player = FactoryBot.create :player\n      visit show_path(model_name: 'player', id: @player.id)\n      click_link 'Delete'\n      click_button \"Yes, I'm sure\"\n\n      expect(URI.parse(page.current_url).path).to eq(index_path(model_name: 'player'))\n    end\n\n    it 'stays on the delete page' do\n      allow_any_instance_of(Player).to receive(:destroy_hook) { throw :abort }\n      @player = FactoryBot.create :player\n      visit show_path(model_name: 'player', id: @player.id)\n      click_link 'Delete'\n      click_button \"Yes, I'm sure\"\n\n      expect(URI.parse(page.current_url).path).to eq(delete_path(model_name: 'player', id: @player.id))\n    end\n  end\n\n  context 'with composite primary keys', composite_primary_keys: true do\n    let(:fanship) { FactoryBot.create(:fanship) }\n\n    it 'deletes the object' do\n      visit delete_path(model_name: 'fanship', id: fanship.id)\n      click_button \"Yes, I'm sure\"\n      is_expected.to have_content('Fanship successfully deleted')\n      expect(Fanship.all).to be_empty\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/edit_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Edit action', type: :request do\n  subject { page }\n\n  describe 'page' do\n    before do\n      @player = FactoryBot.create :player\n      visit edit_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'shows \"Edit model\"' do\n      is_expected.to have_content('Edit Player')\n    end\n\n    it 'shows required fields as \"Required\"' do\n      is_expected.to have_selector('div', text: /Name\\s*Required/)\n      is_expected.to have_selector('div', text: /Number\\s*Required/)\n    end\n\n    it 'shows non-required fields as \"Optional\"' do\n      expect(find('#player_position_field .form-text')).to have_content('Optional')\n      expect(find('#player_born_on_field .form-text')).to have_content('Optional')\n      expect(find('#player_notes_field .form-text')).to have_content('Optional')\n    end\n\n    it 'checks required fields to have required attribute set' do\n      expect(find_field('player_name')[:required]).to be_present\n      expect(find_field('player_number')[:required]).to be_present\n    end\n\n    it 'checks optional fields to not have required attribute set' do\n      expect(find_field('player_position')[:required]).to be_blank\n    end\n  end\n\n  describe 'css hooks' do\n    it 'is present' do\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('#team_division_id_field.belongs_to_association_type.division_field')\n    end\n  end\n\n  describe 'field grouping' do\n    it 'is hideable' do\n      RailsAdmin.config Team do\n        edit do\n          group :default do\n            label 'Hidden group'\n            hide\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      # Should not have the group header\n      is_expected.to have_no_selector('legend', text: 'Hidden Group')\n      # Should not have any of the group's fields either\n      is_expected.to have_no_selector('select#team_division')\n      is_expected.to have_no_selector('input#team_name')\n      is_expected.to have_no_selector('input#team_logo_url')\n      is_expected.to have_no_selector('input#team_manager')\n      is_expected.to have_no_selector('input#team_ballpark')\n      is_expected.to have_no_selector('input#team_mascot')\n      is_expected.to have_no_selector('input#team_founded')\n      is_expected.to have_no_selector('input#team_wins')\n      is_expected.to have_no_selector('input#team_losses')\n      is_expected.to have_no_selector('input#team_win_percentage')\n      is_expected.to have_no_selector('input#team_revenue')\n    end\n\n    it 'hides association groupings' do\n      RailsAdmin.config Team do\n        edit do\n          group :players do\n            label 'Players'\n            field :players\n            hide\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      # Should not have the group header\n      is_expected.to have_no_selector('legend', text: 'Players')\n      # Should not have any of the group's fields either\n      is_expected.to have_no_selector('select#team_player_ids')\n    end\n\n    it 'is renameable' do\n      RailsAdmin.config Team do\n        edit do\n          group :default do\n            label 'Renamed group'\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      # NOTE: capybara 2.0 is exceedingly reluctant to reveal the text of invisible elements. This was\n      # the least terrible option I was able to find. It would probably be better to refactor the test\n      # so the label we're looking for is displayed.\n      expect(find('legend', visible: false).native.text).to include('Renamed group')\n    end\n\n    describe 'help' do\n      before do\n        class HelpTest < Tableless\n          column :name, 'varchar(50)'\n          column :division, :varchar\n        end\n        RailsAdmin.config.included_models = [HelpTest, Team]\n      end\n\n      after(:each) do\n        # restore validation setting\n        HelpTest._validators[:name] = []\n        HelpTest.reset_callbacks(:validate)\n      end\n\n      context 'using mongoid', skip_active_record: true do\n        it 'uses the db column size for the maximum length' do\n          visit new_path(model_name: 'help_test')\n          expect(find('#help_test_name_field .form-text')).to have_content('Length up to 255.')\n        end\n\n        it 'returns nil for the maximum length' do\n          visit new_path(model_name: 'team')\n          expect(find('#team_custom_field_field .form-text')).not_to have_content('Length')\n        end\n      end\n\n      context 'using active_record', skip_mongoid: true do\n        it 'uses the db column size for the maximum length' do\n          visit new_path(model_name: 'help_test')\n          expect(find('#help_test_name_field .form-text')).to have_content('Length up to 50.')\n        end\n\n        it 'uses the :minimum setting from the validation' do\n          HelpTest.class_eval do\n            validates_length_of :name, minimum: 1\n          end\n          visit new_path(model_name: 'help_test')\n          expect(find('#help_test_name_field .form-text')).to have_content('Length of 1-50.')\n        end\n\n        it 'uses the minimum of db column size or :maximum setting from the validation' do\n          HelpTest.class_eval do\n            validates_length_of :name, maximum: 51\n          end\n          visit new_path(model_name: 'help_test')\n          expect(find('#help_test_name_field .form-text')).to have_content('Length up to 50.')\n        end\n      end\n\n      it 'shows help section if present' do\n        RailsAdmin.config HelpTest do\n          edit do\n            group :default do\n              help 'help paragraph to display'\n            end\n          end\n        end\n        visit new_path(model_name: 'help_test')\n        is_expected.to have_selector('fieldset>p', text: 'help paragraph to display')\n      end\n\n      it 'does not show help if not present' do\n        RailsAdmin.config HelpTest do\n          edit do\n            group :default do\n              label 'no help'\n            end\n          end\n        end\n        visit new_path(model_name: 'help_test')\n        is_expected.not_to have_selector('fieldset>p')\n      end\n\n      it 'is able to display multiple help if there are multiple sections' do\n        RailsAdmin.config HelpTest do\n          edit do\n            group :default do\n              field :name\n              help 'help for default'\n            end\n            group :other_section do\n              label 'Other Section'\n              field :division\n              help 'help for other section'\n            end\n          end\n        end\n        visit new_path(model_name: 'help_test')\n        is_expected.to have_selector('fieldset>p', text: 'help for default')\n        is_expected.to have_selector('fieldset>p', text: 'help for other section')\n        is_expected.to have_selector('fieldset>p', count: 2)\n      end\n\n      it 'uses the :is setting from the validation' do\n        HelpTest.class_eval do\n          validates_length_of :name, is: 3\n        end\n        visit new_path(model_name: 'help_test')\n        expect(find('#help_test_name_field .form-text')).to have_content('Length of 3.')\n      end\n\n      it 'uses the :maximum setting from the validation' do\n        HelpTest.class_eval do\n          validates_length_of :name, maximum: 49\n        end\n        visit new_path(model_name: 'help_test')\n        expect(find('#help_test_name_field .form-text')).to have_content('Length up to 49.')\n      end\n\n      it 'uses the :minimum and :maximum from the validation' do\n        HelpTest.class_eval do\n          validates_length_of :name, minimum: 1, maximum: 49\n        end\n        visit new_path(model_name: 'help_test')\n        expect(find('#help_test_name_field .form-text')).to have_content('Length of 1-49.')\n      end\n\n      it 'uses the range from the validation' do\n        HelpTest.class_eval do\n          validates_length_of :name, in: 1..49\n        end\n        visit new_path(model_name: 'help_test')\n        expect(find('#help_test_name_field .form-text')).to have_content('Length of 1-49.')\n      end\n\n      it 'does not show help for hidden fields' do\n        RailsAdmin.config HelpTest do\n          edit do\n            field :name, :hidden\n          end\n        end\n        visit new_path(model_name: 'help_test')\n        expect(page).not_to have_css('.form-text')\n      end\n    end\n\n    it 'has accessor for its fields' do\n      RailsAdmin.config Team do\n        edit do\n          group :default do\n            field :name\n            field :logo_url\n          end\n          group :belongs_to_associations do\n            label \"Belong's to associations\"\n            field :division\n          end\n          group :basic_info do\n            field :manager\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('legend', text: 'Basic info', visible: false)\n      is_expected.to have_selector('legend', text: 'Basic info', visible: true)\n      is_expected.to have_selector('legend', text: \"Belong's to associations\")\n      is_expected.to have_selector('label', text: 'Name')\n      is_expected.to have_selector('label', text: 'Logo url')\n      is_expected.to have_selector('label', text: 'Division')\n      is_expected.to have_selector('.control-group', count: 4)\n    end\n\n    it 'has accessor for its fields by type' do\n      RailsAdmin.config Team do\n        edit do\n          group :default do\n            field :name\n            field :logo_url\n          end\n          group :other do\n            field :division_id\n            field :manager\n            field :ballpark\n            fields_of_type :string do\n              label { \"#{label} (STRING)\" }\n            end\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('label', text: 'Name')\n      is_expected.to have_selector('label', text: 'Logo url')\n      is_expected.to have_selector('label', text: 'Division')\n      is_expected.to have_selector('label', text: 'Manager (STRING)')\n      is_expected.to have_selector('label', text: 'Ballpark (STRING)')\n    end\n  end\n\n  describe 'fields' do\n    it 'shows all by default' do\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('select#team_division_id')\n      is_expected.to have_selector('input#team_name')\n      is_expected.to have_selector('input#team_logo_url')\n      is_expected.to have_selector('input#team_manager')\n      is_expected.to have_selector('input#team_ballpark')\n      is_expected.to have_selector('input#team_mascot')\n      is_expected.to have_selector('input#team_founded')\n      is_expected.to have_selector('input#team_wins')\n      is_expected.to have_selector('input#team_losses')\n      is_expected.to have_selector('input#team_win_percentage')\n      is_expected.to have_selector('input#team_revenue')\n      is_expected.to have_selector('select#team_player_ids')\n      is_expected.to have_selector('select#team_fan_ids')\n    end\n\n    it 'appears in order defined' do\n      RailsAdmin.config Team do\n        edit do\n          field :manager\n          field :division\n          field :name\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector(:xpath, \"//*[contains(@class, 'field')][1]//*[@id='team_manager']\")\n      is_expected.to have_selector(:xpath, \"//*[contains(@class, 'field')][2]//*[@id='team_division_id']\")\n      is_expected.to have_selector(:xpath, \"//*[contains(@class, 'field')][3]//*[@id='team_name']\")\n    end\n\n    it 'only shows the defined fields if some fields are defined' do\n      RailsAdmin.config Team do\n        edit do\n          field :division\n          field :name\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('label', text: 'Division')\n      is_expected.to have_selector('label', text: 'Name')\n      is_expected.to have_selector('.control-group', count: 2)\n    end\n\n    describe 'I18n awarly' do\n      after :each do\n        I18n.locale = :en\n      end\n\n      it 'delegates the label option to the ActiveModel API and memoizes it' do\n        RailsAdmin.config Team do\n          edit do\n            field :manager\n            field :fans\n          end\n        end\n        visit new_path(model_name: 'team')\n        is_expected.to have_selector('label', text: 'Team Manager')\n        is_expected.to have_selector('label', text: 'Some Fans')\n        I18n.locale = :fr\n        visit new_path(model_name: 'team')\n        is_expected.to have_selector('label', text: \"Manager de l'équipe\")\n        is_expected.to have_selector('label', text: 'Quelques fans')\n      end\n    end\n\n    it 'is renameable' do\n      RailsAdmin.config Team do\n        edit do\n          field :manager do\n            label 'Renamed field'\n          end\n          field :division\n          field :name\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('label', text: 'Renamed field')\n      is_expected.to have_selector('label', text: 'Division')\n      is_expected.to have_selector('label', text: 'Name')\n    end\n\n    it 'is renameable by type' do\n      RailsAdmin.config Team do\n        edit do\n          fields_of_type :string do\n            label { \"#{label} (STRING)\" }\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('label', text: 'Division')\n      is_expected.to have_selector('label', text: 'Name (STRING)')\n      is_expected.to have_selector('label', text: 'Logo url (STRING)')\n      is_expected.to have_selector('label', text: 'Manager (STRING)')\n      is_expected.to have_selector('label', text: 'Ballpark (STRING)')\n      is_expected.to have_selector('label', text: 'Mascot (STRING)')\n      is_expected.to have_selector('label', text: 'Founded')\n      is_expected.to have_selector('label', text: 'Wins')\n      is_expected.to have_selector('label', text: 'Losses')\n      is_expected.to have_selector('label', text: 'Win percentage')\n      is_expected.to have_selector('label', text: 'Revenue')\n      is_expected.to have_selector('label', text: 'Players')\n      is_expected.to have_selector('label', text: 'Fans')\n    end\n\n    it 'is globally renameable by type' do\n      RailsAdmin.config Team do\n        edit do\n          fields_of_type :string do\n            label { \"#{label} (STRING)\" }\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('label', text: 'Division')\n      is_expected.to have_selector('label', text: 'Name (STRING)')\n      is_expected.to have_selector('label', text: 'Logo url (STRING)')\n      is_expected.to have_selector('label', text: 'Manager (STRING)')\n      is_expected.to have_selector('label', text: 'Ballpark (STRING)')\n      is_expected.to have_selector('label', text: 'Mascot (STRING)')\n      is_expected.to have_selector('label', text: 'Founded')\n      is_expected.to have_selector('label', text: 'Wins')\n      is_expected.to have_selector('label', text: 'Losses')\n      is_expected.to have_selector('label', text: 'Win percentage')\n      is_expected.to have_selector('label', text: 'Revenue')\n      is_expected.to have_selector('label', text: 'Players')\n      is_expected.to have_selector('label', text: 'Fans')\n    end\n\n    it 'is flaggable as read only and be configurable with formatted_value' do\n      RailsAdmin.config Team do\n        edit do\n          field :name do\n            read_only true\n            formatted_value do\n              \"I'm outputted in the form\"\n            end\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_content(\"I'm outputted in the form\")\n    end\n\n    it 'is hideable' do\n      RailsAdmin.config Team do\n        edit do\n          field :manager do\n            hide\n          end\n          field :division\n          field :name\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_no_selector('#team_manager')\n      is_expected.to have_selector('#team_division_id')\n      is_expected.to have_selector('#team_name')\n    end\n\n    it 'is hideable by type' do\n      RailsAdmin.config Team do\n        edit do\n          fields_of_type :string do\n            hide\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('label', text: 'Division')\n      is_expected.to have_no_selector('label', text: 'Name')\n      is_expected.to have_no_selector('label', text: 'Logo url')\n      is_expected.to have_no_selector('label', text: 'Manager')\n      is_expected.to have_no_selector('label', text: 'Ballpark')\n      is_expected.to have_no_selector('label', text: 'Mascot')\n      is_expected.to have_selector('label', text: 'Founded')\n      is_expected.to have_selector('label', text: 'Wins')\n      is_expected.to have_selector('label', text: 'Losses')\n      is_expected.to have_selector('label', text: 'Win percentage')\n      is_expected.to have_selector('label', text: 'Revenue')\n      is_expected.to have_selector('label', text: 'Players')\n      is_expected.to have_selector('label', text: 'Fans')\n    end\n\n    it 'is globally hideable by type' do\n      RailsAdmin.config Team do\n        edit do\n          fields_of_type :string do\n            hide\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('label', text: 'Division')\n      is_expected.to have_no_selector('label', text: 'Name')\n      is_expected.to have_no_selector('label', text: 'Logo url')\n      is_expected.to have_no_selector('label', text: 'Manager')\n      is_expected.to have_no_selector('label', text: 'Ballpark')\n      is_expected.to have_no_selector('label', text: 'Mascot')\n      is_expected.to have_selector('label', text: 'Founded')\n      is_expected.to have_selector('label', text: 'Wins')\n      is_expected.to have_selector('label', text: 'Losses')\n      is_expected.to have_selector('label', text: 'Win percentage')\n      is_expected.to have_selector('label', text: 'Revenue')\n      is_expected.to have_selector('label', text: 'Players')\n      is_expected.to have_selector('label', text: 'Fans')\n    end\n\n    it 'has option to customize the help text' do\n      RailsAdmin.config Team do\n        edit do\n          field :manager do\n            help \"#{help} Additional help text for manager field.\"\n          end\n          field :division\n          field :name\n        end\n      end\n      visit new_path(model_name: 'team')\n      expect(find('#team_manager_field .form-text')).to have_content('Required. Length up to 100. Additional help text for manager field.')\n      expect(find('#team_division_id_field .form-text')).to have_content('Required')\n      expect(find('#team_name_field .form-text')).not_to have_content('Additional help text')\n    end\n\n    it 'has option to override required status' do\n      RailsAdmin.config Team do\n        edit do\n          field :manager do\n            optional true\n          end\n          field :division do\n            optional true\n          end\n          field :name do\n            required true\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      expect(find('#team_manager_field .form-text')).to have_content('Optional')\n      expect(find('#team_division_id_field .form-text')).to have_content('Optional')\n      expect(find('#team_name_field .form-text')).to have_content(I18n.translate('admin.help.team.name'))\n    end\n\n    describe 'inline_add' do\n      it 'can hide the add button on an associated field' do\n        RailsAdmin.config Player do\n          edit do\n            field :team do\n              inline_add false\n            end\n            field :draft do\n              inline_add false\n            end\n            field :comments do\n              inline_add false\n            end\n          end\n        end\n        visit new_path(model_name: 'player')\n        is_expected.to have_no_selector('a', text: 'Add a new Team')\n        is_expected.to have_no_selector('a', text: 'Add a new Draft')\n        is_expected.to have_no_selector('a', text: 'Add a new Comment')\n      end\n\n      it 'can show the add button on an associated field' do\n        RailsAdmin.config Player do\n          edit do\n            field :team do\n              inline_add true\n            end\n            field :draft do\n              inline_add true\n            end\n            field :comments do\n              inline_add true\n            end\n          end\n        end\n        visit new_path(model_name: 'player')\n        is_expected.to have_selector('a', text: 'Add a new Team')\n        is_expected.to have_selector('a', text: 'Add a new Draft')\n        is_expected.to have_selector('a', text: 'Add a new Comment')\n      end\n\n      context 'when the associated model is invisible' do\n        before do\n          RailsAdmin.config do |config|\n            [Team, Draft, Comment].each do |model|\n              config.model model do\n                visible false\n              end\n            end\n          end\n        end\n\n        it 'does not prevent showing the add button' do\n          visit new_path(model_name: 'player')\n          is_expected.to have_selector('a', text: 'Add a new Team')\n          is_expected.to have_selector('a', text: 'Add a new Draft')\n          is_expected.to have_selector('a', text: 'Add a new Comment')\n        end\n      end\n    end\n\n    describe 'inline_edit' do\n      it 'can hide the edit button on an associated field' do\n        RailsAdmin.config Player do\n          edit do\n            field :team do\n              inline_edit false\n            end\n            field :draft do\n              inline_edit false\n            end\n          end\n        end\n        visit new_path(model_name: 'player')\n        is_expected.to have_no_selector('a', text: 'Edit this Team')\n        is_expected.to have_no_selector('a', text: 'Edit this Draft')\n      end\n\n      it 'can show the edit button on an associated field' do\n        RailsAdmin.config Player do\n          edit do\n            field :team do\n              inline_edit true\n            end\n            field :draft do\n              inline_edit true\n            end\n          end\n        end\n        visit new_path(model_name: 'player')\n        is_expected.to have_selector('a', text: 'Edit this Team')\n        is_expected.to have_selector('a', text: 'Edit this Draft')\n      end\n\n      context 'when the associated model is invisible' do\n        before do\n          RailsAdmin.config do |config|\n            [Team, Draft].each do |model|\n              config.model model do\n                visible false\n              end\n            end\n          end\n        end\n\n        it 'does not prevent showing the edit button' do\n          visit new_path(model_name: 'player')\n          is_expected.to have_selector('a', text: 'Edit this Team')\n          is_expected.to have_selector('a', text: 'Edit this Draft')\n        end\n      end\n    end\n  end\n\n  context 'with missing object' do\n    before do\n      visit edit_path(model_name: 'player', id: 1)\n    end\n\n    it 'raises NotFound' do\n      expect(page.driver.status_code).to eq(404)\n    end\n  end\n\n  context 'with a readonly object' do\n    let(:comment) { FactoryBot.create :comment, (CI_ORM == :mongoid ? {_type: 'ReadOnlyComment'} : {}) }\n\n    it 'raises ActionNotAllowed' do\n      expect { visit edit_path(model_name: 'read_only_comment', id: comment.id) }.to raise_error 'RailsAdmin::ActionNotAllowed'\n    end\n  end\n\n  context 'with missing label', given: ['a player exists', 'three teams with no name exist'] do\n    before do\n      @player = FactoryBot.create :player\n      @teams = Array.new(3) { FactoryBot.create :team, name: '' }\n      visit edit_path(model_name: 'player', id: @player.id)\n    end\n  end\n\n  context 'with overridden to_param' do\n    before do\n      @ball = FactoryBot.create :ball\n      visit edit_path(model_name: 'ball', id: @ball.id)\n    end\n\n    it 'displays a link to the delete page' do\n      is_expected.to have_selector \"a[href$='/admin/ball/#{@ball.id}/delete']\"\n    end\n  end\n\n  context 'on cancel' do\n    before do\n      @player = FactoryBot.create :player\n      visit '/admin/player'\n      click_link 'Edit'\n    end\n\n    it 'sends back to previous URL', js: true do\n      find_button('Cancel').trigger('click')\n      is_expected.to have_text 'No actions were taken'\n      expect(page.current_path).to eq('/admin/player')\n    end\n\n    it 'allows submit even if client-side validation is not satisfied', js: true do\n      fill_in 'player[name]', with: ''\n      find_button('Cancel').trigger('click')\n      is_expected.to have_text 'No actions were taken'\n    end\n  end\n\n  context 'with errors' do\n    before do\n      @player = FactoryBot.create :player\n      visit edit_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'returns to edit page' do\n      fill_in 'player[name]', with: ''\n      click_button 'Save' # first(:button, \"Save\").click\n      expect(page.driver.status_code).to eq(406)\n      is_expected.to have_selector \"form[action='#{edit_path(model_name: 'player', id: @player.id)}']\"\n    end\n  end\n\n  describe 'add another' do\n    before do\n      @player = FactoryBot.create :player\n\n      visit edit_path(model_name: 'player', id: @player.id)\n\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      fill_in 'player[number]', with: '42'\n      fill_in 'player[position]', with: 'Second baseman'\n      click_button 'Save' # first(:button, \"Save\").click\n\n      @player = RailsAdmin::AbstractModel.new('Player').first\n    end\n\n    it 'updates an object with correct attributes' do\n      expect(@player.name).to eq('Jackie Robinson')\n      expect(@player.number).to eq(42)\n      expect(@player.position).to eq('Second baseman')\n    end\n  end\n\n  describe 'update and edit', js: true do\n    before do\n      @player = FactoryBot.create :player\n\n      visit edit_path(model_name: 'player', id: @player.id)\n\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      fill_in 'player[number]', with: '42'\n      fill_in 'player[position]', with: 'Second baseman'\n      find_button('Save and edit').trigger('click')\n    end\n\n    it 'updates an object with correct attributes' do\n      is_expected.to have_text 'Player successfully updated'\n      expect(page.current_path).to eq(\"/admin/player/#{@player.id}/edit\")\n\n      @player.reload\n      expect(@player.name).to eq('Jackie Robinson')\n      expect(@player.number).to eq(42)\n      expect(@player.position).to eq('Second baseman')\n    end\n  end\n\n  context 'with a submit button with custom value', js: true do\n    before do\n      @player = FactoryBot.create :player\n\n      visit edit_path(model_name: 'player', id: @player.id)\n\n      execute_script %{$('.form-actions [name=\"_save\"]').attr('name', 'player[name]').attr('value', 'Jackie Robinson')}\n      find_button('Save').trigger('click')\n      is_expected.to have_text 'Player successfully updated'\n    end\n\n    it 'submits the value' do\n      @player.reload\n      expect(@player.name).to eq('Jackie Robinson')\n    end\n  end\n\n  context 'with missing object' do\n    before do\n      put edit_path(model_name: 'player', id: 1), params: {player: {name: 'Jackie Robinson', number: 42, position: 'Second baseman'}}\n    end\n\n    it 'raises NotFound' do\n      expect(response.code).to eq('404')\n    end\n  end\n\n  context 'with invalid object' do\n    before do\n      @player = FactoryBot.create :player\n\n      visit edit_path(model_name: 'player', id: @player.id)\n\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      fill_in 'player[number]', with: 'a'\n      fill_in 'player[position]', with: 'Second baseman'\n      click_button 'Save' # first(:button, \"Save\").click\n\n      @player.reload\n    end\n\n    it 'shows an error message' do\n      expect(Capybara.string(body)).to have_content('Player failed to be updated')\n    end\n  end\n\n  context 'with overridden to_param' do\n    before do\n      @ball = FactoryBot.create :ball\n\n      visit edit_path(model_name: 'ball', id: @ball.id)\n\n      fill_in 'ball[color]', with: 'gray'\n      click_button 'Save and edit'\n\n      @ball.reload\n    end\n\n    it 'updates an object with correct attributes' do\n      expect(@ball.color).to eq('gray')\n    end\n  end\n\n  context 'on update of STI subclass on superclass view' do\n    before do\n      @hardball = FactoryBot.create :hardball\n\n      visit edit_path(model_name: 'ball', id: @hardball.id)\n\n      fill_in 'ball[color]', with: 'cyan'\n      click_button 'Save and edit'\n\n      @hardball.reload\n    end\n\n    it 'updates an object with correct attributes' do\n      expect(@hardball.color).to eq('cyan')\n    end\n  end\n\n  context \"with a field with 'format' as a name (conflicts with Kernel#format)\" do\n    it 'is updatable without any error' do\n      RailsAdmin.config FieldTest do\n        edit do\n          field :format\n        end\n      end\n      visit new_path(model_name: 'field_test')\n      fill_in 'field_test[format]', with: 'test for format'\n      click_button 'Save' # first(:button, \"Save\").click\n      @record = RailsAdmin::AbstractModel.new('FieldTest').first\n      expect(@record.format).to eq('test for format')\n    end\n  end\n\n  context \"with a field with 'open' as a name\" do\n    it 'is updatable without any error' do\n      RailsAdmin.config FieldTest do\n        edit do\n          field :open do\n            nullable false\n          end\n        end\n      end\n      record = FieldTest.create\n      visit edit_path(model_name: 'field_test', id: record.id)\n      expect do\n        check 'field_test[open]'\n        click_button 'Save'\n      end.to change { record.reload.open }.from(nil).to(true)\n    end\n  end\n\n  context 'with composite primary keys', composite_primary_keys: true do\n    let(:fanship) { FactoryBot.create(:fanship) }\n\n    it 'edits the object' do\n      visit edit_path(model_name: 'fanship', id: fanship.id)\n      fill_in 'Since', with: '2000-01-23'\n      click_button 'Save'\n      expect { fanship.reload }.to change { fanship.since }.from(nil).to(Date.new(2000, 1, 23))\n    end\n\n    context 'using custom serializer' do\n      before do\n        RailsAdmin.config.composite_keys_serializer = Class.new do\n          def self.serialize(keys)\n            keys.join(',')\n          end\n\n          def self.deserialize(string)\n            string.split(',')\n          end\n        end\n      end\n\n      it 'edits the object' do\n        visit edit_path(model_name: 'fanship', id: \"#{fanship.fan_id},#{fanship.team_id}\")\n        fill_in 'Since', with: '2000-01-23'\n        click_button 'Save'\n        expect { fanship.reload }.to change { fanship.since }.from(nil).to(Date.new(2000, 1, 23))\n      end\n    end\n\n    context 'receiving invalid id' do\n      it 'returns 404' do\n        visit edit_path(model_name: 'fanship', id: '11')\n        expect(page.driver.status_code).to eq(404)\n        is_expected.to have_content(\"Fanship with id '11' could not be found\")\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/export_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\nrequire 'csv'\n\nRSpec.describe 'Export action', type: :request do\n  subject { page }\n\n  let!(:player) { FactoryBot.create(:player) }\n\n  it 'exports to CSV' do\n    visit export_path(model_name: 'player')\n    click_button 'Export to csv'\n    is_expected.to have_content player.name\n  end\n\n  it 'exports to JSON' do\n    visit export_path(model_name: 'player')\n    click_button 'Export to json'\n    is_expected.to have_content player.name\n  end\n\n  it 'exports to XML' do\n    pending \"Mongoid does not support to_xml's :include option\" if CI_ORM == :mongoid\n    visit export_path(model_name: 'player')\n    click_button 'Export to xml'\n\n    is_expected.to have_content player.name\n  end\n\n  it 'works with Turbo Drive enabled', js: true do\n    visit export_path(model_name: 'player')\n    page.execute_script 'console.error = function(error) { throw error }'\n    expect { find_button('Export to csv').trigger('click') }.not_to raise_error\n  end\n\n  it 'does not break when nothing is checked' do\n    visit export_path(model_name: 'comment')\n    all('input[type=\"checkbox\"]').each(&:uncheck)\n    expect { click_button 'Export to csv' }.not_to raise_error\n  end\n\n  describe 'with associations' do\n    let!(:players) { FactoryBot.create_list(:player, 3) }\n    let(:team) { FactoryBot.create :team }\n    let(:draft) { FactoryBot.create :draft }\n    let(:comments) { FactoryBot.create_list(:comment, 2) }\n\n    before do\n      player.team = team\n      player.draft = draft\n      player.comments = comments\n      player.save\n    end\n\n    it 'exports to CSV with default schema, containing properly translated header and follow configuration' do\n      RailsAdmin.config do |c|\n        c.model Player do\n          include_all_fields\n          field :name do\n            export_value do\n              \"#{value} exported\"\n            end\n          end\n\n          field :json_field, :json do\n            formatted_value do\n              '{}'\n            end\n          end\n        end\n      end\n\n      visit export_path(model_name: 'player')\n      is_expected.to have_content 'Select fields to export'\n      select \"<comma> ','\", from: 'csv_options_generator_col_sep'\n      click_button 'Export to csv'\n      csv = CSV.parse page.driver.response.body.force_encoding('utf-8') # comes through as us-ascii on some platforms\n      expect(csv[0]).to match_array ['Id', 'Created at', 'Updated at', 'Deleted at', 'Name', 'Position',\n                                     'Number', 'Retired', 'Injured', 'Born on', 'Notes', 'Suspended', 'Formation', 'Json field', 'Id [Team]', 'Created at [Team]',\n                                     'Updated at [Team]', 'Name [Team]', 'Logo url [Team]', 'Team Manager [Team]', 'Ballpark [Team]',\n                                     'Mascot [Team]', 'Founded [Team]', 'Wins [Team]', 'Losses [Team]', 'Win percentage [Team]',\n                                     'Revenue [Team]', 'Color [Team]', 'Custom field [Team]', 'Main Sponsor [Team]', 'Id [Draft]', 'Created at [Draft]',\n                                     'Updated at [Draft]', 'Date [Draft]', 'Round [Draft]', 'Pick [Draft]', 'Overall [Draft]',\n                                     'College [Draft]', 'Notes [Draft]', 'Id [Comments]', 'Content [Comments]', 'Created at [Comments]',\n                                     'Updated at [Comments]']\n      expect(csv.flatten).to include(\"#{player.name} exported\")\n      expect(csv.flatten).to include(player.team.name)\n      expect(csv.flatten).to include(player.draft.college)\n\n      expect(csv.flatten.join(' ')).to include(player.comments.first.content.split(\"\\n\").first.strip)\n      expect(csv.flatten.join(' ')).to include(player.comments.second.content.split(\"\\n\").first.strip)\n    end\n\n    let(:custom_schema) do\n      # removed schema=>only=>created_at\n      {\n        'only' => [PK_COLUMN.to_s, 'updated_at', 'deleted_at', 'name', 'position', 'number', 'retired', 'injured', 'born_on', 'notes', 'suspended'],\n        'include' => {\n          'team' => {'only' => [PK_COLUMN.to_s, 'created_at', 'updated_at', 'name', 'logo_url', 'manager', 'ballpark', 'mascot', 'founded', 'wins', 'losses', 'win_percentage', 'revenue', 'color']},\n          'draft' => {'only' => [PK_COLUMN.to_s, 'created_at', 'updated_at', 'date', 'round', 'pick', 'overall', 'college', 'notes']},\n          'comments' => {'only' => [PK_COLUMN.to_s, 'content', 'created_at', 'updated_at']},\n        },\n      }\n    end\n\n    it 'exports to CSV with custom schema' do\n      page.driver.post(export_path(model_name: 'player', schema: custom_schema, csv: true, all: true, csv_options: {generator: {col_sep: ','}}))\n      csv = CSV.parse page.driver.response.body\n      expect(csv[0]).not_to include('Created at')\n    end\n\n    it 'exports polymorphic fields the easy way for now' do\n      visit export_path(model_name: 'comment')\n      select \"<comma> ','\", from: 'csv_options_generator_col_sep'\n      click_button 'Export to csv'\n      csv = CSV.parse page.driver.response.body\n      expect(csv[0]).to match_array ['Id', 'Commentable', 'Commentable type', 'Content', 'Created at', 'Updated at']\n      csv[1..].each do |line|\n        expect(line[csv[0].index('Commentable')]).to eq(player.id.to_s)\n        expect(line[csv[0].index('Commentable type')]).to eq(player.class.to_s)\n      end\n    end\n  end\n\n  context 'on cancel' do\n    before do\n      @player = FactoryBot.create :player\n      visit export_path(model_name: 'player')\n    end\n\n    it 'does nothing', js: true do\n      find_button('Cancel').trigger('click')\n      is_expected.to have_text 'No actions were taken'\n    end\n  end\n\n  describe 'bulk export' do\n    it 'is supported' do\n      visit index_path(model_name: 'player')\n      click_link 'Export found Players'\n      is_expected.to have_content('Select fields to export')\n    end\n\n    describe 'with model scope' do\n      let!(:comments) { %w[something anything].map { |content| FactoryBot.create :comment_confirmed, content: content } }\n      before do\n        RailsAdmin.config do |config|\n          config.model Comment::Confirmed do\n            scope { Comment::Confirmed.unscoped }\n          end\n        end\n      end\n\n      it 'overrides default_scope' do\n        page.driver.post(export_path(model_name: 'comment~confirmed', schema: {only: ['content']}, csv: true, all: true, csv_options: {generator: {col_sep: ','}}, bulk_ids: comments.map(&:id)))\n        csv = CSV.parse page.driver.response.body\n        expect(csv.flatten).to match_array %w[Content something anything]\n      end\n    end\n  end\n\n  context 'with composite primary keys', composite_primary_keys: true do\n    let!(:fanship) { FactoryBot.create(:fanship) }\n\n    it 'exports to CSV' do\n      visit export_path(model_name: 'fanship')\n      click_button 'Export to csv'\n      is_expected.to have_content fanship.fan.name\n      is_expected.to have_content fanship.team.name\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/history_index_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'HistoryIndex action', type: :request, active_record: true do\n  subject { page }\n\n  let(:user) { FactoryBot.create :user }\n  let(:paper_trail_test) { FactoryBot.create :paper_trail_test }\n  before(:each) do\n    RailsAdmin.config do |config|\n      config.audit_with :paper_trail, 'User', 'PaperTrail::Version'\n    end\n\n    PaperTrail::Version.delete_all\n    with_versioning do\n      PaperTrail.request.whodunnit = user.id\n      30.times do |i|\n        paper_trail_test.update!(name: \"updated name #{i}\")\n      end\n    end\n  end\n\n  it 'shows the history' do\n    visit history_index_path(model_name: 'paper_trail_test')\n    is_expected.to have_css(%([href=\"/admin/paper_trail_test/#{paper_trail_test.id}\"]), count: 20)\n  end\n\n  it 'supports pagination' do\n    visit history_index_path(model_name: 'paper_trail_test', page: 2)\n    is_expected.to have_css(%([href=\"/admin/paper_trail_test/#{paper_trail_test.id}\"]), count: 11)\n  end\n\n  it 'supports sorting', js: true do\n    visit history_index_path(model_name: 'paper_trail_test')\n    find('th.header', text: 'Item').click\n    is_expected.to have_css('th.item.headerSortDown')\n  end\n\n  context \"when Kaminari's custom param_name is set\" do\n    before { Kaminari.config.param_name = :pagina }\n    after { Kaminari.config.param_name = :page }\n\n    it 'picks the page value from params' do\n      visit history_index_path(model_name: 'paper_trail_test', pagina: 2)\n      is_expected.to have_css(%([href=\"/admin/paper_trail_test/#{paper_trail_test.id}\"]), count: 11)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/history_show_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'HistoryShow action', type: :request, active_record: true do\n  let(:user) { FactoryBot.create :user }\n  let(:paper_trail_test) { FactoryBot.create :paper_trail_test }\n  before(:each) do\n    RailsAdmin.config do |config|\n      config.audit_with :paper_trail, 'User', 'PaperTrail::Version'\n    end\n\n    PaperTrail::Version.delete_all\n    with_versioning do\n      PaperTrail.request.whodunnit = user.id\n      30.times do |i|\n        paper_trail_test.update!(name: \"updated name #{i}\")\n      end\n    end\n  end\n\n  it 'shows the history' do\n    visit history_show_path(model_name: 'paper_trail_test', id: paper_trail_test.id)\n    expect(all('table#history tbody tr').count).to eq(20)\n  end\n\n  it 'supports pagination' do\n    visit history_show_path(model_name: 'paper_trail_test', id: paper_trail_test.id, page: 2)\n    expect(all('table#history tbody tr').count).to eq(11)\n  end\n\n  context \"when Kaminari's custom param_name is set\" do\n    before { Kaminari.config.param_name = :pagina }\n    after { Kaminari.config.param_name = :page }\n\n    it 'picks the page value from params' do\n      visit history_show_path(model_name: 'paper_trail_test', id: paper_trail_test.id, pagina: 2)\n      expect(all('table#history tbody tr').count).to eq(11)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/index_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Index action', type: :request do\n  subject { page }\n\n  describe 'page' do\n    it 'shows \"List of Models\", should show filters and should show column headers' do\n      RailsAdmin.config.default_items_per_page = 1\n      2.times { FactoryBot.create :player } # two pages of players\n      visit index_path(model_name: 'player')\n      is_expected.to have_content('List of Players')\n      is_expected.to have_content('Created at')\n      is_expected.to have_content('Updated at')\n\n      # it \"shows the show, edit and delete links\" do\n      is_expected.to have_selector(\"li[title='Show'] a\")\n      is_expected.to have_selector(\"li[title='Edit'] a\")\n      is_expected.to have_selector(\"li[title='Delete'] a\")\n\n      # it \"has the search box with some prompt text\" do\n      is_expected.to have_selector(\"input[placeholder='Filter']\")\n\n      # https://github.com/railsadminteam/rails_admin/issues/362\n      # test that no link uses the \"wildcard route\" with the main\n      # controller and list method\n      # it \"does not use the 'wildcard route'\" do\n      is_expected.to have_selector(\"a[href*='all=true']\") # make sure we're fully testing pagination\n      is_expected.to have_no_selector(\"a[href^='/rails_admin/main/list']\")\n    end\n  end\n\n  describe 'css hooks' do\n    it 'is present' do\n      RailsAdmin.config Team do\n        list do\n          field :name\n        end\n      end\n      FactoryBot.create :team\n      visit index_path(model_name: 'team')\n      is_expected.to have_selector('th.header.string_type.name_field')\n      is_expected.to have_selector('td.string_type.name_field')\n    end\n  end\n\n  describe 'with querying and filtering' do\n    before do\n      @teams = Array.new(2) do\n        FactoryBot.create(:team)\n      end\n      @players = [\n        FactoryBot.create(:player, retired: true, injured: true, team: @teams[0]),\n        FactoryBot.create(:player, retired: true, injured: false, team: @teams[0]),\n        FactoryBot.create(:player, retired: false, injured: true, team: @teams[1]),\n        FactoryBot.create(:player, retired: false, injured: false, team: @teams[1]),\n      ]\n      @comment = FactoryBot.create(:comment, commentable: @players[2])\n    end\n\n    it 'allows to query on any attribute' do\n      RailsAdmin.config Player do\n        list do\n          field :name\n          field :team\n          field :injured\n          field :retired\n        end\n      end\n\n      visit index_path(model_name: 'player', query: @players[0].name)\n      is_expected.to have_content(@players[0].name)\n      (1..3).each do |i|\n        is_expected.to have_no_content(@players[i].name)\n      end\n    end\n\n    it 'allows to clear the search query box', js: true do\n      visit index_path(model_name: 'player', query: @players[0].name)\n      is_expected.not_to have_content(@players[1].name)\n      find_button('Reset filters').click\n      is_expected.to have_content(@players[1].name)\n    end\n\n    it 'allows to filter on one attribute' do\n      RailsAdmin.config Player do\n        list do\n          field :name\n          field :team\n          field :injured\n          field :retired\n        end\n      end\n\n      visit index_path(model_name: 'player', f: {injured: {'1' => {v: 'true'}}})\n      is_expected.to have_content(@players[0].name)\n      is_expected.to have_no_content(@players[1].name)\n      is_expected.to have_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'allows to combine filters on two different attributes' do\n      RailsAdmin.config Player do\n        list do\n          field :name\n          field :team\n          field :injured\n          field :retired\n        end\n      end\n\n      visit index_path(model_name: 'player', f: {retired: {'1' => {v: 'true'}}, injured: {'1' => {v: 'true'}}})\n      is_expected.to have_content(@players[0].name)\n      (1..3).each do |i|\n        is_expected.to have_no_content(@players[i].name)\n      end\n    end\n\n    it 'allows to filter on belongs_to relationships' do\n      RailsAdmin.config Player do\n        list do\n          field :name\n          field :team\n          field :injured\n          field :retired\n        end\n      end\n\n      visit index_path(model_name: 'player', f: {team: {'1' => {v: @teams[0].name}}})\n      is_expected.to have_content(@players[0].name)\n      is_expected.to have_content(@players[1].name)\n      is_expected.to have_no_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'allows to filter on has_one relationships' do\n      @draft = FactoryBot.create(:draft, player: @players[1], college: 'University of Alabama')\n      RailsAdmin.config Player do\n        list do\n          field :name\n          field :draft do\n            searchable :college\n          end\n        end\n      end\n\n      visit index_path(model_name: 'player', f: {draft: {'1' => {v: 'Alabama'}}})\n      is_expected.to have_content(@players[1].name)\n      is_expected.to have_css('tbody .name_field', count: 1)\n    end\n\n    it 'allows to disable search on attributes' do\n      RailsAdmin.config Player do\n        list do\n          field :position\n          field :name do\n            searchable false\n          end\n        end\n      end\n      visit index_path(model_name: 'player', query: @players[0].name)\n      is_expected.to have_no_content(@players[0].name)\n    end\n\n    it 'allows to search a belongs_to attribute over the base table' do\n      RailsAdmin.config Player do\n        list do\n          field PK_COLUMN\n          field :name\n          field :team do\n            searchable Player => :team_id\n          end\n        end\n      end\n      visit index_path(model_name: 'player', f: {team: {'1' => {v: @teams.first.id}}})\n      is_expected.to have_content(@players[0].name)\n      is_expected.to have_content(@players[1].name)\n      is_expected.to have_no_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'allows to search a belongs_to attribute over the target table' do\n      RailsAdmin.config Player do\n        list do\n          field PK_COLUMN\n          field :name\n          field :team do\n            searchable Team => :name\n          end\n        end\n      end\n      visit index_path(model_name: 'player', f: {team: {'1' => {v: @teams.first.name}}})\n      is_expected.to have_content(@players[0].name)\n      is_expected.to have_content(@players[1].name)\n      is_expected.to have_no_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'allows to search a belongs_to attribute over the target table with a table name specified as a hash' do\n      RailsAdmin.config Player do\n        list do\n          field PK_COLUMN\n          field :name\n          field :team do\n            searchable teams: :name\n          end\n        end\n      end\n      visit index_path(model_name: 'player', f: {team: {'1' => {v: @teams.first.name}}})\n      is_expected.to have_content(@players[0].name)\n      is_expected.to have_content(@players[1].name)\n      is_expected.to have_no_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'allows to search a belongs_to attribute over the target table with a table name specified as a string' do\n      RailsAdmin.config Player do\n        list do\n          field PK_COLUMN\n          field :name\n          field :team do\n            searchable 'teams.name'\n          end\n        end\n      end\n      visit index_path(model_name: 'player', f: {team: {'1' => {v: @teams.first.name}}})\n      is_expected.to have_content(@players[0].name)\n      is_expected.to have_content(@players[1].name)\n      is_expected.to have_no_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'allows to search a belongs_to attribute over the label method by default' do\n      RailsAdmin.config Player do\n        list do\n          field PK_COLUMN\n          field :name\n          field :team\n        end\n      end\n      visit index_path(model_name: 'player', f: {team: {'1' => {v: @teams.first.name}}})\n      is_expected.to have_content(@players[0].name)\n      is_expected.to have_content(@players[1].name)\n      is_expected.to have_no_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'allows to search a belongs_to attribute over the target table when an attribute is specified' do\n      RailsAdmin.config Player do\n        list do\n          field PK_COLUMN\n          field :name\n          field :team do\n            searchable :name\n          end\n        end\n      end\n      visit index_path(model_name: 'player', f: {team: {'1' => {v: @teams.first.name}}})\n      is_expected.to have_content(@players[0].name)\n      is_expected.to have_content(@players[1].name)\n      is_expected.to have_no_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'allows to search over more than one attribute' do\n      RailsAdmin.config Player do\n        list do\n          field PK_COLUMN\n          field :name\n          field :team do\n            searchable [:name, {Player => :team_id}]\n          end\n        end\n      end\n      visit index_path(model_name: 'player', f: {team: {'1' => {v: @teams.first.name}, '2' => {v: @teams.first.id, o: 'is'}}})\n      is_expected.to have_content(@players[0].name)\n      is_expected.to have_content(@players[1].name)\n      is_expected.to have_no_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n      # same with a different id\n      visit index_path(model_name: 'player', f: {team: {'1' => {v: @teams.first.name}, '2' => {v: @teams.last.id, o: 'is'}}})\n      is_expected.to have_no_content(@players[0].name)\n      is_expected.to have_no_content(@players[1].name)\n      is_expected.to have_no_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'allows to search a has_many attribute over the target table' do\n      RailsAdmin.config Player do\n        list do\n          field PK_COLUMN\n          field :name\n          field :comments do\n            searchable :content\n          end\n        end\n      end\n      visit index_path(model_name: 'player', f: {comments: {'1' => {v: @comment.content}}})\n      is_expected.to have_no_content(@players[0].name)\n      is_expected.to have_no_content(@players[1].name)\n      is_expected.to have_content(@players[2].name)\n      is_expected.to have_no_content(@players[3].name)\n    end\n\n    it 'displays base filters when no filters are present in the params' do\n      RailsAdmin.config Player do\n        list { filters(%i[name team]) }\n        field :name do\n          default_filter_operator 'is'\n        end\n        field :team do\n          filterable true\n        end\n      end\n      visit index_path(model_name: 'player')\n\n      expect(JSON.parse(find('#filters_box')['data-options']).map(&:symbolize_keys)).to match_array [\n        {\n          index: 1,\n          label: 'Name',\n          name: 'name',\n          type: 'string',\n          value: '',\n          operator: 'is',\n          operators: %w[_discard like not_like is starts_with ends_with],\n        },\n        {\n          index: 2,\n          label: 'Team',\n          name: 'team',\n          type: 'belongs_to_association',\n          value: '',\n          operator: nil,\n          operators: %w[_discard like not_like is starts_with ends_with _separator _present _blank],\n        },\n      ]\n    end\n\n    it 'shows the help text below the search box' do\n      RailsAdmin.config Player do\n        list do\n          search_help 'Use this box to search!'\n        end\n      end\n      visit index_path(model_name: 'player')\n      is_expected.to have_css('.form-text', text: /Use this box/)\n    end\n  end\n\n  describe 'fields' do\n    before do\n      if defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new('7.1') || defined?(CompositePrimaryKeys)\n        RailsAdmin.config Fan do\n          configure(:fanships) { hide }\n          configure(:fanship) { hide }\n        end\n      end\n    end\n    it 'shows all by default' do\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Id', 'Created at', 'Updated at', 'Their Name', 'Teams']\n    end\n\n    it 'hides some fields on demand with a block' do\n      RailsAdmin.config Fan do\n        list do\n          exclude_fields_if do\n            type == :datetime\n          end\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Id', 'Their Name', 'Teams']\n    end\n\n    it 'hides some fields on demand with fields list' do\n      RailsAdmin.config Fan do\n        list do\n          exclude_fields :created_at, :updated_at\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Id', 'Their Name', 'Teams']\n    end\n\n    it 'adds some fields on demand with a block' do\n      RailsAdmin.config Fan do\n        list do\n          include_fields_if do\n            type != :datetime\n          end\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Id', 'Their Name', 'Teams']\n    end\n\n    it 'shows some fields on demand with fields list, respect ordering and configure them' do\n      RailsAdmin.config Fan do\n        list do\n          fields :name, PK_COLUMN do\n            label do\n              \"Modified #{label}\"\n            end\n          end\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Modified Id', 'Modified Their Name']\n    end\n\n    it 'shows all fields if asked' do\n      RailsAdmin.config Fan do\n        list do\n          include_all_fields\n          field PK_COLUMN\n          field :name\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Id', 'Created at', 'Updated at', 'Their Name', 'Teams']\n    end\n\n    it 'appears in order defined' do\n      RailsAdmin.config Fan do\n        list do\n          field :updated_at\n          field :name\n          field PK_COLUMN\n          field :created_at\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to eq(['Updated at', 'Their Name', 'Id', 'Created at'])\n    end\n\n    it 'only lists the defined fields if some fields are defined' do\n      RailsAdmin.config Fan do\n        list do\n          field PK_COLUMN\n          field :name\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to eq(['Id', 'Their Name'])\n      is_expected.to have_no_selector('th:nth-child(4).header')\n    end\n\n    it 'delegates the label option to the ActiveModel API' do\n      RailsAdmin.config Fan do\n        list do\n          field :name\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(find('th:nth-child(2)')).to have_content('Their Name')\n    end\n\n    it 'is renameable' do\n      RailsAdmin.config Fan do\n        list do\n          field PK_COLUMN do\n            label 'Identifier'\n          end\n          field :name\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(find('th:nth-child(2)')).to have_content('Identifier')\n      expect(find('th:nth-child(3)')).to have_content('Their Name')\n    end\n\n    it 'is renameable by type' do\n      RailsAdmin.config Fan do\n        list do\n          fields_of_type :datetime do\n            label { \"#{label} (datetime)\" }\n          end\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Id', 'Created at (datetime)', 'Updated at (datetime)', 'Their Name', 'Teams']\n    end\n\n    it 'is globally renameable by type' do\n      RailsAdmin.config Fan do\n        list do\n          fields_of_type :datetime do\n            label { \"#{label} (datetime)\" }\n          end\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Id', 'Created at (datetime)', 'Updated at (datetime)', 'Their Name', 'Teams']\n    end\n\n    it 'is sortable by default' do\n      visit index_path(model_name: 'fan')\n      is_expected.to have_selector('th:nth-child(2).header')\n      is_expected.to have_selector('th:nth-child(3).header')\n      is_expected.to have_selector('th:nth-child(4).header')\n      is_expected.to have_selector('th:nth-child(5).header')\n    end\n\n    it 'has option to disable sortability' do\n      RailsAdmin.config Fan do\n        list do\n          field PK_COLUMN do\n            sortable false\n          end\n          field :name\n        end\n      end\n      visit index_path(model_name: 'fan')\n      is_expected.to have_no_selector('th:nth-child(2).header')\n      is_expected.to have_selector('th:nth-child(3).header')\n    end\n\n    it 'has option to disable sortability by type' do\n      RailsAdmin.config Fan do\n        list do\n          fields_of_type :datetime do\n            sortable false\n          end\n          field PK_COLUMN\n          field :name\n          field :created_at\n          field :updated_at\n        end\n      end\n      visit index_path(model_name: 'fan')\n      is_expected.to have_selector('th:nth-child(2).header')\n      is_expected.to have_selector('th:nth-child(3).header')\n      is_expected.to have_no_selector('th:nth-child(4).header')\n      is_expected.to have_no_selector('th:nth-child(5).header')\n    end\n\n    it 'has option to disable sortability by type globally' do\n      RailsAdmin.config Fan do\n        list do\n          fields_of_type :datetime do\n            sortable false\n          end\n          field PK_COLUMN\n          field :name\n          field :created_at\n          field :updated_at\n        end\n      end\n      visit index_path(model_name: 'fan')\n      is_expected.to have_selector('th:nth-child(2).header')\n      is_expected.to have_selector('th:nth-child(3).header')\n      is_expected.to have_no_selector('th:nth-child(4).header')\n      is_expected.to have_no_selector('th:nth-child(5).header')\n    end\n\n    it 'has option to hide fields by type' do\n      RailsAdmin.config Fan do\n        list do\n          fields_of_type :datetime do\n            hide\n          end\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Id', 'Their Name', 'Teams']\n    end\n\n    it 'has option to hide fields by type globally' do\n      RailsAdmin.config Fan do\n        list do\n          fields_of_type :datetime do\n            hide\n          end\n        end\n      end\n      visit index_path(model_name: 'fan')\n      expect(all('th').collect(&:text).delete_if { |t| /^\\n*$/ =~ t }).\n        to match_array ['Id', 'Their Name', 'Teams']\n    end\n\n    it 'has option to customize column width' do\n      RailsAdmin.config Fan do\n        list do\n          field PK_COLUMN do\n            column_width 200\n          end\n          field :name\n          field :created_at\n          field :updated_at\n        end\n      end\n      @fans = FactoryBot.create_list(:fan, 2)\n      visit index_path(model_name: 'fan')\n      # NOTE: Capybara really doesn't want us to look at invisible text. This test\n      # could break at any moment.\n      expect(find('style').native.text).to include(\"#list th.#{PK_COLUMN}_field\")\n      expect(find('style').native.text).to include(\"#list td.#{PK_COLUMN}_field\")\n    end\n\n    it 'has option to customize output formatting' do\n      RailsAdmin.config Fan do\n        list do\n          field PK_COLUMN\n          field :name do\n            formatted_value do\n              value.to_s.upcase\n            end\n          end\n          field :created_at\n          field :updated_at\n        end\n      end\n      @fans = FactoryBot.create_list(:fan, 2).sort_by(&:id)\n      visit index_path(model_name: 'fan')\n      expect(find('tbody tr:nth-child(1) td:nth-child(3)')).to have_content(@fans[1].name.upcase)\n      expect(find('tbody tr:nth-child(2) td:nth-child(3)')).to have_content(@fans[0].name.upcase)\n    end\n\n    it 'has a simple option to customize output formatting of date fields' do\n      RailsAdmin.config Fan do\n        list do\n          field PK_COLUMN\n          field :name\n          field :created_at do\n            date_format :short\n          end\n          field :updated_at\n        end\n      end\n      @fans = FactoryBot.create_list(:fan, 2)\n      visit index_path(model_name: 'fan')\n      is_expected.to have_selector('tbody tr:nth-child(1) td:nth-child(4)', text: /\\d{2} \\w{3} \\d{1,2}:\\d{1,2}/)\n    end\n\n    it 'has option to customize output formatting of date fields' do\n      RailsAdmin.config Fan do\n        list do\n          field PK_COLUMN\n          field :name\n          field :created_at do\n            strftime_format '%Y-%m-%d'\n          end\n          field :updated_at\n        end\n      end\n      @fans = FactoryBot.create_list(:fan, 2)\n      visit index_path(model_name: 'fan')\n      is_expected.to have_selector('tbody tr:nth-child(1) td:nth-child(4)', text: /\\d{4}-\\d{2}-\\d{2}/)\n    end\n\n    it 'allows addition of virtual fields (object methods)' do\n      RailsAdmin.config Team do\n        list do\n          field PK_COLUMN\n          field :name\n          field :player_names_truncated\n        end\n      end\n      @team = FactoryBot.create :team\n      @players = FactoryBot.create_list :player, 2, team: @team\n      visit index_path(model_name: 'team')\n      expect(find('tbody tr:nth-child(1) td:nth-child(4)')).to have_content(@players.sort_by(&:id).collect(&:name).join(', '))\n    end\n\n    describe 'with title attribute' do\n      it 'does not allow XSS' do\n        RailsAdmin.config Team do\n          list do\n            field :name\n          end\n        end\n        @team = FactoryBot.create :team, name: '\" onclick=\"alert()\" \"'\n        visit index_path(model_name: 'team')\n        expect(find('tbody tr:nth-child(1) td:nth-child(2)')['onclick']).to be_nil\n        expect(find('tbody tr:nth-child(1) td:nth-child(2)')['title']).to eq '\" onclick=\"alert()\" \"'\n      end\n\n      it 'does not break values with HTML tags' do\n        RailsAdmin.config Player do\n          list do\n            field :team\n          end\n        end\n        @player = FactoryBot.create :player, team: FactoryBot.create(:team)\n        visit index_path(model_name: 'player')\n        expect(find('tbody tr:nth-child(1) td:nth-child(2)')['title']).to eq @player.team.name\n      end\n    end\n  end\n\n  context 'when no record exists' do\n    before do\n      visit index_path(model_name: 'player')\n    end\n\n    it 'shows \"No records found\" message' do\n      is_expected.to have_content('No records found')\n    end\n  end\n\n  context 'without pagination' do\n    before do\n      @players = FactoryBot.create_list(:player, 2)\n      visit index_path(model_name: 'player')\n    end\n\n    it 'shows \"2 results\"' do\n      is_expected.to have_content('2 players')\n    end\n  end\n\n  context 'with pagination' do\n    def visit_page(page)\n      visit index_path(model_name: 'player', page: page)\n    end\n\n    before do\n      FactoryBot.create_list :player, 3\n    end\n\n    describe 'with limited_pagination=false' do\n      before { RailsAdmin.config.default_items_per_page = 1 }\n\n      it 'page 1' do\n        visit_page(1)\n\n        within('ul.pagination') do\n          expect(find('li:first')).to have_content('« Prev')\n          expect(find('li:last')).to have_content('Next »')\n          expect(find('li.active')).to have_content('1')\n        end\n      end\n\n      it 'page 2' do\n        visit_page(2)\n\n        within('ul.pagination') do\n          expect(find('li:first')).to have_content('« Prev')\n          expect(find('li:last')).to have_content('Next »')\n          expect(find('li.active')).to have_content('2')\n        end\n      end\n\n      it 'page 3' do\n        visit_page(3)\n\n        within('ul.pagination') do\n          expect(find('li:first')).to have_content('« Prev')\n          expect(find('li:last')).to have_content('Next »')\n          expect(find('li.active')).to have_content('3')\n        end\n      end\n    end\n\n    context 'with limited_pagination=true' do\n      before do\n        RailsAdmin.config.default_items_per_page = 1\n        allow(RailsAdmin::AbstractModel.new(Player).config.list).\n          to receive(:limited_pagination).\n          and_return(true)\n      end\n\n      it 'page 1' do\n        visit_page(1)\n\n        within('ul.pagination') do\n          expect(find('li:first')).not_to have_content('« Prev')\n          expect(find('li:last')).to have_content('Next »')\n        end\n      end\n\n      it 'page 2' do\n        visit_page(2)\n\n        within('ul.pagination') do\n          expect(find('li:first')).to have_content('« Prev')\n          expect(find('li:last')).to have_content('Next »')\n        end\n      end\n\n      it 'page 3' do\n        visit_page(3)\n\n        within('ul.pagination') do\n          expect(find('li:first')).to have_content('« Prev')\n          expect(find('li:last')).to have_content('Next »')\n        end\n      end\n    end\n\n    describe 'number of items per page' do\n      before do\n        FactoryBot.create_list :league, 2\n      end\n\n      it 'is configurable per model' do\n        RailsAdmin.config League do\n          list do\n            items_per_page 1\n          end\n        end\n        visit index_path(model_name: 'league')\n        is_expected.to have_selector('tbody tr', count: 1)\n        visit index_path(model_name: 'player')\n        is_expected.to have_selector('tbody tr', count: 3)\n      end\n    end\n  end\n\n  context 'on showing all' do\n    it 'responds successfully with a single model' do\n      FactoryBot.create :player\n      visit index_path(model_name: 'player', all: true)\n      expect(find('div.total-count')).to have_content('1 player')\n      expect(find('div.total-count')).not_to have_content('1 players')\n    end\n\n    it 'responds successfully with multiple models' do\n      FactoryBot.create_list(:player, 2)\n      visit index_path(model_name: 'player', all: true)\n      expect(find('div.total-count')).to have_content('2 players')\n    end\n  end\n\n  context 'with pagination disabled by :associated_collection' do\n    it 'responds successfully' do\n      @team = FactoryBot.create :team\n      Array.new(2) { FactoryBot.create :player, team: @team }\n      visit index_path(model_name: 'player', associated_collection: 'players', compact: true, current_action: 'update', source_abstract_model: 'team', source_object_id: @team.id)\n      expect(find('div.total-count')).to have_content('2 players')\n    end\n  end\n\n  describe 'sorting' do\n    let(:today) { Date.today }\n    let(:players) do\n      [{name: 'Jackie Robinson',  created_at: today,            team_id: rand(99_999), number: 42},\n       {name: 'Deibinson Romero', created_at: (today - 2.days), team_id: rand(99_999), number: 13},\n       {name: 'Sandy Koufax',     created_at: (today - 1.days), team_id: rand(99_999), number: 32}]\n    end\n    let(:leagues) do\n      [{name: 'American',      created_at: (today - 1.day)},\n       {name: 'Florida State', created_at: (today - 2.days)},\n       {name: 'National',      created_at: today}]\n    end\n    let(:player_names_by_date) { players.sort_by { |p| p[:created_at] }.collect { |p| p[:name] } }\n    let(:league_names_by_date) { leagues.sort_by { |l| l[:created_at] }.collect { |l| l[:name] } }\n\n    before { @players = players.collect { |h| Player.create(h) } }\n\n    it 'has reverse direction by default' do\n      RailsAdmin.config Player do\n        list do\n          sort_by :created_at\n          field :name\n        end\n      end\n      visit index_path(model_name: 'player')\n      player_names_by_date.reverse.each_with_index do |name, i|\n        expect(find(\"tbody tr:nth-child(#{i + 1})\")).to have_content(name)\n      end\n    end\n\n    it 'allows change direction by using field configuration' do\n      RailsAdmin.config Player do\n        list do\n          sort_by :created_at\n          configure :created_at do\n            sort_reverse false\n          end\n          field :name\n        end\n      end\n      visit index_path(model_name: 'player')\n      player_names_by_date.each_with_index do |name, i|\n        expect(find(\"tbody tr:nth-child(#{i + 1})\")).to have_content(name)\n      end\n    end\n\n    it 'can be activated by clicking the table header', js: true do\n      visit index_path(model_name: 'player')\n      find('th.header', text: 'Name').trigger('click')\n      is_expected.to have_css('th.name_field.headerSortDown')\n      expect(all('tbody td.name_field').map(&:text)).to eq @players.map(&:name).sort\n    end\n  end\n\n  context 'on listing as compact json' do\n    it 'has_content an array with 2 elements and contain an array of elements with keys id and label' do\n      FactoryBot.create_list(:player, 2)\n      get index_path(model_name: 'player', compact: true, format: :json)\n      expect(ActiveSupport::JSON.decode(response.body).length).to eq(2)\n      ActiveSupport::JSON.decode(response.body).each do |object|\n        expect(object).to have_key('id')\n        expect(object).to have_key('label')\n      end\n    end\n  end\n\n  describe 'with search operator' do\n    let(:player) { FactoryBot.create :player }\n\n    before do\n      expect(Player.count).to eq(0)\n    end\n\n    it 'finds the player if the query matches the default search operator' do\n      RailsAdmin.config do |config|\n        config.default_search_operator = 'ends_with'\n        config.model Player do\n          list { field :name }\n        end\n      end\n      visit index_path(model_name: 'player', query: player.name[2, -1])\n      is_expected.to have_content(player.name)\n    end\n\n    it 'does not find the player if the query does not match the default search operator' do\n      RailsAdmin.config do |config|\n        config.default_search_operator = 'ends_with'\n        config.model Player do\n          list { field :name }\n        end\n      end\n      visit index_path(model_name: 'player', query: player.name[0, 2])\n      is_expected.to have_no_content(player.name)\n    end\n\n    it 'finds the player if the query matches the specified search operator' do\n      RailsAdmin.config Player do\n        list do\n          field :name do\n            search_operator 'starts_with'\n          end\n        end\n      end\n      visit index_path(model_name: 'player', query: player.name[0, 2])\n      is_expected.to have_content(player.name)\n    end\n\n    it 'does not find the player if the query does not match the specified search operator' do\n      RailsAdmin.config Player do\n        list do\n          field :name do\n            search_operator 'starts_with'\n          end\n        end\n      end\n      visit index_path(model_name: 'player', query: player.name[1..])\n      is_expected.to have_no_content(player.name)\n    end\n  end\n\n  describe 'with custom search' do\n    before do\n      RailsAdmin.config do |config|\n        config.model Player do\n          list do\n            search_by :rails_admin_search\n          end\n        end\n      end\n    end\n    let!(:players) do\n      [FactoryBot.create(:player, name: 'Joe'),\n       FactoryBot.create(:player, name: 'George')]\n    end\n\n    it 'performs search using given scope' do\n      visit index_path(model_name: 'player', query: 'eoJ')\n      is_expected.to have_content(players[0].name)\n      is_expected.to have_no_content(players[1].name)\n    end\n  end\n\n  context 'with overridden to_param' do\n    before do\n      @ball = FactoryBot.create :ball\n\n      visit index_path(model_name: 'ball')\n    end\n\n    it 'shows the show, edit and delete links with valid url' do\n      is_expected.to have_selector(\"td a[href$='/admin/ball/#{@ball.id}']\")\n      is_expected.to have_selector(\"td a[href$='/admin/ball/#{@ball.id}/edit']\")\n      is_expected.to have_selector(\"td a[href$='/admin/ball/#{@ball.id}/delete']\")\n    end\n  end\n\n  describe 'with model scope' do\n    context 'without default scope' do\n      let!(:teams) { %w[red yellow blue].map { |color| FactoryBot.create :team, color: color } }\n\n      it 'works', active_record: true do\n        RailsAdmin.config do |config|\n          config.model Team do\n            scope { Team.where(color: %w[red blue]) }\n          end\n        end\n        visit index_path(model_name: 'team')\n        expect(all(:css, 'td.color_field').map(&:text)).to match_array %w[red blue]\n      end\n\n      it 'works', mongoid: true do\n        RailsAdmin.config do |config|\n          config.model Team do\n            scope { Team.any_in(color: %w[red blue]) }\n          end\n        end\n        visit index_path(model_name: 'team')\n        expect(all(:css, 'td.color_field').map(&:text)).to match_array %w[red blue]\n      end\n    end\n\n    context 'with default_scope' do\n      let!(:comments) { %w[something anything].map { |content| FactoryBot.create :comment_confirmed, content: content } }\n      before do\n        RailsAdmin.config do |config|\n          config.model Comment::Confirmed do\n            scope { Comment::Confirmed.unscoped }\n          end\n        end\n      end\n\n      it 'can be overriden' do\n        visit index_path(model_name: 'comment~confirmed')\n        expect(all(:css, 'td.content_field').map(&:text)).to match_array %w[something anything]\n      end\n    end\n  end\n\n  describe 'with scopes' do\n    before do\n      RailsAdmin.config do |config|\n        config.model Team do\n          list do\n            scopes [nil, :red, :white]\n          end\n        end\n      end\n      @teams = [\n        FactoryBot.create(:team, color: 'red'),\n        FactoryBot.create(:team, color: 'red'),\n        FactoryBot.create(:team, color: 'white'),\n        FactoryBot.create(:team, color: 'black'),\n      ]\n    end\n\n    it 'displays configured scopes' do\n      visit index_path(model_name: 'team')\n      expect(find('#scope_selector li:first')).to have_content('All')\n      expect(find('#scope_selector li:nth-child(2)')).to have_content('Red')\n      expect(find('#scope_selector li:nth-child(3)')).to have_content('White')\n      expect(find('#scope_selector li:last')).to have_content('White')\n      expect(find('#scope_selector li a.active')).to have_content('All')\n    end\n\n    it 'shows only scoped records' do\n      visit index_path(model_name: 'team')\n      is_expected.to have_content(@teams[0].name)\n      is_expected.to have_content(@teams[1].name)\n      is_expected.to have_content(@teams[2].name)\n      is_expected.to have_content(@teams[3].name)\n\n      visit index_path(model_name: 'team', scope: 'red')\n      expect(find('#scope_selector li a.active')).to have_content('Red')\n      is_expected.to have_content(@teams[0].name)\n      is_expected.to have_content(@teams[1].name)\n      is_expected.to have_no_content(@teams[2].name)\n      is_expected.to have_no_content(@teams[3].name)\n\n      visit index_path(model_name: 'team', scope: 'white')\n      expect(find('#scope_selector li a.active')).to have_content('White')\n      is_expected.to have_no_content(@teams[0].name)\n      is_expected.to have_no_content(@teams[1].name)\n      is_expected.to have_content(@teams[2].name)\n      is_expected.to have_no_content(@teams[3].name)\n    end\n\n    it 'shows all records instead when scope not in list' do\n      visit index_path(model_name: 'team', scope: 'green')\n      is_expected.to have_content(@teams[0].name)\n      is_expected.to have_content(@teams[1].name)\n      is_expected.to have_content(@teams[2].name)\n      is_expected.to have_content(@teams[3].name)\n    end\n\n    describe 'i18n' do\n      before :each do\n        en = {admin: {scopes: {\n          _all: 'every',\n          red: 'krasnyj',\n        }}}\n        I18n.backend.store_translations(:en, en)\n      end\n      after { I18n.reload! }\n\n      context 'global' do\n        it 'displays configured scopes' do\n          visit index_path(model_name: 'team')\n          expect(find('#scope_selector li:first')).to have_content('every')\n          expect(find('#scope_selector li:nth-child(2)')).to have_content('krasnyj')\n          expect(find('#scope_selector li:nth-child(3)')).to have_content('White')\n          expect(find('#scope_selector li:last')).to have_content('White')\n          expect(find('#scope_selector li a.active')).to have_content('every')\n        end\n      end\n\n      context 'per model' do\n        before :each do\n          en = {admin: {scopes: {team: {\n            _all: 'any',\n            red: 'kr',\n          }}}}\n          I18n.backend.store_translations(:en, en)\n        end\n        after { I18n.reload! }\n\n        it 'displays configured scopes' do\n          visit index_path(model_name: 'team')\n          expect(find('#scope_selector li:first')).to have_content('any')\n          expect(find('#scope_selector li:nth-child(2)')).to have_content('kr')\n          expect(find('#scope_selector li:nth-child(3)')).to have_content('White')\n          expect(find('#scope_selector li:last')).to have_content('White')\n          expect(find('#scope_selector li a.active')).to have_content('any')\n        end\n      end\n    end\n  end\n\n  describe 'row CSS class' do\n    before do\n      RailsAdmin.config do |config|\n        config.model Team do\n          list do\n            row_css_class { 'my_class' }\n          end\n        end\n      end\n      @teams = [\n        FactoryBot.create(:team, color: 'red'),\n        FactoryBot.create(:team, color: 'red'),\n        FactoryBot.create(:team, color: 'white'),\n        FactoryBot.create(:team, color: 'black'),\n      ]\n    end\n\n    it 'appends the CSS class to the model row class' do\n      visit index_path(model_name: 'team')\n      expect(page).to have_css('tr.team_row.my_class')\n    end\n  end\n\n  describe 'checkboxes?' do\n    describe 'default is enabled' do\n      before do\n        RailsAdmin.config FieldTest do\n          list\n        end\n      end\n\n      it 'displays checkboxes on index' do\n        @records = FactoryBot.create_list :field_test, 3\n\n        visit index_path(model_name: 'field_test')\n        checkboxes = all(:xpath, './/form[@id=\"bulk_form\"]//input[@type=\"checkbox\"]')\n        expect(checkboxes.length).to be > 0\n\n        expect(page).to have_content('Selected items')\n      end\n    end\n\n    describe 'false' do\n      before do\n        RailsAdmin.config FieldTest do\n          list do\n            checkboxes false\n          end\n        end\n      end\n\n      it 'does not display any checkboxes on index' do\n        @records = FactoryBot.create_list :field_test, 3\n\n        visit index_path(model_name: 'field_test')\n        checkboxes = all(:xpath, './/form[@id=\"bulk_form\"]//input[@type=\"checkbox\"]')\n        expect(checkboxes.length).to eq 0\n\n        expect(page).not_to have_content('Selected items')\n      end\n    end\n  end\n\n  describe 'sidescroll' do\n    all_team_columns = ['', 'Id', 'Created at', 'Updated at', 'Division', 'Name', 'Logo url', 'Team Manager', 'Ballpark', 'Mascot', 'Founded', 'Wins', 'Losses', 'Win percentage', 'Revenue', 'Color', 'Custom field', 'Main Sponsor', 'Players', 'Some Fans', 'Comments', '']\n\n    it 'displays all fields on one page' do\n      FactoryBot.create_list :team, 3\n      visit index_path(model_name: 'team')\n      cols = all('th').collect(&:text)\n      expect(cols[0..4]).to eq(all_team_columns[0..4])\n      expect(cols).to contain_exactly(*all_team_columns)\n    end\n\n    it 'allows fields to be sticky' do\n      RailsAdmin.config Team do\n        list do\n          configure(:division) { sticky true }\n          configure(:name) { sticky true }\n        end\n      end\n      FactoryBot.create_list :team, 3\n      visit index_path(model_name: 'team')\n      cols = all('th').collect(&:text)\n      expect(cols[0..4]).to eq(['', 'Division', 'Name', 'Id', 'Created at'])\n      expect(cols).to contain_exactly(*all_team_columns)\n      expect(page).to have_selector('.name_field.sticky')\n      expect(page).to have_selector('.division_field.sticky')\n    end\n\n    it 'displays all fields with no checkboxes' do\n      RailsAdmin.config Team do\n        list do\n          checkboxes false\n        end\n      end\n      FactoryBot.create_list :team, 3\n      visit index_path(model_name: 'team')\n      cols = all('th').collect(&:text)\n      expect(cols[0..3]).to eq(all_team_columns[1..4])\n      expect(cols).to contain_exactly(*all_team_columns[1..])\n    end\n  end\n\n  context 'with composite primary keys', composite_primary_keys: true do\n    let!(:fanships) { FactoryBot.create_list(:fanship, 3) }\n\n    it 'shows the list' do\n      visit index_path(model_name: 'fanship')\n      expect(all('th').collect(&:text)[0..3]).to eq(['', 'Fan', 'Team', 'Since'])\n      fanships.each do |fanship|\n        is_expected.to have_content fanship.fan.name\n        is_expected.to have_content fanship.team.name\n      end\n      is_expected.to have_content '3 fanships'\n    end\n\n    context 'using custom serializer' do\n      before do\n        RailsAdmin.config.composite_keys_serializer = Class.new do\n          def self.serialize(keys)\n            keys.join(',')\n          end\n\n          def self.deserialize(string)\n            string.split(',')\n          end\n        end\n      end\n\n      it 'shows the member action links accordingly' do\n        visit index_path(model_name: 'fanship')\n        is_expected.to have_css(%(a[href$=\"/admin/fanship/#{fanships[0].fan_id},#{fanships[0].team_id}/edit\"]))\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/new_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'New action', type: :request do\n  subject { page }\n\n  describe 'page' do\n    before do\n      visit new_path(model_name: 'player')\n    end\n\n    it 'shows \"New Model\"' do\n      is_expected.to have_content('New Player')\n    end\n\n    it 'shows required fields as \"Required\"' do\n      is_expected.to have_selector('div', text: /Name\\s*Required/)\n      is_expected.to have_selector('div', text: /Number\\s*Required/)\n    end\n\n    it 'shows non-required fields as \"Optional\"' do\n      is_expected.to have_selector('#player_position_field .form-text', text: 'Optional')\n      is_expected.to have_selector('#player_born_on_field .form-text', text: 'Optional')\n      is_expected.to have_selector('#player_notes_field .form-text', text: 'Optional')\n    end\n\n    # https://github.com/railsadminteam/rails_admin/issues/362\n    # test that no link uses the \"wildcard route\" with the main\n    # controller and new method\n    it \"does not use the 'wildcard route'\" do\n      is_expected.to have_no_selector(\"a[href^='/rails_admin/main/new']\")\n    end\n  end\n\n  context 'with missing label' do\n    before do\n      FactoryBot.create :team, name: ''\n      visit new_path(model_name: 'player')\n    end\n  end\n\n  context 'with parameters for pre-population' do\n    it 'populates form field when corresponding parameters are passed in' do\n      visit new_path(model_name: 'player', player: {name: 'Sam'})\n      expect(page).to have_css('input[value=Sam]')\n    end\n\n    it 'prepropulates has_one relationships' do\n      @draft = FactoryBot.create :draft\n      @player = FactoryBot.create :player, name: 'has_one association prepopulated'\n      visit new_path(model_name: 'player', player: {draft_id: @draft.id})\n      expect(page).to have_css(\"select#player_draft_id option[selected='selected'][value='#{@draft.id}']\")\n    end\n\n    it 'prepropulates has_many relationships' do\n      @player = FactoryBot.create :player, name: 'has_many association prepopulated'\n      visit new_path(model_name: 'team', team: {player_ids: [@player.id]})\n      expect(page).to have_css(\"select#team_player_ids option[selected='selected'][value='#{@player.id}']\")\n    end\n  end\n\n  context 'with namespaced model' do\n    it 'has correct input field names' do\n      visit new_path(model_name: 'cms~basic_page')\n      is_expected.to have_selector('label[for=cms_basic_page_title]')\n      is_expected.to have_selector(\"input#cms_basic_page_title[name='cms_basic_page[title]']\")\n      is_expected.to have_selector('label[for=cms_basic_page_content]')\n      is_expected.to have_selector(\"textarea#cms_basic_page_content[name='cms_basic_page[content]']\")\n    end\n\n    context 'with parameters for pre-population' do\n      it 'populates form field when corresponding parameters are passed in' do\n        visit new_path(model_name: 'cms~basic_page', cms_basic_page: {title: 'Hello'})\n        expect(page).to have_css('input[value=Hello]')\n      end\n    end\n\n    it 'creates object with correct attributes' do\n      visit new_path(model_name: 'cms~basic_page')\n\n      fill_in 'cms_basic_page[title]', with: 'Hello'\n      fill_in 'cms_basic_page[content]', with: 'World'\n      expect do\n        click_button 'Save' # first(:button, \"Save\").click\n      end.to change(Cms::BasicPage, :count).by(1)\n    end\n  end\n\n  context 'on create' do\n    before do\n      visit new_path(model_name: 'player')\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      fill_in 'player[number]', with: '42'\n      fill_in 'player[position]', with: 'Second baseman'\n      click_button 'Save'\n      @player = RailsAdmin::AbstractModel.new('Player').first\n    end\n\n    it 'creates an object with correct attributes' do\n      expect(@player.name).to eq('Jackie Robinson')\n      expect(@player.number).to eq(42)\n      expect(@player.position).to eq('Second baseman')\n    end\n  end\n\n  context 'on create and edit' do\n    before do\n      visit new_path(model_name: 'player')\n\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      fill_in 'player[number]', with: '42'\n      fill_in 'player[position]', with: 'Second baseman'\n      click_button 'Save and edit'\n\n      @player = RailsAdmin::AbstractModel.new('Player').first\n    end\n\n    it 'creates an object with correct attributes' do\n      expect(@player.name).to eq('Jackie Robinson')\n      expect(@player.number).to eq(42)\n      expect(@player.position).to eq('Second baseman')\n    end\n  end\n\n  context 'on create and add another', js: true do\n    before do\n      visit new_path(model_name: 'player')\n\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      fill_in 'player[number]', with: '42'\n      fill_in 'player[position]', with: 'Second baseman'\n      find_button('Save and add another').trigger('click')\n    end\n\n    it 'creates an object with correct attributes' do\n      is_expected.to have_text 'Player successfully created'\n      expect(page.current_path).to eq('/admin/player/new')\n\n      @player = RailsAdmin::AbstractModel.new('Player').first\n      expect(@player.name).to eq('Jackie Robinson')\n      expect(@player.number).to eq(42)\n      expect(@player.position).to eq('Second baseman')\n    end\n  end\n\n  context 'with uniqueness constraint violated', given: 'a player exists' do\n    before do\n      @team = FactoryBot.create :team\n      @player = FactoryBot.create :player, team: @team\n\n      post new_path(model_name: 'player', player: {name: @player.name, number: @player.number.to_s, position: @player.position, team_id: @team.id})\n    end\n\n    it 'shows an error message' do\n      expect(response.body).to include('There is already a player with that number on this team')\n    end\n  end\n\n  context 'with invalid object' do\n    before do\n      post new_path(model_name: 'player', player: {id: 1})\n    end\n\n    it 'shows an error message' do\n      expect(response.body).to include('Player failed to be created')\n    end\n  end\n\n  context 'with object with errors on base' do\n    before do\n      visit new_path(model_name: 'player')\n      fill_in 'player[name]', with: 'Jackie Robinson on steroids'\n      click_button 'Save and add another'\n    end\n\n    it 'shows error base error message in flash' do\n      is_expected.to have_content('Player failed to be created')\n      is_expected.to have_content('Player is cheating')\n    end\n  end\n\n  context 'with a readonly object' do\n    it 'shows non-editable form' do\n      RailsAdmin.config do |config|\n        config.model ReadOnlyComment do\n          edit do\n            field :content\n          end\n        end\n      end\n      visit new_path(model_name: 'read_only_comment')\n      is_expected.not_to have_css('textarea[name=\"read_only_comment[content]\"]')\n      is_expected.to have_css('button[name=\"_save\"]:disabled')\n    end\n  end\n\n  context 'with composite primary keys', composite_primary_keys: true do\n    let!(:fan) { FactoryBot.create(:fan) }\n    let!(:team) { FactoryBot.create(:team) }\n\n    it 'creates an object' do\n      visit new_path(model_name: 'fanship')\n      select(fan.name, from: 'Fan')\n      select(team.name, from: 'Team')\n      expect { click_button 'Save' }.to change { Fanship.count }.by(1)\n      expect(Fanship.first.attributes.fetch_values('fan_id', 'team_id')).to eq [fan.id, team.id]\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/show_in_app_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'ShowInApp action', type: :request do\n  subject { page }\n\n  describe 'link' do\n    let!(:player) { FactoryBot.create :player }\n\n    it 'has the data-turbo: false attribute' do\n      visit index_path(model_name: 'player')\n      is_expected.to have_selector(%(li[title=\"Show in app\"] a[data-turbo=\"false\"]))\n      click_link 'Show'\n      is_expected.to have_selector(%(a[data-turbo=\"false\"]), text: 'Show in app')\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/actions/show_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Show action', type: :request do\n  subject { page }\n  let(:team) { FactoryBot.create :team }\n\n  describe 'page' do\n    it 'has History, Edit, Delete, Details and attributes' do\n      @player = FactoryBot.create :player\n      visit show_path(model_name: 'player', id: @player.id)\n\n      is_expected.to have_selector('a', text: 'History')\n      is_expected.to have_selector('a', text: 'Edit')\n      is_expected.to have_selector('a', text: 'Delete')\n      is_expected.to have_content('Details')\n      is_expected.to have_content('Name')\n      is_expected.to have_content(@player.name)\n      is_expected.to have_content('Number')\n      is_expected.to have_content(@player.number)\n    end\n  end\n\n  context 'with invalid id' do\n    it 'raises NotFound' do\n      visit '/admin/players/123this-id-doesnt-exist'\n      expect(page.driver.status_code).to eq(404)\n    end\n  end\n\n  describe 'JSON show view' do\n    before do\n      @player = FactoryBot.create :player\n      visit uri\n    end\n\n    let(:uri) { show_path(model_name: 'player', id: @player.id, format: :json) }\n    let(:body) { page.body }\n\n    it 'creates a JSON uri' do\n      expect(uri).to eq(\"/admin/player/#{@player.id}.json\")\n    end\n\n    it 'contains the JSONified object' do\n      expect(JSON.parse(body)).to eq JSON.parse @player.reload.to_json\n    end\n  end\n\n  context 'when compact_show_view is enabled' do\n    it 'hides nil fields in show view by default' do\n      visit show_path(model_name: 'team', id: team.id)\n      is_expected.not_to have_css('.logo_url_field')\n    end\n\n    it 'hides blank fields in show view by default' do\n      team.update logo_url: ''\n      visit show_path(model_name: 'team', id: team.id)\n      is_expected.not_to have_css('.logo_url_field')\n    end\n\n    it 'is disactivable' do\n      RailsAdmin.config do |c|\n        c.compact_show_view = false\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n      is_expected.to have_css('.logo_url_field')\n    end\n\n    describe 'with boolean field' do\n      let(:player) { FactoryBot.create :player, retired: false }\n\n      it 'does not hide false value' do\n        visit show_path(model_name: 'player', id: player.id)\n        is_expected.to have_css('.retired_field')\n      end\n    end\n  end\n\n  context 'when compact_show_view is disabled' do\n    before do\n      RailsAdmin.config do |c|\n        c.compact_show_view = false\n      end\n    end\n\n    it 'shows nil fields' do\n      team.update logo_url: nil\n      visit show_path(model_name: 'team', id: team.id)\n      is_expected.to have_css('.logo_url_field')\n    end\n\n    it 'shows blank fields' do\n      team.update logo_url: ''\n      visit show_path(model_name: 'team', id: team.id)\n      is_expected.to have_css('.logo_url_field')\n    end\n  end\n\n  describe 'bindings' do\n    it 'should be present' do\n      RailsAdmin.config Team do |_c|\n        show do\n          field :name do\n            show do\n              bindings[:object] && bindings[:view] && bindings[:controller]\n            end\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('div .name_field.string_type')\n    end\n  end\n\n  describe 'css hooks' do\n    it 'is present' do\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('div .name_field.string_type')\n    end\n  end\n\n  describe 'field grouping' do\n    before do\n      RailsAdmin.config do |c|\n        c.compact_show_view = false\n      end\n    end\n\n    it 'is hideable' do\n      RailsAdmin.config Team do\n        show do\n          group :default do\n            hide\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.not_to have_selector('h4', text: 'Basic info')\n\n      %w[\n        division name logo_url manager\n        ballpark mascot founded wins\n        losses win_percentage revenue\n      ].each do |field|\n        is_expected.not_to have_selector(\".#{field}_field\")\n      end\n    end\n\n    it 'hides association groupings by the name of the association' do\n      RailsAdmin.config Team do\n        show do\n          group :players do\n            hide\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.not_to have_selector('h4', text: 'Players')\n    end\n\n    it 'is renameable' do\n      RailsAdmin.config Team do\n        show do\n          group :default do\n            label 'Renamed group'\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('h4', text: 'Renamed group')\n    end\n\n    it 'has accessor for its fields' do\n      RailsAdmin.config Team do\n        show do\n          group :default do\n            field :name\n            field :logo_url\n          end\n          group :belongs_to_associations do\n            label \"Belong's to associations\"\n            field :division\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('h4', text: 'Basic info')\n      is_expected.to have_selector('h4', text: \"Belong's to associations\")\n\n      is_expected.to have_selector('.name_field')\n      is_expected.to have_selector('.logo_url_field')\n      is_expected.to have_selector('.division_field')\n    end\n\n    it 'has accessor for its fields by type' do\n      RailsAdmin.config Team do\n        show do\n          group :default do\n            field :name\n            field :logo_url\n          end\n          group :other do\n            field :division\n            field :manager\n            field :ballpark\n            fields_of_type :string do\n              label { \"#{label} (STRING)\" }\n            end\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('.card-header', text: 'Name')\n      is_expected.to have_selector('.card-header', text: 'Logo url')\n      is_expected.to have_selector('.card-header', text: 'Division')\n      is_expected.to have_selector('.card-header', text: 'Manager (STRING)')\n      is_expected.to have_selector('.card-header', text: 'Ballpark (STRING)')\n    end\n  end\n\n  describe 'fields' do\n    before do\n      RailsAdmin.config do |c|\n        c.compact_show_view = false\n      end\n    end\n\n    it 'shows all by default' do\n      visit show_path(model_name: 'team', id: team.id)\n\n      %w[\n        division name logo_url manager\n        ballpark mascot founded wins\n        losses win_percentage revenue players fans\n      ].each do |field|\n        is_expected.to have_selector(\".#{field}_field\")\n      end\n    end\n\n    it 'only shows the defined fields and appear in order defined' do\n      RailsAdmin.config Team do\n        show do\n          field :manager\n          field :division\n          field :name\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('.manager_field')\n      is_expected.to have_selector('.division_field')\n      is_expected.to have_selector('.name_field')\n    end\n\n    it 'delegates the label option to the ActiveModel API' do\n      RailsAdmin.config Team do\n        show do\n          field :manager\n          field :fans\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('.card-header', text: 'Team Manager')\n      is_expected.to have_selector('.card-header', text: 'Some Fans')\n    end\n\n    it 'is renameable' do\n      RailsAdmin.config Team do\n        show do\n          field :manager do\n            label 'Renamed field'\n          end\n          field :division\n          field :name\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('.card-header', text: 'Renamed field')\n      is_expected.to have_selector('.card-header', text: 'Division')\n      is_expected.to have_selector('.card-header', text: 'Name')\n    end\n\n    it 'is renameable by type' do\n      RailsAdmin.config Team do\n        show do\n          fields_of_type :string do\n            label { \"#{label} (STRING)\" }\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      [\n        'Division', 'Name (STRING)', 'Logo url (STRING)', 'Manager (STRING)',\n        'Ballpark (STRING)', 'Mascot (STRING)', 'Founded', 'Wins', 'Losses',\n        'Win percentage', 'Revenue', 'Players', 'Fans'\n      ].each do |text|\n        is_expected.to have_selector('.card-header', text: text)\n      end\n    end\n\n    it 'is globally renameable by type' do\n      RailsAdmin.config Team do\n        show do\n          fields_of_type :string do\n            label { \"#{label} (STRING)\" }\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      [\n        'Division', 'Name (STRING)', 'Logo url (STRING)', 'Manager (STRING)',\n        'Ballpark (STRING)', 'Mascot (STRING)', 'Founded', 'Wins', 'Losses',\n        'Win percentage', 'Revenue', 'Players', 'Fans'\n      ].each do |text|\n        is_expected.to have_selector('.card-header', text: text)\n      end\n    end\n\n    it 'is hideable' do\n      RailsAdmin.config Team do\n        show do\n          field :manager do\n            hide\n          end\n          field :division\n          field :name\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('.division_field')\n      is_expected.to have_selector('.name_field')\n    end\n\n    it 'is hideable by type' do\n      RailsAdmin.config Team do\n        show do\n          fields_of_type :string do\n            hide\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      ['Name', 'Logo url', 'Manager', 'Ballpark', 'Mascot'].each do |text|\n        is_expected.not_to have_selector('.card-header', text: text)\n      end\n\n      ['Division', 'Founded', 'Wins', 'Losses', 'Win percentage', 'Revenue', 'Players', 'Fans'].each do |text|\n        is_expected.to have_selector('.card-header', text: text)\n      end\n    end\n\n    it 'is globally hideable by type' do\n      RailsAdmin.config Team do\n        show do\n          fields_of_type :string do\n            hide\n          end\n        end\n      end\n\n      visit show_path(model_name: 'team', id: team.id)\n\n      ['Name', 'Logo url', 'Manager', 'Ballpark', 'Mascot'].each do |text|\n        is_expected.not_to have_selector('.card-header', text: text)\n      end\n\n      ['Division', 'Founded', 'Wins', 'Losses', 'Win percentage', 'Revenue', 'Players', 'Fans'].each do |text|\n        is_expected.to have_selector('.card-header', text: text)\n      end\n    end\n  end\n\n  describe 'virtual field' do\n    let(:team) { FactoryBot.create :team, name: 'foobar' }\n    context 'with formatted_value defined' do\n      before do\n        RailsAdmin.config Team do\n          show do\n            field :truncated_name do\n              formatted_value do\n                bindings[:object].name.truncate(5)\n              end\n            end\n          end\n        end\n      end\n\n      it 'shows up correctly' do\n        visit show_path(model_name: 'team', id: team.id)\n\n        is_expected.to have_selector('.truncated_name_field')\n        is_expected.to have_selector('.card', text: 'fo...')\n      end\n    end\n\n    context 'without formatted_value' do\n      before do\n        RailsAdmin.config Team do\n          show do\n            field :truncated_name do\n              pretty_value do\n                bindings[:object].name.truncate(5)\n              end\n            end\n          end\n        end\n      end\n\n      it 'raises error along with suggestion' do\n        expect { visit show_path(model_name: 'team', id: team.id) }.to raise_error(/you should declare 'formatted_value'/)\n      end\n    end\n  end\n\n  describe 'with model scope' do\n    let!(:comments) { %w[something anything].map { |content| FactoryBot.create :comment_confirmed, content: content } }\n    before do\n      RailsAdmin.config do |config|\n        config.model Comment::Confirmed do\n          scope { Comment::Confirmed.unscoped }\n        end\n      end\n    end\n\n    it 'overrides default_scope' do\n      visit show_path(model_name: 'comment~confirmed', id: comments[0].id)\n      is_expected.to have_selector('.card-body', text: 'something')\n      visit show_path(model_name: 'comment~confirmed', id: comments[1].id)\n      is_expected.to have_selector('.card-body', text: 'anything')\n    end\n  end\n\n  context 'with composite primary keys', composite_primary_keys: true do\n    let(:fanship) { FactoryBot.create(:fanship) }\n\n    it 'shows the object' do\n      visit show_path(model_name: 'fanship', id: fanship.id)\n      is_expected.to have_link(fanship.fan.name)\n      is_expected.to have_link(fanship.team.name)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/auditing/paper_trail_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin PaperTrail auditing', active_record: true do\n  before(:each) do\n    RailsAdmin.config do |config|\n      config.audit_with :paper_trail\n    end\n  end\n\n  shared_examples :paper_on_object_creation do\n    describe 'on object creation', type: :request do\n      subject { page }\n      before do\n        @user = FactoryBot.create :user\n        RailsAdmin::Config.authenticate_with { warden.authenticate! scope: :user }\n        RailsAdmin::Config.current_user_method(&:current_user)\n        login_as @user\n        with_versioning do\n          visit new_path(model_name: paper_model_name)\n          fill_in paper_field_name, with: 'Jackie Robinson'\n          click_button 'Save'\n          @object = RailsAdmin::AbstractModel.new(paper_class_name).first\n        end\n      end\n\n      it 'records a version' do\n        expect(@object.versions.size).to eq 1\n        expect(@object.versions.first.whodunnit).to eq @user.id.to_s\n      end\n    end\n  end\n\n  shared_examples :paper_history do\n    describe 'model history fetch' do\n      before(:each) do\n        PaperTrail::Version.delete_all\n        @model = RailsAdmin::AbstractModel.new(paper_class_name)\n        @user = FactoryBot.create :user\n        @paper_trail_test = FactoryBot.create(paper_factory)\n        with_versioning do\n          # `PaperTrail.whodunnit` deprecated in PT 9, will be removed in 10.\n          # Use `PaperTrail.request.whodunnit` instead.\n          if PaperTrail.respond_to?(:request)\n            PaperTrail.request.whodunnit = @user.id\n          else\n            PaperTrail.whodunnit = @user.id\n          end\n          30.times do |i|\n            @paper_trail_test.update!(name: \"updated name #{i}\")\n          end\n        end\n      end\n\n      it 'creates versions' do\n        expect(paper_class_name.constantize.version_class_name.constantize.count).to eq(30)\n      end\n\n      describe 'model history fetch with auditing adapter' do\n        before(:all) do\n          @adapter = RailsAdmin::Extensions::PaperTrail::AuditingAdapter.new(nil)\n        end\n\n        it 'fetches on page of history' do\n          versions = @adapter.listing_for_model @model, nil, false, false, false, nil, 20\n          expect(versions.total_count).to eq(30)\n          expect(versions.count).to eq(20)\n        end\n\n        it 'respects RailsAdmin::Config.default_items_per_page' do\n          RailsAdmin.config.default_items_per_page = 15\n          versions = @adapter.listing_for_model @model, nil, false, false, false, nil\n          expect(versions.total_count).to eq(30)\n          expect(versions.count).to eq(15)\n        end\n\n        it 'sets correct next page' do\n          versions = @adapter.listing_for_model @model, nil, false, false, false, 2, 10\n          expect(versions.next_page).to eq(3)\n        end\n\n        it 'can fetch all history' do\n          versions = @adapter.listing_for_model @model, nil, false, false, true, nil, 20\n          expect(versions.total_count).to eq(30)\n          expect(versions.count).to eq(30)\n        end\n\n        describe 'returned version objects' do\n          before(:each) do\n            @padinated_listing = @adapter.listing_for_model @model, nil, false, false, false, nil\n            @version = @padinated_listing.first\n          end\n\n          it '#username returns user email' do\n            expect(@version.username).to eq(@user.email)\n          end\n\n          it '#message returns event' do\n            expect(@version.message).to eq('update')\n          end\n\n          describe 'changed item attributes' do\n            it '#item returns item.id' do\n              expect(@version.item).to eq(@paper_trail_test.id)\n            end\n\n            it '#table returns item class name' do\n              expect(@version.table.to_s).to eq(@model.model.base_class.name)\n            end\n          end\n\n          context 'with Kaminari' do\n            before do\n              Kaminari.config.page_method_name = :per_page_kaminari\n            end\n\n            after do\n              Kaminari.config.page_method_name = :page\n            end\n\n            let(:paginated_array) { Kaminari::PaginatableArray.new.page('1') }\n\n            it \"supports pagination when Kaminari's page_method_name is customized\" do\n              expect(PaperTrail::Version).to receive(:per_page_kaminari).twice.and_return(@padinated_listing)\n              allow(Kaminari).to receive(:paginate_array).and_return(paginated_array)\n              expect(paginated_array).to receive(:per_page_kaminari).twice.and_return(paginated_array)\n              @adapter.listing_for_model @model, nil, false, false, false, nil\n              @adapter.listing_for_object @model, @paper_trail_test, nil, false, false, false, nil\n            end\n\n            it \"does not break when Kaminari's page_method_name is not applied to Kaminari::PaginatableArray\" do\n              expect(PaperTrail::Version).to receive(:per_page_kaminari).twice.and_return(@padinated_listing)\n              allow(Kaminari).to receive(:paginate_array).and_return(paginated_array)\n              allow(paginated_array).to receive(:respond_to).with(:per_page_kaminari).and_return(false)\n              expect(paginated_array).to receive(:page).twice.and_return(paginated_array)\n              @adapter.listing_for_model @model, nil, false, false, false, nil\n              @adapter.listing_for_object @model, @paper_trail_test, nil, false, false, false, nil\n            end\n          end\n        end\n      end\n    end\n  end\n\n  context 'with a normal PaperTrail model' do\n    let(:paper_class_name) { 'PaperTrailTest' }\n    let(:paper_factory) { :paper_trail_test }\n\n    it_behaves_like :paper_on_object_creation do\n      let(:paper_model_name) { 'paper_trail_test' }\n      let(:paper_field_name) { 'paper_trail_test[name]' }\n    end\n\n    it_behaves_like :paper_history\n  end\n\n  context 'with a subclassed PaperTrail model' do\n    let(:paper_class_name) { 'PaperTrailTestSubclass' }\n    let(:paper_factory) { :paper_trail_test_subclass }\n\n    it_behaves_like :paper_on_object_creation do\n      let(:paper_model_name) { 'paper_trail_test_subclass' }\n      let(:paper_field_name) { 'paper_trail_test_subclass[name]' }\n    end\n\n    it_behaves_like :paper_history\n  end\n\n  context 'with a namespaced PaperTrail model' do\n    let(:paper_class_name) { 'PaperTrailTest::SubclassInNamespace' }\n    let(:paper_factory) { :paper_trail_test_subclass_in_namespace }\n\n    it_behaves_like :paper_on_object_creation do\n      let(:paper_model_name) { 'paper_trail_test~subclass_in_namespace' }\n      let(:paper_field_name) { 'paper_trail_test_subclass_in_namespace[name]' }\n    end\n\n    it_behaves_like :paper_history\n  end\n\n  context 'with a PaperTrail model with custom version association name' do\n    let(:paper_class_name) { 'PaperTrailTestWithCustomAssociation' }\n    let(:paper_factory) { :paper_trail_test_with_custom_association }\n\n    it_behaves_like :paper_history\n  end\nend\n"
  },
  {
    "path": "spec/integration/authentication/devise_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin Devise Authentication', type: :request do\n  subject { page }\n  let!(:user) { FactoryBot.create :user }\n\n  before do\n    RailsAdmin.config do |config|\n      config.authenticate_with do\n        warden.authenticate! scope: :user\n      end\n      config.current_user_method(&:current_user)\n    end\n  end\n\n  it 'supports logging-in', js: true do\n    visit dashboard_path\n    fill_in 'Email', with: user.email\n    fill_in 'Password', with: 'password'\n    click_button 'Log in'\n    is_expected.to have_css 'body.rails_admin'\n  end\n\n  it 'supports logging-out', js: true do\n    login_as user\n    visit dashboard_path\n    click_link 'Log out'\n    is_expected.to have_content 'Log in'\n  end\nend\n"
  },
  {
    "path": "spec/integration/authorization/cancancan_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin CanCanCan Authorization', type: :request do\n  class Ability\n    include CanCan::Ability\n    def initialize(user)\n      can :access, :rails_admin if user.roles.include? :admin\n      can :read, :dashboard\n      if user.roles.include? :test_exception\n        can :access, :rails_admin\n        can :manage, :all\n        can :show_in_app, :all\n\n        can %i[update destroy], Player\n        cannot %i[update destroy], Player, retired: true\n      else\n        can :manage, Player if user.roles.include? :manage_player\n        can :read, Player, retired: false if user.roles.include? :read_player\n        can :create, Player, suspended: true if user.roles.include? :create_player\n        can :update, Player, retired: false if user.roles.include? :update_player\n        can :destroy, Player, retired: false if user.roles.include? :destroy_player\n        can :history, Player, retired: false if user.roles.include? :history_player\n        can :show_in_app, Player, retired: false if user.roles.include? :show_in_app_player\n      end\n    end\n  end\n\n  class AdminAbility\n    include CanCan::Ability\n    def initialize(user)\n      can :access, :rails_admin if user.roles.include? :admin\n      can :show_in_app, :all\n      can :manage, :all\n    end\n  end\n\n  subject { page }\n\n  before do\n    RailsAdmin.config do |c|\n      c.authorize_with(:cancancan)\n      c.authenticate_with { warden.authenticate! scope: :user }\n      c.current_user_method(&:current_user)\n    end\n    @player_model = RailsAdmin::AbstractModel.new(Player)\n    @user = FactoryBot.create :user\n    login_as @user\n  end\n\n  describe 'with no roles' do\n    before do\n      @user.update(roles: [])\n    end\n\n    it 'GET /admin should raise CanCan::AccessDenied' do\n      expect { visit dashboard_path }.to raise_error(CanCan::AccessDenied)\n    end\n\n    it 'GET /admin/player should raise CanCan::AccessDenied' do\n      expect { visit index_path(model_name: 'player') }.to raise_error(CanCan::AccessDenied)\n    end\n  end\n\n  describe 'with read player role' do\n    before do\n      @user.update(roles: %i[admin read_player])\n    end\n\n    it 'GET /admin should show Player but not League' do\n      visit dashboard_path\n      is_expected.to have_content('Player')\n      is_expected.not_to have_content('League')\n      is_expected.not_to have_content('Add new')\n    end\n\n    it 'GET /admin/player should render successfully but not list retired players and not show new, edit, or delete actions' do\n      # ensure :name column to be shown\n      RailsAdmin.config Player do\n        list do\n          field :name\n        end\n      end\n      @players = [\n        FactoryBot.create(:player, retired: false),\n        FactoryBot.create(:player, retired: true),\n      ]\n\n      visit index_path(model_name: 'player')\n\n      is_expected.to have_content(@players[0].name)\n      is_expected.not_to have_content(@players[1].name)\n      is_expected.not_to have_content('Add new')\n      is_expected.to have_css('.show_member_link')\n      is_expected.not_to have_css('.edit_member_link')\n      is_expected.not_to have_css('.delete_member_link')\n      is_expected.not_to have_css('.history_show_member_link')\n      is_expected.not_to have_css('.show_in_app_member_link')\n    end\n\n    it 'GET /admin/team should raise CanCan::AccessDenied' do\n      expect { visit index_path(model_name: 'team') }.to raise_error(CanCan::AccessDenied)\n    end\n\n    it 'GET /admin/player/new should raise CanCan::AccessDenied' do\n      expect { visit new_path(model_name: 'player') }.to raise_error(CanCan::AccessDenied)\n    end\n  end\n\n  describe 'with create and read player role' do\n    before do\n      @user.update(roles: %i[admin read_player create_player])\n    end\n\n    it 'GET /admin/player/new should render and create record upon submission' do\n      visit new_path(model_name: 'player')\n\n      is_expected.not_to have_content('Save and edit')\n      is_expected.not_to have_content('Delete')\n\n      is_expected.to have_content('Save and add another')\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      fill_in 'player[number]', with: '42'\n      fill_in 'player[position]', with: 'Second baseman'\n      click_button 'Save' # first(:button, \"Save\").click\n      is_expected.not_to have_content('Edit')\n\n      @player = RailsAdmin::AbstractModel.new('Player').first\n      expect(@player.name).to eq('Jackie Robinson')\n      expect(@player.number).to eq(42)\n      expect(@player.position).to eq('Second baseman')\n      expect(@player).to be_suspended # suspended is inherited behavior based on permission\n    end\n\n    it 'POST /admin/player/new with unauthorized attribute value should raise access denied' do\n      visit new_path(model_name: 'player')\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      choose name: 'player[suspended]', option: '0'\n      expect { click_button 'Save' }.to raise_error(CanCan::AccessDenied)\n    end\n\n    it 'GET /admin/player/1/edit should raise access denied' do\n      @player = FactoryBot.create :player\n      expect { visit edit_path(model_name: 'player', id: @player.id) }.to raise_error(CanCan::AccessDenied)\n    end\n  end\n\n  describe 'with update and read player role' do\n    before do\n      @user.update(roles: %i[admin read_player update_player])\n    end\n\n    it 'GET /admin/player/1/edit should render and update record upon submission' do\n      @player = FactoryBot.create :player\n      visit edit_path(model_name: 'player', id: @player.id)\n      is_expected.to have_content('Save and edit')\n      is_expected.not_to have_content('Save and add another')\n      is_expected.not_to have_content('Add new')\n      is_expected.not_to have_content('Delete')\n      is_expected.not_to have_content('History')\n      is_expected.not_to have_content('Show in app')\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      click_button 'Save' # click_button \"Save\" # first(:button, \"Save\").click\n      @player.reload\n      expect(@player.name).to eq('Jackie Robinson')\n    end\n\n    it 'GET /admin/player/1/edit with retired player should raise access denied' do\n      @player = FactoryBot.create :player, retired: true\n      expect { visit edit_path(model_name: 'player', id: @player.id) }.to raise_error(CanCan::AccessDenied)\n    end\n\n    it 'PUT /admin/player/new with unauthorized attribute value should raise access denied' do\n      @player = FactoryBot.create :player\n      visit edit_path(model_name: 'player', id: @player.id)\n      choose name: 'player[retired]', option: '1'\n      expect { click_button 'Save' }.to raise_error(CanCan::AccessDenied)\n    end\n\n    it 'GET /admin/player/1/delete should raise access denied' do\n      @player = FactoryBot.create :player\n      expect { visit delete_path(model_name: 'player', id: @player.id) }.to raise_error(CanCan::AccessDenied)\n    end\n  end\n\n  describe 'with history role' do\n    it 'shows links to history action' do\n      @user.update(roles: %i[admin read_player history_player])\n      @player = FactoryBot.create :player\n\n      visit index_path(model_name: 'player')\n      is_expected.to have_css('.show_member_link')\n      is_expected.not_to have_css('.edit_member_link')\n      is_expected.not_to have_css('.delete_member_link')\n      is_expected.to have_css('.history_show_member_link')\n\n      visit show_path(model_name: 'player', id: @player.id)\n      is_expected.to have_content('Show')\n      is_expected.not_to have_content('Edit')\n      is_expected.not_to have_content('Delete')\n      is_expected.to have_content('History')\n    end\n  end\n\n  describe 'with show in app role' do\n    it 'shows links to show in app action' do\n      @user.update(roles: %i[admin read_player show_in_app_player])\n      @player = FactoryBot.create :player\n\n      visit index_path(model_name: 'player')\n      is_expected.to have_css('.show_member_link')\n      is_expected.not_to have_css('.edit_member_link')\n      is_expected.not_to have_css('.delete_member_link')\n      is_expected.not_to have_css('.history_show_member_link')\n      is_expected.to have_css('.show_in_app_member_link')\n\n      visit show_path(model_name: 'player', id: @player.id)\n      is_expected.to have_content('Show')\n      is_expected.not_to have_content('Edit')\n      is_expected.not_to have_content('Delete')\n      is_expected.not_to have_content('History')\n      is_expected.to have_content('Show in app')\n    end\n  end\n\n  describe 'with all roles' do\n    it 'shows links to all actions' do\n      @user.update(roles: %i[admin manage_player])\n      @player = FactoryBot.create :player\n\n      visit index_path(model_name: 'player')\n      is_expected.to have_css('.show_member_link')\n      is_expected.to have_css('.edit_member_link')\n      is_expected.to have_css('.delete_member_link')\n      is_expected.to have_css('.history_show_member_link')\n      is_expected.to have_css('.show_in_app_member_link')\n\n      visit show_path(model_name: 'player', id: @player.id)\n      is_expected.to have_content('Show')\n      is_expected.to have_content('Edit')\n      is_expected.to have_content('Delete')\n      is_expected.to have_content('History')\n      is_expected.to have_content('Show in app')\n    end\n  end\n\n  describe 'with destroy and read player role' do\n    before do\n      @user.update(roles: %i[admin read_player destroy_player])\n    end\n\n    it 'GET /admin/player/1/delete should render and destroy record upon submission' do\n      @player = FactoryBot.create :player\n      player_id = @player.id\n      visit delete_path(model_name: 'player', id: player_id)\n\n      click_button \"Yes, I'm sure\"\n\n      expect(@player_model.get(player_id)).to be_nil\n    end\n\n    it 'GET /admin/player/1/delete with retired player should raise access denied' do\n      @player = FactoryBot.create :player, retired: true\n      expect { visit delete_path(model_name: 'player', id: @player.id) }.to raise_error(CanCan::AccessDenied)\n    end\n\n    it 'GET /admin/player/bulk_delete should render records which are authorized to' do\n      active_player = FactoryBot.create :player, retired: false\n      retired_player = FactoryBot.create :player, retired: true\n\n      post bulk_action_path(bulk_action: 'bulk_delete', model_name: 'player', bulk_ids: [active_player, retired_player].collect(&:id))\n\n      expect(response.body).to include(active_player.name)\n      expect(response.body).not_to include(retired_player.name)\n    end\n\n    it 'POST /admin/player/bulk_destroy should destroy records which are authorized to' do\n      active_player = FactoryBot.create :player, retired: false\n      retired_player = FactoryBot.create :player, retired: true\n\n      delete bulk_delete_path(model_name: 'player', bulk_ids: [active_player, retired_player].collect(&:id))\n      expect(@player_model.get(active_player.id)).to be_nil\n      expect(@player_model.get(retired_player.id)).not_to be_nil\n    end\n  end\n\n  describe 'with exception role' do\n    it 'GET /admin/player/bulk_delete should render records which are authorized to' do\n      @user.update(roles: %i[admin test_exception])\n      active_player = FactoryBot.create :player, retired: false\n      retired_player = FactoryBot.create :player, retired: true\n\n      post bulk_action_path(bulk_action: 'bulk_delete', model_name: 'player', bulk_ids: [active_player, retired_player].collect(&:id))\n\n      expect(response.body).to include(active_player.name)\n      expect(response.body).not_to include(retired_player.name)\n    end\n\n    it 'POST /admin/player/bulk_destroy should destroy records which are authorized to' do\n      @user.update(roles: %i[admin test_exception])\n      active_player = FactoryBot.create :player, retired: false\n      retired_player = FactoryBot.create :player, retired: true\n\n      delete bulk_delete_path(model_name: 'player', bulk_ids: [active_player, retired_player].collect(&:id))\n      expect(@player_model.get(active_player.id)).to be_nil\n      expect(@player_model.get(retired_player.id)).not_to be_nil\n    end\n  end\n\n  describe 'with a custom admin ability' do\n    before do\n      RailsAdmin.config do |c|\n        c.authorize_with :cancancan do\n          ability_class { AdminAbility }\n        end\n      end\n      @user = FactoryBot.create :user\n      login_as @user\n    end\n\n    describe 'with admin role only' do\n      before do\n        @user.update(roles: [:admin])\n      end\n\n      it 'GET /admin/team should render successfully' do\n        visit index_path(model_name: 'team')\n        expect(page.status_code).to eq(200)\n      end\n\n      it 'GET /admin/player/new should render successfully' do\n        visit new_path(model_name: 'player')\n        expect(page.status_code).to eq(200)\n      end\n\n      it 'GET /admin/player/1/edit should render successfully' do\n        @player = FactoryBot.create :player\n        visit edit_path(model_name: 'player', id: @player.id)\n        expect(page.status_code).to eq(200)\n      end\n\n      it 'GET /admin/player/1/edit with retired player should render successfully' do\n        @player = FactoryBot.create :player, retired: true\n        visit edit_path(model_name: 'player', id: @player.id)\n        expect(page.status_code).to eq(200)\n      end\n\n      it 'GET /admin/player/1/delete should render successfully' do\n        @player = FactoryBot.create :player\n        visit delete_path(model_name: 'player', id: @player.id)\n        expect(page.status_code).to eq(200)\n      end\n\n      it 'GET /admin/player/1/delete with retired player should render successfully' do\n        @player = FactoryBot.create :player, retired: true\n        visit delete_path(model_name: 'player', id: @player.id)\n        expect(page.status_code).to eq(200)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/authorization/pundit_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin Pundit Authorization', type: :request do\n  subject { page }\n\n  before do\n    RailsAdmin.config do |c|\n      c.authorize_with(:pundit)\n      c.authenticate_with { warden.authenticate! scope: :user }\n      c.current_user_method(&:current_user)\n    end\n    @player_model = RailsAdmin::AbstractModel.new(Player)\n    @user = FactoryBot.create :user, roles: []\n    login_as @user\n  end\n\n  describe 'with no roles' do\n    it 'GET /admin should raise Pundit::NotAuthorizedError' do\n      expect { visit dashboard_path }.to raise_error(Pundit::NotAuthorizedError)\n    end\n\n    it 'GET /admin/player should raise Pundit::NotAuthorizedError' do\n      expect { visit index_path(model_name: 'player') }.to raise_error(Pundit::NotAuthorizedError)\n    end\n  end\n\n  describe 'with read player role' do\n    before do\n      @user.update(roles: %i[admin read_player])\n    end\n\n    it 'GET /admin should show Player but not League' do\n      visit dashboard_path\n      is_expected.to have_content('Player')\n      is_expected.not_to have_content('League')\n      is_expected.not_to have_content('Add new')\n    end\n\n    it 'GET /admin/team should raise Pundit::NotAuthorizedError' do\n      expect { visit index_path(model_name: 'team') }.to raise_error(Pundit::NotAuthorizedError)\n    end\n\n    it 'GET /admin/player/1/edit should raise access denied' do\n      @player = FactoryBot.create :player\n      expect { visit edit_path(model_name: 'player', id: @player.id) }.to raise_error(Pundit::NotAuthorizedError)\n    end\n  end\n\n  describe 'with admin role' do\n    before do\n      @user.update(roles: %i[admin manage_player])\n    end\n\n    it 'GET /admin should show Player but not League' do\n      visit dashboard_path\n      is_expected.to have_content('Player')\n    end\n\n    it 'GET /admin/player/new should render and create record upon submission' do\n      visit new_path(model_name: 'player')\n\n      is_expected.to have_content('Save and edit')\n      is_expected.not_to have_content('Delete')\n\n      is_expected.to have_content('Save and add another')\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      fill_in 'player[number]', with: '42'\n      fill_in 'player[position]', with: 'Second baseman'\n      click_button 'Save'\n      is_expected.not_to have_content('Edit')\n\n      @player = RailsAdmin::AbstractModel.new('Player').first\n      expect(@player.name).to eq('Jackie Robinson')\n      expect(@player.number).to eq(42)\n      expect(@player.position).to eq('Second baseman')\n    end\n  end\n\n  describe 'with all roles' do\n    it 'shows links to all actions' do\n      @user.update(roles: %i[admin manage_player])\n      @player = FactoryBot.create :player\n\n      visit index_path(model_name: 'player')\n      is_expected.to have_css('.show_member_link')\n      is_expected.to have_css('.edit_member_link')\n      is_expected.to have_css('.delete_member_link')\n      is_expected.to have_css('.history_show_member_link')\n      is_expected.to have_css('.show_in_app_member_link')\n\n      visit show_path(model_name: 'player', id: @player.id)\n      is_expected.to have_content('Show')\n      is_expected.to have_content('Edit')\n      is_expected.to have_content('Delete')\n      is_expected.to have_content('History')\n      is_expected.to have_content('Show in app')\n    end\n  end\n\n  describe 'with create and read player role' do\n    before do\n      @user.update(roles: %i[admin read_player create_player])\n    end\n\n    it 'POST /admin/player/new with unauthorized attribute value should raise access denied' do\n      visit new_path(model_name: 'player')\n      fill_in 'player[name]', with: 'Jackie Robinson'\n      choose name: 'player[suspended]', option: '0'\n      expect { click_button 'Save' }.to raise_error(Pundit::NotAuthorizedError)\n    end\n  end\n\n  describe 'with update and read player role' do\n    before do\n      @user.update(roles: %i[admin read_player update_player])\n    end\n\n    it 'PUT /admin/player/new with unauthorized attribute value should raise access denied' do\n      @player = FactoryBot.create :player\n      visit edit_path(model_name: 'player', id: @player.id)\n      choose name: 'player[retired]', option: '1'\n      expect { click_button 'Save' }.to raise_error(Pundit::NotAuthorizedError)\n    end\n  end\n\n  context 'when ApplicationController already has pundit_user' do\n    let(:admin) { FactoryBot.create :user, roles: [:admin] }\n    before do\n      RailsAdmin.config.parent_controller = 'ApplicationController'\n      allow_any_instance_of(ApplicationController).to receive(:pundit_user).and_return(admin)\n    end\n\n    it 'uses original pundit_user' do\n      pending 'no way to dynamically change superclass'\n      expect { visit dashboard_path }.not_to raise_error\n    end\n  end\n\n  context 'when custom authorization key is set' do\n    before do\n      RailsAdmin.config do |c|\n        c.actions do\n          dashboard\n          index do\n            authorization_key :rails_admin_index\n          end\n        end\n      end\n    end\n\n    it 'uses the custom key' do\n      expect { visit index_path(model_name: 'team') }.not_to raise_error\n    end\n  end\n\n  context 'when custom authorization key is suffixed with ?' do\n    before do\n      @user.update(roles: [:admin])\n      RailsAdmin.config do |c|\n        c.actions do\n          dashboard do\n            authorization_key :dashboard?\n          end\n          index\n        end\n      end\n    end\n\n    it 'does not append ? on policy check' do\n      expect_any_instance_of(ApplicationPolicy).not_to receive(:'dashboard??')\n      visit dashboard_path\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/action_text_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nif defined?(ActionText)\n  RSpec.describe 'ActionText field', type: :request, js: true do\n    subject { page }\n\n    before do\n      RailsAdmin.config FieldTest do\n        edit do\n          field :action_text_field\n        end\n      end\n    end\n\n    it 'works without error' do\n      allow(ConsoleLogger).to receive(:warn).with(/ActionText assets should be loaded statically/)\n      expect { visit new_path(model_name: 'field_test') }.not_to raise_error\n      is_expected.to have_selector('trix-toolbar')\n    end\n\n    if RailsAdmin.config.asset_source == :sprockets && Rails.gem_version < Gem::Version.new('7.0')\n      it 'shows a warning if ActionText assets are loaded dynamically' do\n        expect(ConsoleLogger).to receive(:warn).with(/ActionText assets should be loaded statically/)\n        visit new_path(model_name: 'field_test')\n        is_expected.to have_selector('trix-toolbar')\n      end\n\n      it 'allows suppressing the warning' do\n        RailsAdmin.config FieldTest do\n          edit do\n            field :action_text_field do\n              warn_dynamic_load false\n            end\n          end\n        end\n        expect(ConsoleLogger).not_to receive(:warn).with(/ActionText assets should be loaded statically/)\n        visit new_path(model_name: 'field_test')\n        is_expected.to have_selector('trix-toolbar')\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/active_record_enum_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'ActiveRecordEnum field', type: :request, active_record: true do\n  subject { page }\n\n  describe 'for string-keyed enum' do\n    before do\n      RailsAdmin.config FieldTest do\n        edit do\n          field :string_enum_field do\n            default_value 'M'\n          end\n        end\n      end\n    end\n\n    it 'auto-detects enumeration' do\n      visit new_path(model_name: 'field_test')\n      is_expected.to have_selector('.enum_type select')\n      is_expected.not_to have_selector('.enum_type select[multiple]')\n      expect(all('.enum_type option').map(&:text).select(&:present?)).to eq %w[S M L]\n    end\n\n    it 'shows current value as selected' do\n      visit edit_path(model_name: 'field_test', id: FieldTest.create(string_enum_field: 'L'))\n      expect(find('.enum_type select').value).to eq 'l'\n    end\n\n    it 'can be updated' do\n      visit edit_path(model_name: 'field_test', id: FieldTest.create(string_enum_field: 'S'))\n      select 'L'\n      click_button 'Save'\n      expect(FieldTest.first.string_enum_field).to eq 'L'\n    end\n\n    it 'pre-populates default value' do\n      visit new_path(model_name: 'field_test')\n      expect(find('.enum_type select').value).to eq 'm'\n    end\n  end\n\n  describe 'for integer-keyed enum' do\n    before do\n      RailsAdmin.config FieldTest do\n        edit do\n          field :integer_enum_field do\n            default_value :medium\n          end\n        end\n      end\n    end\n\n    it 'auto-detects enumeration' do\n      visit new_path(model_name: 'field_test')\n      is_expected.to have_selector('.enum_type select')\n      is_expected.not_to have_selector('.enum_type select[multiple]')\n      expect(all('.enum_type option').map(&:text).select(&:present?)).to eq %w[small medium large]\n    end\n\n    it 'shows current value as selected' do\n      visit edit_path(model_name: 'field_test', id: FieldTest.create(integer_enum_field: :large))\n      expect(find('.enum_type select').value).to eq '2'\n    end\n\n    it 'can be updated' do\n      visit edit_path(model_name: 'field_test', id: FieldTest.create(integer_enum_field: :small))\n      select 'large'\n      click_button 'Save'\n      expect(FieldTest.first.integer_enum_field).to eq 'large'\n    end\n\n    it 'pre-populates default value' do\n      visit new_path(model_name: 'field_test')\n      expect(find('.enum_type select').value).to eq '1'\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/active_storage_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'ActiveStorage field', type: :request, active_record: true do\n  subject { page }\n  let(:field_test) { FactoryBot.create :field_test }\n  before do\n    # To suppress 'SQLite3::BusyException: database is locked' exception\n    @original = page.driver.browser.url_blacklist # rubocop:disable Naming/InclusiveLanguage\n    page.driver.browser.url_blacklist = [%r{/rails/active_storage/representations}] # rubocop:disable Naming/InclusiveLanguage\n  end\n  after { page.driver.browser.url_blacklist = @original } # rubocop:disable Naming/InclusiveLanguage\n\n  describe 'direct upload', js: true do\n    before do\n      RailsAdmin.config FieldTest do\n        edit do\n          field(:active_storage_asset) { direct true }\n        end\n      end\n    end\n\n    it 'works' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      attach_file 'Active storage asset', file_path('test.jpg')\n      expect_any_instance_of(ActiveStorage::DirectUploadsController).to receive(:create).and_call_original\n      click_button 'Save'\n      expect(page).to have_content 'Field test successfully updated'\n      field_test.reload\n      expect(field_test.active_storage_asset.filename).to eq 'test.jpg'\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/base_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Base field', type: :request do\n  subject { page }\n\n  describe '#default_value' do\n    it 'is set for all types of input fields' do\n      RailsAdmin.config do |config|\n        config.excluded_models = []\n        config.model(FieldTest) do\n          field :string_field do\n            default_value 'string_field default_value'\n          end\n          field :text_field do\n            default_value 'string_field text_field'\n          end\n          field :boolean_field do\n            default_value true\n          end\n          field :date_field do\n            default_value Date.today\n          end\n        end\n      end\n\n      visit new_path(model_name: 'field_test')\n      # In Rails 3.2.3 behavior of textarea has changed to insert newline after the opening tag,\n      # but Capybara's RackTest driver is not up to this behavior change.\n      # (https://github.com/jnicklas/capybara/issues/677)\n      # So we manually cut off first newline character as a workaround here.\n      expect(find_field('field_test[string_field]').value.gsub(/^\\n/, '')).to eq('string_field default_value')\n      expect(find_field('field_test[text_field]').value.gsub(/^\\n/, '')).to eq('string_field text_field')\n      expect(find('[name=\"field_test[date_field]\"]', visible: false).value).to eq(Date.today.to_s)\n      expect(has_checked_field?('field_test[boolean_field]')).to be_truthy\n    end\n\n    it 'sets default value for selects' do\n      RailsAdmin.config(Team) do\n        field :color, :enum do\n          default_value 'black'\n          enum do\n            %w[black white]\n          end\n        end\n      end\n      visit new_path(model_name: 'team')\n      expect(find_field('team[color]').value).to eq('black')\n    end\n\n    it 'renders custom value next time if error happend' do\n      RailsAdmin.config(Team) do\n        field :name do\n          render do\n            raise ZeroDivisionError unless bindings[:object].persisted?\n\n            'Custom Name'\n          end\n        end\n      end\n      expect { visit new_path(model_name: 'team') }.to raise_error(/ZeroDivisionError/)\n      record = FactoryBot.create(:team)\n      visit edit_path(model_name: 'team', id: record.id)\n      expect(page).to have_content('Custom Name')\n    end\n  end\n\n  describe '#bindings' do\n    it 'is available' do\n      RailsAdmin.config do |config|\n        config.excluded_models = []\n      end\n      RailsAdmin.config Category do\n        field :parent_category do\n          visible do\n            !bindings[:object].new_record?\n          end\n        end\n      end\n\n      visit new_path(model_name: 'category')\n      is_expected.to have_no_css('#category_parent_category_id')\n      click_button 'Save' # first(:button, \"Save\").click\n      visit edit_path(model_name: 'category', id: Category.first)\n      is_expected.to have_css('#category_parent_category_id')\n      click_button 'Save' # first(:button, \"Save\").click\n      is_expected.to have_content('Category successfully updated')\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/belongs_to_association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'BelongsToAssociation field', type: :request do\n  subject { page }\n\n  it 'does not add a related id to the belongs_to create team link' do\n    @player = FactoryBot.create :player\n    visit edit_path(model_name: 'player', id: @player.id)\n    is_expected.to have_selector(\"a[data-link='/admin/team/new?modal=true']\")\n  end\n\n  describe 'on create' do\n    let!(:draft) { FactoryBot.create :draft }\n    let(:team) { FactoryBot.create :team }\n\n    it 'shows selects' do\n      visit new_path(model_name: 'player')\n      is_expected.to have_selector('select#player_team_id')\n    end\n\n    context 'with default_value' do\n      before do\n        id = team.id\n        RailsAdmin.config Player do\n          configure :team do\n            default_value id\n          end\n        end\n      end\n\n      it 'shows the value as selected' do\n        visit new_path(model_name: 'player')\n        expect(find('select#player_team_id').value).to eq team.id.to_s\n      end\n    end\n  end\n\n  describe 'on show' do\n    before do\n      @team   = FactoryBot.create :team\n      @player = FactoryBot.create :player, team_id: @team.id\n      visit show_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'shows associated objects' do\n      is_expected.to have_css(\"a[href='/admin/team/#{@team.id}']\")\n    end\n  end\n\n  context 'with custom primary_key option' do\n    let(:users) { FactoryBot.create_list :managing_user, 2 }\n    let!(:teams) { [FactoryBot.create(:managed_team, manager: users[0].email), FactoryBot.create(:managed_team)] }\n    before do\n      RailsAdmin.config.included_models = [ManagedTeam, ManagingUser]\n      RailsAdmin.config ManagedTeam do\n        field :user\n      end\n    end\n\n    it 'allows update' do\n      visit edit_path(model_name: 'managed_team', id: teams[0].id)\n      expect(page).to have_css(\"select#managed_team_manager option[value=\\\"#{users[0].email}\\\"]\")\n      select(\"ManagingUser ##{users[1].id}\", from: 'User')\n      click_button 'Save'\n      teams[0].reload\n      expect(teams[0].user).to eq users[1]\n    end\n\n    context 'when fetching associated objects via xhr' do\n      before do\n        RailsAdmin.config ManagedTeam do\n          field(:user) { associated_collection_cache_all false }\n        end\n      end\n\n      it 'allows update', js: true do\n        visit edit_path(model_name: 'managed_team', id: teams[0].id)\n        find('input.ra-filtering-select-input').set('M')\n        page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n        expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n        page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"ManagingUser ##{users[1].id}\")).click()}\n        click_button 'Save'\n        teams[0].reload\n        expect(teams[0].user).to eq users[1]\n      end\n    end\n  end\n\n  context 'with composite foreign keys', composite_primary_keys: true do\n    let!(:fanship) { FactoryBot.create(:fanship) }\n    let(:favorite_player) { FactoryBot.create(:favorite_player) }\n\n    describe 'via default field' do\n      it 'allows update' do\n        visit edit_path(model_name: 'favorite_player', id: favorite_player.id)\n        is_expected.to have_select('Fanship', selected: \"Fanship ##{favorite_player.fanship.id}\")\n        select(\"Fanship ##{fanship.id}\", from: 'Fanship')\n        click_button 'Save'\n        is_expected.to have_content 'Favorite player successfully updated'\n        expect(FavoritePlayer.all.map(&:fanship)).to eq [fanship]\n      end\n\n      context 'with invalid key' do\n        before do\n          allow_any_instance_of(RailsAdmin::Config::Fields::Types::BelongsToAssociation).\n            to receive(:collection).and_return([[\"Fanship ##{fanship.id}\", 'invalid']])\n        end\n\n        it 'fails to update' do\n          visit edit_path(model_name: 'favorite_player', id: favorite_player.id)\n          select(\"Fanship ##{fanship.id}\", from: 'Fanship')\n          click_button 'Save'\n          is_expected.to have_content 'Fanship must exist'\n        end\n      end\n    end\n\n    describe 'via remote-sourced field' do\n      before do\n        RailsAdmin.config FavoritePlayer do\n          field :fanship do\n            associated_collection_cache_all false\n          end\n        end\n      end\n\n      it 'allows update', js: true do\n        visit edit_path(model_name: 'favorite_player', id: favorite_player.id)\n        find('.fanship_field input.ra-filtering-select-input').set(fanship.fan_id)\n        page.execute_script(\"document.querySelector('.fanship_field input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n        expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n        page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Fanship ##{fanship.id}\")).click()}\n        click_button 'Save'\n        is_expected.to have_content 'Favorite player successfully updated'\n        expect(FavoritePlayer.all.map(&:fanship)).to eq [fanship]\n      end\n    end\n\n    describe 'via nested field' do\n      it 'allows update' do\n        visit edit_path(model_name: 'nested_favorite_player', id: favorite_player.id)\n        fill_in 'Since', with: '2020-01-23'\n        click_button 'Save'\n        is_expected.to have_content 'Nested favorite player successfully updated'\n        expect(favorite_player.reload.fanship.since).to eq Date.new(2020, 1, 23)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/boolean_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Boolean field', type: :request do\n  subject { page }\n  let(:field_test) { FactoryBot.create :field_test }\n\n  context 'if nullable' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :boolean_field\n      end\n    end\n\n    it 'shows 3 radio buttons' do\n      visit new_path(model_name: 'field_test')\n      is_expected.to have_content 'New Field test'\n      expect(all('[name=\"field_test[boolean_field]\"]').map { |e| e['value'] }).to eq ['1', '0', '']\n    end\n\n    it 'can be updated' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n\n      # change the value to true and assert the values\n      find('.boolean_type label.success').click\n      click_button 'Save and edit'\n      # validate that the success button rendered and is active\n      expect(page).to have_selector('.boolean_type input[value=\"1\"][checked]')\n      # validate the value is true\n      expect(field_test.reload.boolean_field).to be true\n\n      # change the value to false and assert the values\n      find('.boolean_type label.danger').click\n      click_button 'Save and edit'\n      expect(page).to have_selector('.boolean_type input[value=\"0\"][checked]')\n      expect(field_test.reload.boolean_field).to be false\n\n      # change the value to nil and assert the values\n      find('.boolean_type label.default').click\n      click_button 'Save and edit'\n      expect(page).to have_selector('.boolean_type input[value=\"\"][checked]')\n      expect(field_test.reload.boolean_field).to be nil\n    end\n  end\n\n  context 'when the boolean is in an embedded document' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :comment\n      end\n\n      RailsAdmin.config Comment do\n        field :content, :boolean\n      end\n    end\n\n    it 'can be updated', js: true do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n\n      # toggle open the embedded document section\n      find('#field_test_comment_attributes_field .add_nested_fields').click\n      # set the value to false and assert the values\n      find('.boolean_type label.danger').click\n      click_button 'Save and edit'\n      expect(field_test.reload.comment.content).to eq '0'\n    end\n  end\n\n  context 'if not nullable' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :boolean_field do\n          nullable false\n        end\n      end\n    end\n\n    it 'shows a checkbox' do\n      visit new_path(model_name: 'field_test')\n      is_expected.to have_content 'New Field test'\n      is_expected.to have_css '[type=\"checkbox\"][name=\"field_test[boolean_field]\"]'\n    end\n\n    it 'can be updated' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      find('.boolean_type input').check\n      click_button 'Save and edit'\n      expect(field_test.reload.boolean_field).to be true\n      find('.boolean_type input').uncheck\n      click_button 'Save and edit'\n      expect(field_test.reload.boolean_field).to be false\n    end\n  end\n\n  context 'if the database column is not nullable', active_record: true do\n    before do\n      RailsAdmin.config FieldTest do\n        field :non_nullable_boolean_field\n      end\n    end\n\n    it 'shows a checkbox' do\n      visit new_path(model_name: 'field_test')\n      is_expected.to have_content 'New Field test'\n      is_expected.to have_css '[type=\"checkbox\"][name=\"field_test[non_nullable_boolean_field]\"]'\n    end\n\n    it 'can be updated' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      find('.boolean_type input').check\n      click_button 'Save and edit'\n      expect(field_test.reload.non_nullable_boolean_field).to be true\n      find('.boolean_type input').uncheck\n      click_button 'Save and edit'\n      expect(field_test.reload.non_nullable_boolean_field).to be false\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/carrierwave_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Carrierwave field', type: :request, active_record: true do\n  subject { page }\n  before do\n    RailsAdmin.config FieldTest do\n      edit do\n        field :string_field\n        field :carrierwave_asset\n      end\n    end\n  end\n\n  it 'supports caching an uploaded file' do\n    visit new_path(model_name: 'field_test')\n    attach_file 'Carrierwave asset', file_path('test.jpg')\n    fill_in 'field_test[string_field]', with: 'Invalid'\n    click_button 'Save'\n    expect(page).to have_content 'Field test failed to be created'\n    fill_in 'field_test[string_field]', with: ''\n    click_button 'Save'\n    expect(FieldTest.first.carrierwave_asset.file).to exist\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/ck_editor_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'CKEditor field', type: :request do\n  subject { page }\n\n  it 'works without error', js: true do\n    RailsAdmin.config Draft do\n      edit do\n        field :notes, :ck_editor\n      end\n    end\n    expect { visit new_path(model_name: 'draft') }.not_to raise_error\n    is_expected.to have_selector('#cke_draft_notes')\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/code_mirror_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'CodeMirror field', type: :request do\n  subject { page }\n\n  it 'works without error', js: true do\n    RailsAdmin.config Draft do\n      edit do\n        field :notes, :code_mirror\n      end\n    end\n    expect { visit new_path(model_name: 'draft') }.not_to raise_error\n    is_expected.to have_selector('.CodeMirror')\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/color_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Color field', type: :request do\n  subject { page }\n\n  it 'uses HTML5 color picker' do\n    RailsAdmin.config Team do\n      field :color, :color\n    end\n    visit new_path(model_name: 'team')\n    is_expected.to have_selector('#team_color[type=\"color\"]')\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/date_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Date field', type: :request do\n  subject { page }\n  before do\n    RailsAdmin.config FieldTest do\n      field :id\n      field :date_field\n    end\n  end\n\n  describe 'filtering' do\n    let!(:field_tests) do\n      [FactoryBot.create(:field_test, date_field: Date.new(2021, 1, 2)),\n       FactoryBot.create(:field_test, date_field: Date.new(2021, 1, 3))]\n    end\n\n    it 'correctly returns a record' do\n      visit index_path(model_name: 'field_test', f: {date_field: {'1' => {v: [nil, '2021-01-03T00:00:00', nil], o: 'between'}}})\n      is_expected.to have_content '1 field test'\n      is_expected.to have_content field_tests[1].id\n    end\n\n    it 'does not break when the condition is not filled' do\n      visit index_path(model_name: 'field_test', f: {date_field: {'1' => {v: [nil, '', ''], o: 'between'}}})\n      is_expected.to have_content '2 field test'\n    end\n\n    context 'with server timezone changed' do\n      around do |example|\n        original = Time.zone\n        Time.zone = ActiveSupport::TimeZone.new('Central Time (US & Canada)')\n        example.run\n        Time.zone = original\n      end\n\n      it 'correctly returns a record' do\n        visit index_path(model_name: 'field_test', f: {date_field: {'1' => {v: [nil, '2021-01-03T00:00:00', nil], o: 'between'}}})\n        is_expected.to have_content '1 field test'\n        is_expected.to have_content field_tests[1].id\n      end\n    end\n  end\n\n  context 'on create' do\n    it 'is initially blank' do\n      visit new_path(model_name: 'field_test')\n      expect(find('[name=\"field_test[date_field]\"]', visible: false).value).to be_blank\n    end\n\n    it 'persists the value' do\n      visit new_path(model_name: 'field_test')\n      find('[name=\"field_test[date_field]\"]', visible: false).set('2021-01-02T00:00:00')\n      click_button 'Save'\n      expect(FieldTest.count).to eq 1\n      expect(FieldTest.first.date_field).to eq Date.new(2021, 1, 2)\n    end\n\n    it 'ignores the time part' do\n      visit new_path(model_name: 'field_test')\n      find('[name=\"field_test[date_field]\"]', visible: false).set('2021-01-02T12:34:00')\n      click_button 'Save'\n      expect(FieldTest.count).to eq 1\n      expect(FieldTest.first.date_field).to eq Date.new(2021, 1, 2)\n    end\n  end\n\n  context 'on update' do\n    let(:field_test) { FactoryBot.create :field_test, date_field: Date.new(2021, 1, 2) }\n\n    it 'updates the value' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      expect(find('[name=\"field_test[date_field]\"]', visible: false).value).to eq '2021-01-02T00:00:00'\n      find('[name=\"field_test[date_field]\"]', visible: false).set('2021-02-03T00:00:00')\n      click_button 'Save'\n      field_test.reload\n      expect(field_test.date_field).to eq Date.new(2021, 2, 3)\n    end\n  end\n\n  context 'with server timezone changed' do\n    let(:field_test) { FactoryBot.create :field_test, date_field: Date.new(2015, 10, 8) }\n\n    around do |example|\n      original = Time.zone\n      Time.zone = ActiveSupport::TimeZone.new('Central Time (US & Canada)')\n      example.run\n      Time.zone = original\n    end\n\n    it 'is not altered by just saving untouched' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      expect(find('[name=\"field_test[date_field]\"]', visible: false).value).to eq '2015-10-08T00:00:00'\n      click_button 'Save'\n      expect { field_test.reload }.not_to change(field_test, :date_field)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/datetime_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Datetime field', type: :request do\n  subject { page }\n  before do\n    RailsAdmin.config FieldTest do\n      edit do\n        field :datetime_field\n      end\n    end\n  end\n\n  describe 'filtering' do\n    let!(:field_tests) do\n      [FactoryBot.create(:field_test, datetime_field: DateTime.new(2021, 1, 2, 3, 45)),\n       FactoryBot.create(:field_test, datetime_field: DateTime.new(2021, 1, 2, 4, 45))]\n    end\n\n    it 'correctly returns a record' do\n      visit index_path(model_name: 'field_test', f: {datetime_field: {'1' => {v: [nil, '2021-01-02T04:00:00', nil], o: 'between'}}})\n      is_expected.to have_content '1 field test'\n      is_expected.to have_content field_tests[1].id\n    end\n\n    it 'does not break when the condition is not filled' do\n      visit index_path(model_name: 'field_test', f: {datetime_field: {'1' => {v: [nil, '', ''], o: 'between'}}})\n      is_expected.to have_content '2 field test'\n    end\n\n    context 'with server timezone changed' do\n      around do |example|\n        original = Time.zone\n        Time.zone = ActiveSupport::TimeZone.new('Central Time (US & Canada)')\n        example.run\n        Time.zone = original\n      end\n\n      it 'correctly returns a record' do\n        visit index_path(model_name: 'field_test', f: {datetime_field: {'1' => {v: [nil, '2021-01-01T22:00:00', nil], o: 'between'}}})\n        is_expected.to have_content '1 field test'\n        is_expected.to have_content field_tests[1].id\n      end\n    end\n  end\n\n  context 'on create' do\n    it 'is initially blank' do\n      visit new_path(model_name: 'field_test')\n      expect(find('[name=\"field_test[datetime_field]\"]', visible: false).value).to be_blank\n    end\n\n    it 'persists the value' do\n      visit new_path(model_name: 'field_test')\n      find('[name=\"field_test[datetime_field]\"]', visible: false).set('2021-01-02T03:45:00')\n      click_button 'Save'\n      expect(FieldTest.count).to eq 1\n      expect(FieldTest.first.datetime_field).to eq DateTime.new(2021, 1, 2, 3, 45)\n    end\n  end\n\n  context 'on update' do\n    let(:field_test) { FactoryBot.create :field_test, datetime_field: DateTime.new(2021, 1, 2, 3, 45) }\n\n    it 'updates the value' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      expect(find('[name=\"field_test[datetime_field]\"]', visible: false).value).to eq '2021-01-02T03:45:00'\n      find('[name=\"field_test[datetime_field]\"]', visible: false).set('2021-02-03T04:55:00')\n      click_button 'Save'\n      field_test.reload\n      expect(field_test.datetime_field).to eq DateTime.new(2021, 2, 3, 4, 55)\n    end\n  end\n\n  context 'with server timezone changed' do\n    let(:field_test) { FactoryBot.create :field_test, datetime_field: DateTime.new(2015, 10, 8, 6, 45) }\n\n    around do |example|\n      original = Time.zone\n      Time.zone = ActiveSupport::TimeZone.new('Central Time (US & Canada)')\n      example.run\n      Time.zone = original\n    end\n\n    it 'treats the datetime set by the browser as local time' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      find('[name=\"field_test[datetime_field]\"]', visible: false).set('2021-02-03T04:55:00')\n      click_button 'Save'\n      field_test.reload\n      expect(field_test.datetime_field.iso8601).to eq '2021-02-03T04:55:00-06:00'\n    end\n\n    it 'is not altered by just saving untouched' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      expect(find('[name=\"field_test[datetime_field]\"]', visible: false).value).to eq '2015-10-08T01:45:00'\n      click_button 'Save'\n      expect { field_test.reload }.not_to change(field_test, :datetime_field)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/enum_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Enum field', type: :request, active_record: true do\n  subject { page }\n\n  before do\n    allow_any_instance_of(Team).to receive(:color_enum).and_return(%w[blue green red])\n  end\n\n  describe 'for single value' do\n    before do\n      RailsAdmin.config Team do\n        field :color\n      end\n    end\n\n    it 'shows a single-value edit form' do\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('.enum_type select')\n      is_expected.not_to have_selector('.enum_type select[multiple]')\n      expect(all('.enum_type option').map(&:text).select(&:present?)).to eq %w[blue green red]\n    end\n\n    it 'uses the filtering-select widget for selection', js: true do\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('.enum_type .filtering-select')\n    end\n  end\n\n  describe 'for multiple values' do\n    before do\n      RailsAdmin.config Team do\n        field :color do\n          multiple true\n        end\n      end\n    end\n\n    it 'shows a multiple-value edit form' do\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('.enum_type select')\n      is_expected.to have_selector('.enum_type select[multiple]')\n      expect(all('.enum_type option').map(&:text).select(&:present?)).to eq %w[blue green red]\n    end\n\n    it 'uses the filtering-multiselect widget for selection', js: true do\n      visit new_path(model_name: 'team')\n      is_expected.to have_selector('.enum_type .ra-multiselect')\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/file_upload_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'FileUpload field', type: :request do\n  subject { page }\n\n  before do\n    RailsAdmin.config FieldTest do\n      field :string_field, :file_upload do\n        delete_method 'boolean_field'\n        def resource_url(_thumb = false)\n          value\n        end\n      end\n    end\n  end\n  let(:field_test) { FactoryBot.create :field_test, string_field: 'http://localhost/dummy.jpg' }\n\n  it 'supports deletion', js: true do\n    visit edit_path(model_name: 'field_test', id: field_test.id)\n    expect(find('#field_test_boolean_field', visible: false)).not_to be_checked\n    click_link \"Delete 'String field'\"\n    expect(find('#field_test_boolean_field', visible: false)).to be_checked\n  end\n\n  it 'shows a inline preview', js: true do\n    visit new_path(model_name: 'field_test')\n    attach_file 'String field', file_path('test.jpg')\n    is_expected.to have_selector('#field_test_string_field_field img.preview')\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/floara_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Floara field', type: :request do\n  subject { page }\n\n  it 'works without error', js: true do\n    RailsAdmin.config Draft do\n      edit do\n        field :notes, :froala\n      end\n    end\n    expect { visit new_path(model_name: 'draft') }.not_to raise_error\n    is_expected.to have_selector('.fr-box')\n  end\n\n  it 'should include custom froala configuration' do\n    RailsAdmin.config Draft do\n      edit do\n        field :notes, :froala do\n          config_options inlineMode: false\n          css_location 'stub_css.css'\n          js_location 'stub_js.js'\n        end\n      end\n    end\n\n    visit new_path(model_name: 'draft')\n    is_expected.to have_selector('textarea#draft_notes[data-richtext=\"froala-wysiwyg\"][data-options]')\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/has_and_belongs_to_many_association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'HasAndBelongsToManyAssociation field', type: :request do\n  subject { page }\n\n  context 'on create' do\n    before do\n      @teams = FactoryBot.create_list(:team, 3)\n      post new_path(model_name: 'fan', fan: {name: 'John Doe', team_ids: [@teams[0].id]})\n      @fan = RailsAdmin::AbstractModel.new('Fan').first\n    end\n\n    it 'creates an object with correct associations' do\n      @teams[0].reload\n      expect(@fan.teams).to include(@teams[0])\n      expect(@fan.teams).not_to include(@teams[1])\n      expect(@fan.teams).not_to include(@teams[2])\n    end\n  end\n\n  describe 'on update' do\n    before do\n      @teams = FactoryBot.create_list(:team, 3)\n      @fan = FactoryBot.create :fan, teams: [@teams[0]]\n      visit edit_path(model_name: 'fan', id: @fan.id)\n    end\n\n    it 'shows associated objects' do\n      is_expected.to have_selector '#fan_team_ids' do |select|\n        options = select.all 'option'\n\n        expect(options[0]['selected']).to eq 'selected'\n        expect(options[1]['selected']).to eq nil\n        expect(options[2]['selected']).to eq nil\n      end\n    end\n  end\n\n  describe 'on show' do\n    before do\n      @player = FactoryBot.create :player\n      @comment1 = FactoryBot.create :comment, commentable: @player\n      @comment2 = FactoryBot.create :comment, commentable: @player\n      @comment3 = FactoryBot.create :comment, commentable: FactoryBot.create(:player)\n\n      visit show_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'shows associated objects' do\n      is_expected.to have_css(\"a[href='/admin/comment/#{@comment1.id}']\")\n      is_expected.to have_css(\"a[href='/admin/comment/#{@comment2.id}']\")\n      is_expected.not_to have_css(\"a[href='/admin/comment/#{@comment3.id}']\")\n    end\n  end\n\n  context \"with Mongoid's custom primary_key option\", mongoid: true do\n    let(:user) { FactoryBot.create :managing_user, players: [players[0]], balls: [balls[0]] }\n    let!(:players) { FactoryBot.create_list(:player, 2) }\n    let!(:balls) { %w[red blue].map { |color| FactoryBot.create(:ball, color: color) } }\n    before do\n      RailsAdmin.config ManagingUser do\n        field :players\n        field :balls\n      end\n    end\n\n    it 'allows update' do\n      visit edit_path(model_name: 'managing_user', id: user.id)\n      expect(find(\"select#managing_user_player_names option[value=\\\"#{players[0].name}\\\"]\")).to be_selected\n      expect(find(\"select#managing_user_ball_ids option[value=\\\"#{balls[0].color}\\\"]\")).to be_selected\n      select(players[1].name, from: 'Players')\n      select(balls[1].rails_admin_default_object_label_method, from: 'Balls')\n      click_button 'Save'\n      expect(ManagingUser.first.players).to match_array players\n      expect(ManagingUser.first.balls).to match_array balls\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/has_many_association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'HasManyAssociation field', type: :request do\n  subject { page }\n\n  it 'adds a related id to the has_many create team link' do\n    @team = FactoryBot.create :team\n    visit edit_path(model_name: 'team', id: @team.id)\n    is_expected.to have_selector(\"a[data-link='/admin/player/new?modal=true&player%5Bteam_id%5D=#{@team.id}']\")\n  end\n\n  context 'when an association is readonly' do\n    it 'is not editable' do\n      @league = FactoryBot.create :league\n      visit edit_path(model_name: 'league', id: @league.id)\n      is_expected.not_to have_selector('select#league_team_ids')\n      is_expected.to have_selector('select#league_division_ids') # decoy, fails if naming scheme changes\n    end\n  end\n\n  describe 'has many associations through more than one association' do\n    it 'is not editable' do\n      @league = FactoryBot.create :league\n      visit edit_path(model_name: 'league', id: @league.id)\n      expect(page).to have_selector('select#league_division_ids')\n      expect(page).to_not have_selector('select#league_player_ids')\n    end\n  end\n\n  describe 'on create' do\n    before do\n      @divisions = Array.new(3) { Division.create!(name: \"div #{Time.now.to_f}\", league: League.create!(name: \"league #{Time.now.to_f}\")) }\n    end\n\n    it 'shows selects' do\n      visit new_path(model_name: 'league')\n      is_expected.to have_selector('select#league_division_ids')\n    end\n\n    it 'creates an object with correct associations' do\n      post new_path(model_name: 'league', league: {name: 'National League', division_ids: [@divisions[0].id]})\n      @league = RailsAdmin::AbstractModel.new('League').all.to_a.last\n      @divisions[0].reload\n      expect(@league.divisions).to include(@divisions[0])\n      expect(@league.divisions).not_to include(@divisions[1])\n      expect(@league.divisions).not_to include(@divisions[2])\n    end\n\n    context 'with default_value' do\n      before do\n        ids = [@divisions[2].id]\n        RailsAdmin.config League do\n          configure :divisions do\n            default_value ids\n          end\n        end\n      end\n\n      it 'shows the value as selected' do\n        visit new_path(model_name: 'league')\n        expect(find('select#league_division_ids').value).to eq [@divisions[2].id.to_s]\n      end\n    end\n  end\n\n  context 'on update' do\n    it 'is fillable and emptyable', active_record: true do\n      @league = FactoryBot.create :league\n      @divisions = Array.new(3) { Division.create!(name: \"div #{Time.now.to_f}\", league: League.create!(name: \"league #{Time.now.to_f}\")) }\n\n      put edit_path(model_name: 'league', id: @league.id, league: {name: 'National League', division_ids: [@divisions[0].id]})\n\n      @league.reload\n      expect(@league.name).to eq('National League')\n      @divisions[0].reload\n      expect(@league.divisions).to include(@divisions[0])\n      expect(@league.divisions).not_to include(@divisions[1])\n      expect(@league.divisions).not_to include(@divisions[2])\n\n      put edit_path(model_name: 'league', id: @league.id, league: {division_ids: ['']})\n\n      @league.reload\n      expect(@league.divisions).to be_empty\n    end\n\n    context 'with embedded model', mongoid: true do\n      it 'is editable' do\n        @record = FactoryBot.create :field_test\n        2.times.each { |i| @record.embeds.create name: \"embed #{i}\" }\n        visit edit_path(model_name: 'field_test', id: @record.id)\n        fill_in 'field_test_embeds_attributes_0_name', with: 'embed 1 edited'\n        page.find('#field_test_embeds_attributes_1__destroy', visible: false).set('true')\n        click_button 'Save' # first(:button, \"Save\").click\n        @record.reload\n        expect(@record.embeds.length).to eq(1)\n        expect(@record.embeds[0].name).to eq('embed 1 edited')\n      end\n    end\n  end\n\n  context 'on show' do\n    context 'with embedded model', mongoid: true do\n      it \"does not show link to individual object's page\" do\n        @record = FactoryBot.create :field_test\n        2.times.each { |i| @record.embeds.create name: \"embed #{i}\" }\n        visit show_path(model_name: 'field_test', id: @record.id)\n        is_expected.not_to have_link('embed 0')\n        is_expected.not_to have_link('embed 1')\n      end\n    end\n  end\n\n  context 'on list' do\n    context 'with embedded model', mongoid: true do\n      it \"does not show link to individual object's page\" do\n        RailsAdmin.config FieldTest do\n          list do\n            field :embeds\n          end\n        end\n        @record = FactoryBot.create :field_test\n        2.times.each { |i| @record.embeds.create name: \"embed #{i}\" }\n        visit index_path(model_name: 'field_test')\n        is_expected.not_to have_link('embed 0')\n        is_expected.not_to have_link('embed 1')\n      end\n    end\n  end\n\n  context 'with not nullable foreign key', active_record: true do\n    before do\n      RailsAdmin.config FieldTest do\n        edit do\n          field :nested_field_tests do\n            nested_form false\n          end\n        end\n      end\n      @field_test = FactoryBot.create :field_test\n    end\n\n    it 'don\\'t allow to remove element', js: true do\n      visit edit_path(model_name: 'FieldTest', id: @field_test.id)\n      is_expected.not_to have_selector('a.ra-multiselect-item-remove')\n      is_expected.not_to have_selector('a.ra-multiselect-item-remove-all')\n    end\n  end\n\n  context 'with nullable foreign key', active_record: true do\n    before do\n      RailsAdmin.config Team do\n        edit do\n          field :players\n        end\n      end\n      @team = FactoryBot.create :team\n    end\n\n    it 'allow to remove element', js: true do\n      visit edit_path(model_name: 'Team', id: @team.id)\n      is_expected.to have_selector('a.ra-multiselect-item-remove')\n      is_expected.to have_selector('a.ra-multiselect-item-remove-all')\n    end\n  end\n\n  context 'with custom primary_key option' do\n    let(:user) { FactoryBot.create :managing_user }\n    let!(:teams) { [FactoryBot.create(:managed_team, manager: user.email), FactoryBot.create(:managed_team)] }\n    before do\n      RailsAdmin.config.included_models = [ManagingUser, ManagedTeam]\n      RailsAdmin.config ManagingUser do\n        field :teams\n      end\n    end\n\n    it 'allows update' do\n      visit edit_path(model_name: 'managing_user', id: user.id)\n      expect(find(\"select#managing_user_team_ids option[value=\\\"#{teams[0].id}\\\"]\")).to have_content teams[0].name\n      select(teams[1].name, from: 'Teams')\n      click_button 'Save'\n      is_expected.to have_content 'Managing user successfully updated'\n      expect(ManagingUser.first.teams).to match_array teams\n    end\n\n    context 'when fetching associated objects via xhr' do\n      before do\n        RailsAdmin.config ManagingUser do\n          field(:teams) { associated_collection_cache_all false }\n        end\n      end\n\n      it 'allows update', js: true do\n        visit edit_path(model_name: 'managing_user', id: user.id)\n        find('input.ra-multiselect-search').set('T')\n        find('.ra-multiselect-collection option', text: teams[1].name).select_option\n        find('.ra-multiselect-item-add').click\n        click_button 'Save'\n        is_expected.to have_content 'Managing user successfully updated'\n        expect(ManagingUser.first.teams).to match_array teams\n      end\n    end\n  end\n\n  context 'with composite foreign keys', composite_primary_keys: true do\n    let(:fan) { FactoryBot.create(:fan) }\n    let!(:fanships) { FactoryBot.create_list(:fanship, 3) }\n\n    describe 'via default field' do\n      before do\n        RailsAdmin.config Fan do\n          field :name\n          field :fanships\n        end\n      end\n\n      it 'shows the current selection' do\n        visit edit_path(model_name: 'fan', id: fanships[0].fan.id)\n        is_expected.to have_select('Fanships', selected: \"Fanship ##{fanships[0].id}\")\n      end\n\n      it 'allows update' do\n        visit edit_path(model_name: 'fan', id: fan.id)\n        select(\"Fanship ##{fanships[0].id}\", from: 'Fanships')\n        select(\"Fanship ##{fanships[1].id}\", from: 'Fanships')\n        click_button 'Save'\n        is_expected.to have_content 'Fan successfully updated'\n        expect(fan.reload.fanships.map(&:team_id)).to match_array fanships.map(&:team_id)[0..1]\n      end\n\n      context 'with invalid key' do\n        before do\n          allow_any_instance_of(RailsAdmin::Config::Fields::Types::HasManyAssociation).\n            to receive(:collection).and_return([[\"Fanship ##{fanships[0].id}\", 'invalid']])\n        end\n\n        it 'fails to update' do\n          visit edit_path(model_name: 'fan', id: fan.id)\n          select(\"Fanship ##{fanships[0].id}\", from: 'Fanships')\n          expect { click_button 'Save' }.to raise_error ActiveRecord::RecordNotFound\n        end\n      end\n    end\n\n    describe 'via remote-sourced field' do\n      before do\n        RailsAdmin.config Fan do\n          field :name\n          field :fanships do\n            associated_collection_cache_all false\n          end\n        end\n      end\n\n      it 'allows update', js: true do\n        visit edit_path(model_name: 'fan', id: fan.id)\n        find('input.ra-multiselect-search').set('F')\n        find('.ra-multiselect-collection option', text: \"Fanship ##{fanships[0].id}\").select_option\n        find('.ra-multiselect-collection option', text: \"Fanship ##{fanships[1].id}\").select_option\n        find('.ra-multiselect-item-add').click\n        click_button 'Save'\n        is_expected.to have_content 'Fan successfully updated'\n        expect(fan.reload.fanships.map(&:team_id)).to match_array fanships.map(&:team_id)[0..1]\n      end\n    end\n\n    describe 'via nested field' do\n      let!(:team) { FactoryBot.create :team }\n      let!(:fanships) { FactoryBot.create_list(:fanship, 2, fan: fan) }\n      before do\n        RailsAdmin.config NestedFan do\n          field :name\n          field :fanships\n        end\n      end\n\n      it 'allows update' do\n        visit edit_path(model_name: 'nested_fan', id: fan.id)\n        select(team.name, from: 'nested_fan_fanships_attributes_0_team_id')\n        fill_in 'nested_fan_fanships_attributes_1_since', with: '2020-01-23'\n        click_button 'Save'\n        is_expected.to have_content 'Nested fan successfully updated'\n        expect(fan.fanships[0].team).to eq team\n        expect(fan.fanships[1].since).to eq Date.new(2020, 1, 23)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/has_one_association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'HasOneAssociation field', type: :request do\n  subject { page }\n\n  it 'adds a related id to the has_one create draft link' do\n    @player = FactoryBot.create :player\n    visit edit_path(model_name: 'player', id: @player.id)\n    is_expected.to have_selector(\"a[data-link='/admin/draft/new?draft%5Bplayer_id%5D=#{@player.id}&modal=true']\")\n  end\n\n  context 'on create' do\n    before do\n      @draft = FactoryBot.create :draft\n    end\n\n    it 'shows selects' do\n      visit new_path(model_name: 'player')\n      is_expected.to have_selector('select#player_draft_id')\n    end\n\n    it 'creates an object with correct associations' do\n      visit new_path(model_name: 'player')\n      fill_in 'Name', with: 'Jackie Robinson'\n      fill_in 'Number', with: @draft.player.number + 1\n      select(\"Draft ##{@draft.id}\", from: 'Draft')\n      click_button 'Save'\n      is_expected.to have_content 'Player successfully created'\n      @player = Player.where(name: 'Jackie Robinson').first\n      @draft.reload\n      expect(@player.draft).to eq(@draft)\n    end\n\n    context 'with default_value' do\n      before do\n        id = @draft.id\n        RailsAdmin.config Player do\n          configure :draft do\n            default_value id\n          end\n        end\n      end\n\n      it 'shows the value as selected' do\n        visit new_path(model_name: 'player')\n        expect(find('select#player_draft_id').value).to eq @draft.id.to_s\n      end\n    end\n  end\n\n  context 'on update' do\n    before do\n      @drafts = FactoryBot.create_list :draft, 2\n      @player = FactoryBot.create :player, draft: @drafts[0]\n      visit edit_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'updates an object with correct associations' do\n      select(\"Draft ##{@drafts[1].id}\", from: 'Draft')\n      click_button 'Save'\n      @player.reload\n      expect(@player.draft).to eq(@drafts[1])\n    end\n\n    it 'clears the current selection' do\n      select('', from: 'Draft')\n      click_button 'Save'\n      @player.reload\n      expect(@player.draft).to be nil\n    end\n  end\n\n  describe 'on show' do\n    before do\n      @player = FactoryBot.create :player\n      @draft  = FactoryBot.create :draft, player: @player\n      visit show_path(model_name: 'player', id: @player.id)\n    end\n\n    it 'shows associated objects' do\n      is_expected.to have_css(\"a[href='/admin/draft/#{@draft.id}']\")\n    end\n  end\n\n  context 'with custom primary_key option' do\n    let(:user) { FactoryBot.create :managing_user }\n    let!(:team) { FactoryBot.create(:managed_team) }\n    before do\n      RailsAdmin.config.included_models = [ManagingUser, ManagedTeam]\n      RailsAdmin.config ManagingUser do\n        field :team\n      end\n    end\n\n    it 'allows update' do\n      visit edit_path(model_name: 'managing_user', id: user.id)\n      select(team.name, from: 'Team')\n      click_button 'Save'\n      is_expected.to have_content 'Managing user successfully updated'\n      expect(ManagingUser.first.team).to eq team\n    end\n\n    context 'when fetching associated objects via xhr' do\n      before do\n        RailsAdmin.config ManagingUser do\n          field(:team) { associated_collection_cache_all false }\n        end\n      end\n\n      it 'allows update', js: true do\n        visit edit_path(model_name: 'managing_user', id: user.id)\n        find('input.ra-filtering-select-input').set('T')\n        page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n        expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n        page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"#{team.name}\")).click()}\n        click_button 'Save'\n        is_expected.to have_content 'Managing user successfully updated'\n        expect(ManagingUser.first.team).to eq team\n      end\n    end\n  end\n\n  context 'with composite foreign keys', composite_primary_keys: true do\n    let(:fan) { FactoryBot.create(:fan) }\n    let!(:fanship) { FactoryBot.create(:fanship, fan: fan) }\n\n    describe 'via default field' do\n      before do\n        RailsAdmin.config Fan do\n          field :name\n          field :fanship\n        end\n      end\n\n      it 'allows create' do\n        visit new_path(model_name: 'fan')\n        fill_in 'Name', with: 'someone'\n        select(\"Fanship ##{fanship.id}\", from: 'Fanship')\n        click_button 'Save'\n        is_expected.to have_content 'Fan successfully created'\n        expect(Fan.where(name: 'someone').first.fanship.team_id).to eq fanship.team_id\n      end\n\n      it 'shows the current selection' do\n        visit edit_path(model_name: 'fan', id: fanship.fan_id)\n        is_expected.to have_select('Fanship', selected: \"Fanship ##{fanship.id}\")\n      end\n    end\n\n    describe 'via remote-sourced field' do\n      before do\n        RailsAdmin.config Fan do\n          field :name\n          field :fanship do\n            associated_collection_cache_all false\n          end\n        end\n      end\n\n      it 'allows create', js: true do\n        visit new_path(model_name: 'fan')\n        fill_in 'Name', with: 'someone'\n        find('.fanship_field input.ra-filtering-select-input').set(fanship.fan_id)\n        page.execute_script(\"document.querySelector('.fanship_field input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n        expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n        page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Fanship ##{fanship.id}\")).click()}\n        click_button 'Save'\n        is_expected.to have_content 'Fan successfully created'\n        expect(Fan.where(name: 'someone').first.fanship.team_id).to eq fanship.team_id\n      end\n    end\n\n    describe 'via nested field' do\n      let!(:team) { FactoryBot.create :team }\n      before do\n        RailsAdmin.config NestedFan do\n          field :name\n          field :fanship\n        end\n      end\n\n      it 'allows update' do\n        visit edit_path(model_name: 'nested_fan', id: fanship.fan_id)\n        select(team.name, from: 'Team')\n        fill_in 'Since', with: '2020-01-23'\n        click_button 'Save'\n        is_expected.to have_content 'Nested fan successfully updated'\n        expect(fan.fanship.team).to eq team\n        expect(fan.fanship.since).to eq Date.new(2020, 1, 23)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/hidden_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Hidden field', type: :request do\n  subject { page }\n\n  describe '#default_value' do\n    before do\n      RailsAdmin::Config.authenticate_with { warden.authenticate! scope: :user }\n      RailsAdmin::Config.current_user_method(&:current_user)\n      login_as User.create(\n        email: 'username@example.com',\n        password: 'password',\n      )\n    end\n\n    before do\n      RailsAdmin.config Player do\n        include_all_fields\n        edit do\n          field :name, :hidden do\n            default_value do\n              bindings[:view]._current_user.email\n            end\n          end\n        end\n      end\n    end\n\n    it 'shows up with default value, hidden' do\n      visit new_path(model_name: 'player')\n      is_expected.to have_selector(\"#player_name[type=hidden][value='username@example.com']\", visible: false)\n      is_expected.not_to have_selector(\"#player_name[type=hidden][value='toto@example.com']\", visible: false)\n    end\n\n    it 'does not show label' do\n      is_expected.not_to have_selector('label', text: 'Name')\n    end\n\n    it 'does not show help block' do\n      is_expected.not_to have_xpath(\"id('player_name')/../p[@class='help-block']\")\n    end\n\n    it 'submits the field value' do\n      visit new_path(model_name: 'player')\n      find(\"#player_name[type=hidden][value='username@example.com']\", visible: false).set('someone@example.com')\n      fill_in 'Number', with: 1\n      click_button 'Save'\n      is_expected.to have_content('Player successfully created')\n      expect(Player.first.name).to eq 'someone@example.com'\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/multiple_active_storage_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'MultipleActiveStorage field', type: :request, active_record: true do\n  subject { page }\n  before do\n    RailsAdmin.config FieldTest do\n      edit do\n        field :active_storage_assets\n      end\n    end\n    # To suppress 'SQLite3::BusyException: database is locked' exception\n    @original = page.driver.browser.url_blacklist # rubocop:disable Naming/InclusiveLanguage\n    page.driver.browser.url_blacklist = [%r{/rails/active_storage/representations}] # rubocop:disable Naming/InclusiveLanguage\n  end\n  after { page.driver.browser.url_blacklist = @original } # rubocop:disable Naming/InclusiveLanguage\n\n  it 'supports uploading multiple files', js: true do\n    visit new_path(model_name: 'field_test')\n    attach_file 'Active storage assets', [file_path('test.jpg'), file_path('test.png')]\n    click_button 'Save'\n    is_expected.to have_content 'Field test successfully created'\n    expect(FieldTest.first.active_storage_assets.map { |image| image.filename.to_s }).to match_array ['test.jpg', 'test.png']\n  end\n\n  context 'when working with existing files' do\n    let(:field_test) { FactoryBot.create(:field_test, active_storage_assets: ['test.jpg', 'test.png'].map { |img| {io: File.open(file_path(img)), filename: img} }) }\n\n    it 'supports appending a file', js: true do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      attach_file 'Active storage assets', [file_path('test.gif')]\n      click_button 'Save'\n      is_expected.to have_content 'Field test successfully updated'\n      field_test.reload\n      expect(field_test.active_storage_assets.map { |image| image.filename.to_s }).to eq ['test.jpg', 'test.png', 'test.gif']\n    end\n\n    it 'supports deleting a file', js: true do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      click_link \"Delete 'Active storage assets' #1\"\n      click_button 'Save'\n      is_expected.to have_content 'Field test successfully updated'\n      field_test.reload\n      expect(field_test.active_storage_assets.map { |image| image.filename.to_s }).to eq ['test.png']\n    end\n  end\n\n  describe 'direct upload', js: true do\n    let(:field_test) { FactoryBot.create :field_test }\n    before do\n      RailsAdmin.config FieldTest do\n        edit do\n          configure(:active_storage_assets) { direct true }\n        end\n      end\n    end\n\n    it 'works' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      attach_file 'Active storage assets', [file_path('test.jpg')]\n      expect_any_instance_of(ActiveStorage::DirectUploadsController).to receive(:create).and_call_original\n      click_button 'Save'\n      expect(page).to have_content 'Field test successfully updated'\n      field_test.reload\n      expect(field_test.active_storage_assets.map { |image| image.filename.to_s }).to eq ['test.jpg']\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/multiple_carrierwave_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'MultipleCarrierwave field', type: :request, active_record: true do\n  subject { page }\n  before do\n    RailsAdmin.config FieldTest do\n      edit do\n        field :carrierwave_assets\n      end\n    end\n  end\n\n  it 'supports uploading multiple files', js: true do\n    visit new_path(model_name: 'field_test')\n    attach_file 'Carrierwave assets', [file_path('test.jpg'), file_path('test.png')]\n    click_button 'Save'\n    is_expected.to have_content 'Field test successfully created'\n    expect(FieldTest.first.carrierwave_assets.map { |image| File.basename(image.url) }).to match_array ['test.jpg', 'test.png']\n  end\n\n  context 'when working with existing files' do\n    let(:field_test) { FactoryBot.create(:field_test, carrierwave_assets: ['test.jpg', 'test.png'].map { |img| File.open(file_path(img)) }) }\n\n    it 'supports appending a file', js: true do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      attach_file 'Carrierwave assets', [file_path('test.gif')]\n      click_button 'Save'\n      is_expected.to have_content 'Field test successfully updated'\n      field_test.reload\n      expect(field_test.carrierwave_assets.map { |image| File.basename(image.url) }).to eq ['test.jpg', 'test.png', 'test.gif']\n    end\n\n    it 'supports deleting a file', js: true do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      click_link \"Delete 'Carrierwave assets' #1\"\n      click_button 'Save'\n      is_expected.to have_content 'Field test successfully updated'\n      field_test.reload\n      expect(field_test.carrierwave_assets.map { |image| File.basename(image.url) }).to eq ['test.png']\n    end\n\n    it 'supports reordering files', js: true do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      page.execute_script File.read(File.expand_path('../../../vendor/assets/javascripts/rails_admin/jquery3.js', __dir__))\n      page.execute_script File.read(File.expand_path('../../support/jquery.simulate.drag-sortable.js', __dir__))\n      page.execute_script %{$(\".ui-sortable-handle:first-child\").simulateDragSortable({move: 1});}\n      click_button 'Save'\n      is_expected.to have_content 'Field test successfully updated'\n      field_test.reload\n      expect(field_test.carrierwave_assets.map { |image| File.basename(image.url) }).to eq ['test.png', 'test.jpg']\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/multiple_file_upload_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'MultipleFileUpload field', type: :request do\n  subject { page }\n\n  before do\n    RailsAdmin.config FieldTest do\n      field :string_field, :multiple_file_upload do\n        attachment do\n          delete_value { value }\n          def resource_url(_thumb = false)\n            value\n          end\n        end\n        delete_method 'boolean_field'\n        reorderable true\n        def value\n          bindings[:object].safe_send(name)&.split\n        end\n      end\n    end\n  end\n  let(:field_test) { FactoryBot.create :field_test, string_field: 'http://localhost/1.jpg http://localhost/2.jpg' }\n\n  it 'supports deletion', js: true do\n    visit edit_path(model_name: 'field_test', id: field_test.id)\n    click_link \"Delete 'String field' #1\"\n    expect(page.all(:css, '[name=\"field_test[boolean_field][]\"]:checked', visible: false).map(&:value)).to eq %w[http://localhost/1.jpg]\n  end\n\n  it 'shows a inline preview', js: true do\n    visit new_path(model_name: 'field_test')\n    attach_file 'String field', file_path('test.jpg')\n    is_expected.to have_selector('#field_test_string_field_field img.preview')\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/paperclip_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Paperclip field', type: :request do\n  subject { page }\n\n  it 'shows a file upload field' do\n    RailsAdmin.config User do\n      edit do\n        field :avatar\n      end\n    end\n    visit new_path(model_name: 'user')\n    is_expected.to have_selector('input#user_avatar')\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/polymorphic_assosiation_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'PolymorphicAssociation field', type: :request do\n  subject { page }\n\n  context 'on create' do\n    it 'is editable', js: true do\n      @players = ['Jackie Robinson', 'Rob Wooten'].map { |name| FactoryBot.create :player, name: name }\n      visit new_path(model_name: 'comment')\n      select 'Player', from: 'comment[commentable_type]'\n      find('input.ra-filtering-select-input').set('Rob')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Jackie Robinson\")).click()}\n      click_button 'Save'\n      is_expected.to have_content 'Comment successfully created'\n      expect(Comment.first.commentable).to eq @players[0]\n    end\n\n    it 'uses base class for models with inheritance' do\n      @hardball = FactoryBot.create :hardball\n      post new_path(model_name: 'comment', comment: {commentable_type: 'Hardball', commentable_id: @hardball.id})\n      @comment = Comment.first\n      expect(@comment.commentable_type).to eq 'Ball'\n      expect(@comment.commentable).to eq @hardball\n    end\n\n    it 'clears the selected id on type change', js: true do\n      @players = ['Jackie Robinson', 'Rob Wooten'].map { |name| FactoryBot.create :player, name: name }\n      visit new_path(model_name: 'comment')\n      select 'Player', from: 'comment[commentable_type]'\n      find('input.ra-filtering-select-input').set('Rob')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Jackie Robinson\")).click()}\n      select 'Team', from: 'comment[commentable_type]'\n      expect(find('#comment_commentable_id', visible: false).value).to eq ''\n    end\n\n    context 'when the associated model is declared in a two-level namespace' do\n      it 'successfully saves the record', js: true do\n        polymorphic_association_tests = ['Jackie Robinson', 'Rob Wooten'].map do |name|\n          FactoryBot.create(:two_level_namespaced_polymorphic_association_test, name: name)\n        end\n\n        visit new_path(model_name: 'comment')\n\n        select 'Polymorphic association test', from: 'comment[commentable_type]'\n        find('input.ra-filtering-select-input').set('Rob')\n\n        page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n        expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n\n        page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Jackie Robinson\")).click()}\n        click_button 'Save'\n        is_expected.to have_content 'Comment successfully created'\n        expect(Comment.first.commentable).to eq polymorphic_association_tests.first\n      end\n    end\n  end\n\n  context 'on update' do\n    let(:team) { FactoryBot.create :team, name: 'Los Angeles Dodgers' }\n    let(:comment) { FactoryBot.create :comment, commentable: team }\n    let!(:players) { ['Jackie Robinson', 'Rob Wooten', 'Scott Hairston'].map { |name| FactoryBot.create :player, name: name } }\n\n    it 'is editable', js: true do\n      visit edit_path(model_name: 'comment', id: comment.id)\n      expect(find('select#comment_commentable_type').value).to eq 'Team'\n      expect(find('select#comment_commentable_id', visible: false).value).to eq team.id.to_s\n      find('input.ra-filtering-select-input').set('Los')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      expect(all('ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to eq ['Los Angeles Dodgers']\n      select 'Player', from: 'comment[commentable_type]'\n      find('input.ra-filtering-select-input').set('Rob')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      expect(all('ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to eq ['Rob Wooten', 'Jackie Robinson']\n      page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Jackie Robinson\")).click()}\n      click_button 'Save'\n      is_expected.to have_content 'Comment successfully updated'\n      expect(comment.reload.commentable).to eq players[0]\n    end\n\n    it 'is visible in the owning end' do\n      visit edit_path(model_name: 'team', id: team.id)\n\n      is_expected.to have_selector('select#team_comment_ids')\n    end\n\n    context 'with records in different models share the same id', js: true do\n      let!(:players) { [FactoryBot.create(:player, id: team.id, name: 'Jackie Robinson')] }\n\n      it 'clears the selected id on type change', js: true do\n        visit edit_path(model_name: 'comment', id: comment.id)\n        select 'Player', from: 'comment[commentable_type]'\n        click_button 'Save'\n        is_expected.to have_content 'Comment successfully updated'\n        expect(comment.reload.commentable).to eq nil\n      end\n\n      it 'updates correctly', js: true do\n        visit edit_path(model_name: 'comment', id: comment.id)\n        select 'Player', from: 'comment[commentable_type]'\n        find('input.ra-filtering-select-input').set('Rob')\n        page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n        expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n        page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Jackie Robinson\")).click()}\n        click_button 'Save'\n        is_expected.to have_content 'Comment successfully updated'\n        expect(comment.reload.commentable).to eq players[0]\n      end\n    end\n  end\n\n  context 'on show' do\n    before do\n      @player = FactoryBot.create :player\n      @comment = FactoryBot.create :comment, commentable: @player\n      visit show_path(model_name: 'comment', id: @comment.id)\n    end\n\n    it 'shows associated object' do\n      is_expected.to have_css(\"a[href='/admin/player/#{@player.id}']\")\n    end\n  end\n\n  context 'on list' do\n    before :each do\n      @team = FactoryBot.create :team\n      @comment = FactoryBot.create :comment, commentable: @team\n    end\n\n    it 'works like belongs to associations in the list view' do\n      visit index_path(model_name: 'comment')\n\n      is_expected.to have_content(@team.name)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/serialized_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Serialized field', type: :request do\n  subject { page }\n\n  context 'with serialized objects' do\n    before do\n      RailsAdmin.config do |c|\n        c.model User do\n          configure :roles, :serialized\n        end\n      end\n\n      @user = FactoryBot.create :user\n\n      visit edit_path(model_name: 'user', id: @user.id)\n\n      fill_in 'user[roles]', with: %(['admin', 'user'])\n      click_button 'Save' # first(:button, \"Save\").click\n\n      @user.reload\n    end\n\n    it 'saves the serialized data' do\n      expect(@user.roles).to eq(%w[admin user])\n    end\n  end\n\n  context 'with serialized objects of Mongoid', mongoid: true do\n    before do\n      @field_test = FactoryBot.create :field_test\n\n      visit edit_path(model_name: 'field_test', id: @field_test.id)\n    end\n\n    it 'saves the serialized data' do\n      fill_in 'field_test[array_field]', with: '[4, 2]'\n      fill_in 'field_test[hash_field]', with: '{ a: 6, b: 2 }'\n      click_button 'Save' # first(:button, \"Save\").click\n\n      @field_test.reload\n      expect(@field_test.array_field).to eq([4, 2])\n      expect(@field_test.hash_field).to eq('a' => 6, 'b' => 2)\n    end\n\n    it 'clears data when empty string is passed' do\n      fill_in 'field_test[array_field]', with: ''\n      fill_in 'field_test[hash_field]', with: ''\n      click_button 'Save' # first(:button, \"Save\").click\n\n      @field_test.reload\n      expect(@field_test.array_field).to eq(nil)\n      expect(@field_test.hash_field).to eq(nil)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/shrine_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Shrine field', type: :request, active_record: true do\n  subject { page }\n  before do\n    RailsAdmin.config FieldTest do\n      edit do\n        field :string_field\n        field :shrine_asset\n      end\n    end\n  end\n\n  it 'supports caching an uploaded file', js: true do\n    visit new_path(model_name: 'field_test')\n    attach_file 'Shrine asset', file_path('test.jpg')\n    fill_in 'field_test[string_field]', with: 'Invalid'\n    click_button 'Save'\n    expect(page).to have_content 'Field test failed to be created'\n    fill_in 'field_test[string_field]', with: ''\n    click_button 'Save'\n    expect(FieldTest.first.shrine_asset).to exist\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/simple_mde_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'SimpleMDE field', type: :request do\n  subject { page }\n\n  it 'works without error', js: true do\n    RailsAdmin.config Draft do\n      edit do\n        field :notes, :simple_mde\n      end\n    end\n    expect { visit new_path(model_name: 'draft') }.not_to raise_error\n    is_expected.to have_selector('a[title=\"Markdown Guide\"]')\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/time_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Time field', type: :request, active_record: true do\n  subject { page }\n  before do\n    RailsAdmin.config FieldTest do\n      edit do\n        field :time_field\n      end\n    end\n  end\n\n  describe 'filtering' do\n    let!(:field_tests) do\n      [FactoryBot.create(:field_test, time_field: DateTime.new(2000, 1, 1, 3, 45)),\n       FactoryBot.create(:field_test, time_field: DateTime.new(2000, 1, 1, 4, 45))]\n    end\n\n    it 'correctly returns a record' do\n      visit index_path(model_name: 'field_test', f: {time_field: {'1' => {v: [nil, '2000-01-01T04:00:00', nil], o: 'between'}}})\n      is_expected.to have_content '1 field test'\n      is_expected.to have_content field_tests[1].id\n    end\n\n    it 'does not break when the condition is not filled' do\n      visit index_path(model_name: 'field_test', f: {time_field: {'1' => {v: [nil, '', ''], o: 'between'}}})\n      is_expected.to have_content '2 field test'\n    end\n\n    context 'with server timezone changed' do\n      around do |example|\n        original = Time.zone\n        Time.zone = ActiveSupport::TimeZone.new('Central Time (US & Canada)')\n        example.run\n        Time.zone = original\n      end\n\n      it 'correctly returns a record' do\n        visit index_path(model_name: 'field_test', f: {time_field: {'1' => {v: [nil, '2000-01-01T22:00:00', nil], o: 'between'}}})\n        is_expected.to have_content '1 field test'\n        is_expected.to have_content field_tests[1].id\n      end\n    end\n  end\n\n  context 'on create' do\n    it 'is initially blank' do\n      visit new_path(model_name: 'field_test')\n      expect(find('[name=\"field_test[time_field]\"]', visible: false).value).to be_blank\n    end\n\n    it 'persists the value' do\n      visit new_path(model_name: 'field_test')\n      find('[name=\"field_test[time_field]\"]', visible: false).set('2000-01-01T03:45:00')\n      click_button 'Save'\n      expect(FieldTest.count).to eq 1\n      expect(FieldTest.first.time_field).to eq DateTime.new(2000, 1, 1, 3, 45)\n    end\n\n    it 'ignores the date part' do\n      visit new_path(model_name: 'field_test')\n      find('[name=\"field_test[time_field]\"]', visible: false).set('2021-01-02T03:45:00')\n      click_button 'Save'\n      expect(FieldTest.first.time_field).to eq DateTime.new(2000, 1, 1, 3, 45)\n    end\n  end\n\n  context 'on update' do\n    let(:field_test) { FactoryBot.create :field_test, time_field: DateTime.new(2021, 1, 2, 3, 45) }\n\n    it 'updates the value' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      expect(find('[name=\"field_test[time_field]\"]', visible: false).value).to eq '2000-01-01T03:45:00'\n      find('[name=\"field_test[time_field]\"]', visible: false).set('2021-02-03T04:55:00')\n      click_button 'Save'\n      field_test.reload\n      expect(field_test.time_field).to eq DateTime.new(2000, 1, 1, 4, 55)\n    end\n  end\n\n  context 'with server timezone changed' do\n    let(:field_test) { FactoryBot.create :field_test, time_field: DateTime.new(2000, 1, 1, 6, 45) }\n\n    around do |example|\n      original = Time.zone\n      Time.zone = ActiveSupport::TimeZone.new('Central Time (US & Canada)')\n      example.run\n      Time.zone = original\n    end\n\n    it 'treats the datetime set by the browser as local time' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      find('[name=\"field_test[time_field]\"]', visible: false).set('2000-01-01T04:55:00')\n      click_button 'Save'\n      field_test.reload\n      expect(field_test.time_field.iso8601).to eq '2000-01-01T04:55:00-06:00'\n    end\n\n    it 'is not altered by just saving untouched' do\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      expect(find('[name=\"field_test[time_field]\"]', visible: false).value).to eq '2000-01-01T00:45:00'\n      click_button 'Save'\n      expect { field_test.reload }.not_to change(field_test, :time_field)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/fields/wysihtml5_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Wysihtml5 field', type: :request do\n  subject { page }\n\n  it 'works without error', js: true do\n    RailsAdmin.config Draft do\n      edit do\n        field :notes, :wysihtml5\n      end\n    end\n    expect { visit new_path(model_name: 'draft') }.not_to raise_error\n    is_expected.to have_selector('.wysihtml5-toolbar')\n  end\n\n  it 'should include custom wysihtml5 configuration' do\n    RailsAdmin.config Draft do\n      edit do\n        field :notes, :wysihtml5 do\n          config_options image: false\n          css_location 'stub_css.css'\n          js_location 'stub_js.js'\n        end\n      end\n    end\n\n    visit new_path(model_name: 'draft')\n    is_expected.to have_selector('textarea#draft_notes[data-richtext=\"bootstrap-wysihtml5\"][data-options]')\n  end\nend\n"
  },
  {
    "path": "spec/integration/rails_admin_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin, type: :request do\n  subject { page }\n\n  before do\n    RailsAdmin::Config.authenticate_with { warden.authenticate! scope: :user }\n    RailsAdmin::Config.current_user_method(&:current_user)\n    login_as User.create(\n      email: 'username@example.com',\n      password: 'password',\n    )\n  end\n\n  # A common mistake for translators is to forget to change the YAML file's\n  # root key from en to their own locale (as people tend to use the English\n  # file as template for a new translation).\n  describe 'localization' do\n    it 'defaults to English' do\n      RailsAdmin.config.included_models = []\n      visit dashboard_path\n\n      is_expected.to have_content('Site Administration')\n      is_expected.to have_content('Dashboard')\n    end\n  end\n\n  describe 'html head' do\n    before { visit dashboard_path }\n\n    # NOTE: the [href^=\"/asset... syntax matches the start of a value. The reason\n    # we just do that is to avoid being confused by rails' asset_ids.\n    it 'loads stylesheets in header' do\n      case RailsAdmin.config.asset_source\n      when :sprockets\n        is_expected.to have_selector('head link[href^=\"/assets/rails_admin\"][href$=\".css\"]', visible: false)\n      when :webpacker\n        is_expected.to have_no_selector('head link[href~=\"rails_admin\"][href$=\".css\"]', visible: false)\n      end\n    end\n\n    it 'loads javascript files in body' do\n      case RailsAdmin.config.asset_source\n      when :sprockets\n        is_expected.to have_selector('head script[src^=\"/assets/rails_admin\"][src$=\".js\"]', visible: false)\n      when :webpacker\n        is_expected.to have_selector('head script[src^=\"/packs-test/js/rails_admin\"][src$=\".js\"]', visible: false)\n      end\n    end\n  end\n\n  describe 'custom theming' do\n    before { visit dashboard_path }\n\n    if CI_ASSET == :sprockets\n      it 'applies the style overridden by assets in the application', js: true do\n        expect(find('.navbar-brand small').style('opacity')).to eq({'opacity' => '0.99'})\n      end\n    end\n  end\n\n  describe 'navbar css class' do\n    it 'is set by default' do\n      expect(RailsAdmin.config.navbar_css_classes).to eq(%w[navbar-dark bg-primary border-bottom])\n    end\n\n    it 'can be configured' do\n      RailsAdmin.config do |config|\n        config.navbar_css_classes = %w[navbar-light border-bottom]\n      end\n      visit dashboard_path\n      is_expected.to have_css('nav.navbar.navbar-light.border-bottom')\n    end\n  end\n\n  describe 'sidebar navigation', js: true do\n    it 'is collapsible' do\n      visit dashboard_path\n      is_expected.to have_css('.sidebar .nav-link', text: 'Players')\n      click_button 'Navigation'\n      is_expected.to have_css('.sidebar .btn-toggle.collapsed')\n      is_expected.not_to have_css('.sidebar #navigation.show')\n      is_expected.not_to have_css('.sidebar .nav-link', text: 'Players')\n    end\n\n    it 'persists over a page transition' do\n      visit dashboard_path\n      click_button 'Navigation'\n      is_expected.to have_css('.sidebar .btn-toggle.collapsed')\n      is_expected.not_to have_css('.sidebar #navigation.show')\n      find('.player_links .show a').trigger('click')\n      is_expected.to have_content 'List of Players'\n      is_expected.not_to have_css('.sidebar .nav-link', text: 'Players')\n    end\n  end\n\n  describe '_current_user' do # https://github.com/railsadminteam/rails_admin/issues/549\n    it 'is accessible from the list view' do\n      RailsAdmin.config Player do\n        list do\n          field :name do\n            visible do\n              bindings[:view]._current_user.email == 'username@example.com'\n            end\n          end\n\n          field :team do\n            visible do\n              bindings[:view]._current_user.email == 'foo@example.com'\n            end\n          end\n        end\n      end\n\n      visit index_path(model_name: 'player')\n      is_expected.to have_selector('.header.name_field')\n      is_expected.not_to have_selector('.header.team_field')\n    end\n  end\n\n  describe 'secondary navigation' do\n    it 'has Gravatar image' do\n      visit dashboard_path\n      is_expected.to have_selector('ul.navbar-nav img[src*=\"gravatar.com\"]')\n    end\n\n    it \"does not show Gravatar when user doesn't have email method\" do\n      allow_any_instance_of(User).to receive(:respond_to?).and_return(true)\n      allow_any_instance_of(User).to receive(:respond_to?).with(:email).and_return(false)\n      allow_any_instance_of(User).to receive(:respond_to?).with(:devise_scope).and_return(false)\n      visit dashboard_path\n      is_expected.not_to have_selector('ul.nav.pull-right li img')\n    end\n\n    it 'does not cause error when email is nil' do\n      allow_any_instance_of(User).to receive(:email).and_return(nil)\n      visit dashboard_path\n      is_expected.to have_selector('body.rails_admin')\n    end\n\n    it 'shows a log out link' do\n      visit dashboard_path\n      is_expected.to have_content 'Log out'\n    end\n\n    it 'has bg-danger class on log out link' do\n      visit dashboard_path\n      is_expected.to have_selector('.bg-danger')\n    end\n\n    it 'has links for actions which are marked as show_in_navigation' do\n      I18n.backend.store_translations(\n        :en, admin: {actions: {\n          shown_in_navigation: {menu: 'Look this'},\n        }}\n      )\n      RailsAdmin.config do |config|\n        config.actions do\n          dashboard do\n            show_in_navigation false\n          end\n          root :shown_in_navigation, :dashboard do\n            action_name :dashboard\n            show_in_navigation true\n          end\n        end\n      end\n\n      visit dashboard_path\n      is_expected.not_to have_css '.root_links li', text: 'Dashboard'\n      is_expected.to have_css '.root_links li', text: 'Look this'\n    end\n  end\n\n  describe 'CSRF protection' do\n    before do\n      allow_any_instance_of(ActionController::Base).to receive(:protect_against_forgery?).and_return(true)\n    end\n\n    it 'is enforced' do\n      visit new_path(model_name: 'league')\n      fill_in 'league[name]', with: 'National league'\n      find('input[name=\"authenticity_token\"]', visible: false).set('invalid token')\n      expect { click_button 'Save' }.to raise_error ActionController::InvalidAuthenticityToken\n    end\n  end\n\n  describe 'Turbo Drive', js: true do\n    let(:player) { FactoryBot.create :player }\n\n    it 'does not trigger JS errors by going away from and back to RailsAdmin' do\n      visit show_path(model_name: 'player', id: player.id)\n      click_link 'Show in app'\n      click_link 'Back to admin'\n      is_expected.to have_content 'Details for Player'\n    end\n\n    it 'triggers rails_admin.dom_ready right after a validation error' do\n      visit edit_path(model_name: 'player', id: player.id)\n      fill_in 'player[name]', with: 'on steroids'\n      find_button('Save').trigger 'click'\n      is_expected.to have_content 'Player failed to be updated'\n      is_expected.to have_css '.filtering-select[data-input-for=\"player_team_id\"]'\n    end\n\n    it 'does not prefetch pages' do\n      allow_any_instance_of(RailsAdmin::Config::Actions::Index).to receive(:controller).and_raise('index prefetched')\n      visit dashboard_path\n      find('.sidebar a.nav-link[href$=\"/player\"]').hover\n      sleep 0.3 # Turbo waits 100ms before prefetch\n    end\n  end\n\n  describe 'dom_ready events', js: true do\n    it 'trigger properly' do\n      visit dashboard_path\n      expect(evaluate_script('domReadyTriggered')).to match_array %w[plainjs/dot jquery/dot]\n    end\n  end\n\n  context 'with invalid model name' do\n    it \"redirects to dashboard and inform the user the model wasn't found\" do\n      visit '/admin/whatever'\n      expect(page.driver.status_code).to eq(404)\n      expect(find('.alert-danger')).to have_content(\"Model 'Whatever' could not be found\")\n    end\n  end\n\n  context 'with invalid action' do\n    it \"redirects to balls index and inform the user the id wasn't found\" do\n      visit '/admin/ball/545-typo'\n      expect(page.driver.status_code).to eq(404)\n      expect(find('.alert-danger')).to have_content(\"Ball with id '545-typo' could not be found\")\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/widgets/datetimepicker_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Datetimepicker widget', type: :request, js: true do\n  subject { page }\n\n  before do\n    RailsAdmin.config FieldTest do\n      edit do\n        field :datetime_field\n      end\n    end\n  end\n\n  it 'is initially blank' do\n    visit new_path(model_name: 'field_test')\n    expect(find('[name=\"field_test[datetime_field]\"]', visible: false).value).to be_blank\n    expect(find('[name=\"field_test[datetime_field]\"] + input').value).to be_blank\n  end\n\n  it 'populates the value selected by the Datetime picker into the hidden_field' do\n    visit new_path(model_name: 'field_test')\n    is_expected.to have_css '.form-control.flatpickr-input', visible: false\n    page.execute_script <<-JS\n      document.querySelector('#field_test_datetime_field')._flatpickr.setDate('2015-10-08 14:00:00');\n    JS\n    expect(find('#field_test_datetime_field + input').value).to eq 'October 08, 2015 14:00'\n    expect(find('[name=\"field_test[datetime_field]\"]', visible: false).value).to eq '2015-10-08T14:00:00'\n  end\n\n  it 'populates the value entered in the text field into the hidden_field' do\n    visit new_path(model_name: 'field_test')\n    find('#field_test_datetime_field + input').set 'January 2, 2021 03:45'\n    expect(find('[name=\"field_test[datetime_field]\"]', visible: false).value).to eq '2021-01-02T03:45:00'\n    expect(find('#field_test_datetime_field + input').value).to eq 'January 02, 2021 03:45'\n  end\n\n  it 'works with a different format' do\n    RailsAdmin.config FieldTest do\n      edit do\n        configure(:datetime_field) { strftime_format '%Y-%m-%d' }\n      end\n    end\n    visit new_path(model_name: 'field_test')\n    find('#field_test_datetime_field + input').set '2021-01-02'\n    expect(find('[name=\"field_test[datetime_field]\"]', visible: false).value).to eq '2021-01-02T00:00:00'\n    expect(find('#field_test_datetime_field + input').value).to eq '2021-01-02'\n  end\n\n  it 'supports custom flatpickr_format' do\n    RailsAdmin.config FieldTest do\n      edit do\n        configure(:datetime_field) { flatpickr_format 'H\\Hi\\MS\\S' }\n      end\n    end\n    visit new_path(model_name: 'field_test')\n    is_expected.to have_css '.form-control.flatpickr-input', visible: false\n    page.execute_script <<-JS\n      document.querySelector('#field_test_datetime_field')._flatpickr.setDate('2015-10-08 12:34:56');\n    JS\n    expect(find('#field_test_datetime_field + input').value).to eq '12H34M56S'\n  end\n\n  context 'with locale set' do\n    around(:each) do |example|\n      original = I18n.default_locale\n      I18n.default_locale = :fr\n      example.run\n      I18n.default_locale = original\n    end\n\n    it 'shows and accepts the value in the given locale' do\n      visit new_path(model_name: 'field_test', field_test: {datetime_field: '2021-01-02T03:45:00'})\n      expect(find('[name=\"field_test[datetime_field]\"]', visible: false).value).to eq '2021-01-02T03:45:00'\n      expect(find('#field_test_datetime_field + input').value).to eq 'samedi 02 janvier 2021 03:45'\n      find('#field_test_datetime_field + input').set 'mercredi 03 février 2021 04:55'\n      expect(find('[name=\"field_test[datetime_field]\"]', visible: false).value).to eq '2021-02-03T04:55:00'\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/widgets/filter_box_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Filter box widget', type: :request, js: true do\n  subject { page }\n\n  it 'adds filters' do\n    RailsAdmin.config Player do\n      field :name\n      field :position\n    end\n    visit index_path(model_name: 'player')\n    is_expected.to have_no_css('#filters_box .filter')\n    click_link 'Add filter'\n    click_link 'Name'\n    within('#filters_box') do\n      is_expected.to have_css('.filter', count: 1)\n      is_expected.to have_css('.filter select[name^=\"f[name]\"]')\n    end\n    click_link 'Add filter'\n    click_link 'Position'\n    within('#filters_box') do\n      is_expected.to have_css('.filter', count: 2)\n      is_expected.to have_css('.filter select[name^=\"f[position]\"]')\n    end\n  end\n\n  it 'removes filters' do\n    RailsAdmin.config Player do\n      field :name\n      field :position\n    end\n    visit index_path(model_name: 'player')\n    is_expected.to have_no_css('#filters_box .filter')\n    click_link 'Add filter'\n    click_link 'Name'\n    click_link 'Add filter'\n    click_link 'Position'\n    within('#filters_box') do\n      is_expected.to have_css('.filter', count: 2)\n      click_button 'Name'\n      is_expected.to have_no_css('.filter select[name^=\"f[name]\"]')\n      click_button 'Position'\n      is_expected.to have_no_css('.filter')\n    end\n  end\n\n  it 'hides redundant filter options for required fields' do\n    RailsAdmin.config Player do\n      list do\n        field :name do\n          required true\n        end\n        field :team\n      end\n    end\n\n    visit index_path(model_name: 'player', f: {name: {'1' => {v: ''}}, team: {'2' => {v: ''}}})\n\n    within(:select, name: 'f[name][1][o]') do\n      expect(page.all('option').map(&:value)).to_not include('_present', '_blank')\n    end\n\n    within(:select, name: 'f[team][2][o]') do\n      expect(page.all('option').map(&:value)).to include('_present', '_blank')\n    end\n  end\n\n  it 'supports limiting filter operators' do\n    RailsAdmin.config Player do\n      list do\n        field :name do\n          filter_operators %w[is starts_with _present]\n        end\n      end\n    end\n\n    visit index_path(model_name: 'player')\n    is_expected.to have_no_css('#filters_box .filter')\n    click_link 'Add filter'\n    click_link 'Name'\n\n    within(:select, name: /f\\[name\\]\\[\\d+\\]\\[o\\]/) do\n      expect(page.all('option').map(&:value)).to eq %w[is starts_with _present]\n    end\n  end\n\n  it 'does not cause duplication when using browser back' do\n    RailsAdmin.config Player do\n      field :name\n    end\n\n    visit index_path(model_name: 'player', f: {name: {'1' => {v: 'a'}}})\n    find(%([href$=\"/admin/player/export\"])).click\n    is_expected.to have_content 'Export Players'\n    page.go_back\n    is_expected.to have_content 'List of Players'\n    expect(all(:css, '#filters_box div.filter').count).to eq 1\n  end\n\n  describe 'for boolean field' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :boolean_field\n      end\n    end\n\n    it 'is filterable with true and false' do\n      visit index_path(model_name: 'field_test')\n      click_link 'Add filter'\n      click_link 'Boolean field'\n      within('#filters_box') do\n        expect(page.all('option').map(&:value)).to include('true', 'false')\n      end\n    end\n  end\n\n  describe 'for date field' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :date_field\n      end\n    end\n\n    it 'populates the value selected by the Datetimepicker into the hidden_field' do\n      visit index_path(model_name: 'field_test')\n      click_link 'Add filter'\n      click_link 'Date field'\n      expect(find('[name^=\"f[date_field]\"][name$=\"[v][]\"]', match: :first, visible: false).value).to be_blank\n      page.execute_script <<-JS\n        document.querySelector('.form-control.date')._flatpickr.setDate('2015-10-08');\n      JS\n      expect(find('[name^=\"f[date_field]\"][name$=\"[v][]\"]', match: :first, visible: false).value).to eq '2015-10-08T00:00:00'\n    end\n  end\n\n  describe 'for datetime field' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :datetime_field\n      end\n    end\n\n    it 'populates the value selected by the Datetimepicker into the hidden_field' do\n      visit index_path(model_name: 'field_test')\n      click_link 'Add filter'\n      click_link 'Datetime field'\n      expect(find('[name^=\"f[datetime_field]\"][name$=\"[v][]\"]', match: :first, visible: false).value).to be_blank\n      page.execute_script <<-JS\n        document.querySelector('.form-control.datetime')._flatpickr.setDate('2015-10-08 14:00:00');\n      JS\n      expect(find('[name^=\"f[datetime_field]\"][name$=\"[v][]\"]', match: :first, visible: false).value).to eq '2015-10-08T14:00:00'\n    end\n  end\n\n  describe 'for enum field' do\n    before do\n      RailsAdmin.config Team do\n        field :color, :enum\n      end\n    end\n\n    it 'supports multiple selection mode' do\n      visit index_path(model_name: 'team')\n      click_link 'Add filter'\n      click_link 'Color'\n      expect(all('#filters_box option').map(&:text)).to include 'white', 'black', 'red', 'green', 'blu<e>é'\n      find('.filter .switch-select .fa-plus').click\n      expect(find('#filters_box select')['multiple']).to be true\n      expect(find('#filters_box select')['name']).to match(/\\[\\]$/)\n    end\n\n    context 'with the filter pre-populated' do\n      it 'does not break' do\n        visit index_path(model_name: 'team', f: {color: {'1' => {v: 'red'}}})\n        is_expected.to have_css('.filter select[name^=\"f[color]\"]')\n        expect(find('.filter select[name^=\"f[color]\"]').value).to eq 'red'\n        expect(all('#filters_box option').map(&:text)).to include 'white', 'black', 'red', 'green', 'blu<e>é'\n      end\n    end\n  end\n\n  describe 'for time field', active_record: true do\n    before do\n      RailsAdmin.config FieldTest do\n        field :time_field\n      end\n    end\n\n    it 'populates the value selected by the Datetimepicker into the hidden_field' do\n      visit index_path(model_name: 'field_test')\n      click_link 'Add filter'\n      click_link 'Time field'\n      expect(find('[name^=\"f[time_field]\"][name$=\"[v][]\"]', match: :first, visible: false).value).to be_blank\n      page.execute_script <<-JS\n        document.querySelector('.form-control.datetime')._flatpickr.setDate('2000-01-01 14:00:00');\n      JS\n      expect(find('[name^=\"f[time_field]\"][name$=\"[v][]\"]', match: :first, visible: false).value).to eq '2000-01-01T14:00:00'\n    end\n  end\n\n  describe 'for has_one association field' do\n    before do\n      RailsAdmin.config Player do\n        field :draft do\n          searchable :college\n        end\n      end\n    end\n\n    it 'is filterable' do\n      visit index_path(model_name: 'player')\n      click_link 'Add filter'\n      click_link 'Draft'\n      expect(page).to have_css '[name^=\"f[draft]\"][name$=\"[o]\"]'\n      expect(page).to have_css '[name^=\"f[draft]\"][name$=\"[v]\"]'\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/widgets/filtering_multi_select_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Filtering multi-select widget', type: :request, js: true do\n  subject { page }\n\n  let(:team) { FactoryBot.create :team }\n  let!(:players) { ['Cory Burns', 'Leonys Martin', 'Matt Garza'].map { |name| FactoryBot.create :player, name: name } }\n  before do\n    RailsAdmin.config Team do\n      field :players\n    end\n  end\n\n  context 'on create' do\n    before { visit new_path(model_name: 'team') }\n\n    it 'is initially unset' do\n      expect(all('.ra-multiselect-collection option').map(&:text)).to match_array ['Leonys Martin', 'Cory Burns', 'Matt Garza']\n      expect(find('.ra-multiselect-selection').text).to be_empty\n    end\n\n    it 'supports filtering' do\n      find('input.ra-multiselect-search').set('Alex')\n      page.execute_script(\"document.querySelector('input.ra-multiselect-search').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_content 'No objects found'\n      find('input.ra-multiselect-search').set('Ma')\n      page.execute_script(\"document.querySelector('input.ra-multiselect-search').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_content 'Leonys'\n      expect(all('.ra-multiselect-collection option').map(&:text)).to match_array ['Leonys Martin', 'Matt Garza']\n    end\n\n    it 'sets ids of the selected items' do\n      find('.ra-multiselect-collection option', text: /Cory/).select_option\n      within('.ra-multiselect-center') { click_link 'Add new' }\n      expect(all('.ra-multiselect-selection option').map(&:text)).to match_array ['Cory Burns']\n      expect(all('.ra-multiselect-collection option').map(&:text)).to match_array ['Leonys Martin', 'Matt Garza']\n      expect(all('#team_player_ids option', visible: false).select(&:selected?).map(&:value)).to match_array [players[0].id.to_s]\n    end\n  end\n\n  context 'on update' do\n    let!(:player) { FactoryBot.create :player, team: team, name: 'Elvis Andrus' }\n    before { visit edit_path(model_name: 'team', id: team.id) }\n\n    it 'additionally selects items' do\n      expect(all('#team_player_ids option', visible: false).select(&:selected?).map(&:value)).to match_array [player.id.to_s]\n      find('.ra-multiselect-collection option', text: /Cory/).select_option\n      within('.ra-multiselect-center') { click_link 'Add new' }\n      expect(all('#team_player_ids option', visible: false).select(&:selected?).map(&:value)).to match_array [players[0].id.to_s, player.id.to_s]\n    end\n\n    it 'deselects the current selection' do\n      find('.ra-multiselect-selection option', text: /Elvis/).select_option\n      within('.ra-multiselect-center') { click_link 'Remove' }\n      expect(all('.ra-multiselect-selection option').map(&:text)).to be_empty\n      expect(all('.ra-multiselect-collection option').map(&:text)).to match_array ['Cory Burns', 'Leonys Martin', 'Matt Garza', 'Elvis Andrus']\n      expect(all('#team_player_ids option', visible: false).select(&:selected?).map(&:value)).to be_empty\n    end\n  end\n\n  describe 'Choose all button' do\n    it 'picks all available items' do\n      visit edit_path(model_name: 'team', id: team.id)\n      click_link 'Choose all'\n      expect(all(:css, '#team_player_ids option', visible: false).map(&:value)).to match_array players.map(&:id).map(&:to_s)\n    end\n  end\n\n  describe 'Clear all button' do\n    let!(:player) { FactoryBot.create :player, team: team, name: 'Elvis Andrus' }\n\n    it 'removes all selected items' do\n      visit edit_path(model_name: 'team', id: team.id)\n      find('.ra-multiselect-collection option', text: /Cory/).select_option\n      within('.ra-multiselect-center') { click_link 'Add new' }\n      expect(all('.ra-multiselect-selection option').map(&:text)).to match_array ['Cory Burns', 'Elvis Andrus']\n      click_link 'Clear all'\n      expect(all(:css, '#team_player_ids option', visible: false).select(&:selected?).map(&:value)).to be_empty\n    end\n  end\n\n  context 'when using remote requests' do\n    before do\n      RailsAdmin.config Team do\n        field(:players) { associated_collection_cache_all false }\n      end\n      visit edit_path(model_name: 'team', id: team.id)\n    end\n\n    it 'supports filtering' do\n      find('input.ra-multiselect-search').set('Alex')\n      page.execute_script(\"document.querySelector('input.ra-multiselect-search').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_content 'No objects found'\n      players[2].update name: 'Adam Rosales'\n      find('input.ra-multiselect-search').set('Ma')\n      page.execute_script(\"document.querySelector('input.ra-multiselect-search').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_content 'Leonys'\n      expect(all('.ra-multiselect-collection option').map(&:text)).to match_array ['Leonys Martin']\n    end\n\n    describe 'Choose all button' do\n      it 'does not pick the placeholder for selection' do\n        click_link 'Choose all'\n        expect(page).not_to have_css('#team_player_ids option', visible: false)\n        expect(page).not_to have_css('.ra-multiselect-selection option')\n      end\n\n      it 'picks all available items' do\n        find('input.ra-multiselect-search').set('Ma')\n        page.execute_script(\"document.querySelector('input.ra-multiselect-search').dispatchEvent(new KeyboardEvent('keydown'))\")\n        expect(page).to have_css('.ra-multiselect-collection option', text: /Matt/)\n        click_link 'Choose all'\n        expect(all(:css, '#team_player_ids option', visible: false).map(&:value)).to match_array players[1..2].map(&:id).map(&:to_s)\n      end\n    end\n  end\n\n  it 'does not cause duplication when using browser back' do\n    visit new_path(model_name: 'team')\n    find(%([href$=\"/admin/team/export\"])).click\n    is_expected.to have_content 'Export Teams'\n    page.go_back\n    is_expected.to have_content 'New Team'\n    expect(all(:css, 'input.ra-multiselect-search').count).to eq 1\n  end\n\n  describe 'dynamic scoping' do\n    let!(:team) { FactoryBot.create :team, division: FactoryBot.create(:division) }\n    let(:division) { FactoryBot.create(:division) }\n    let!(:teams) { ['Los Angeles Dodgers', 'Texas Rangers'].map { |name| FactoryBot.create :team, name: name, division: division } }\n    before do\n      RailsAdmin.config Team do\n        field :name\n        field :division\n      end\n      RailsAdmin.config Fan do\n        field :division, :enum do\n          enum { Division.pluck(:name, CI_ORM == :active_record ? :custom_id : :id).to_h }\n          def value\n            nil\n          end\n\n          def parse_input(params)\n            params.delete :division\n          end\n        end\n        field :teams do\n          dynamically_scope_by :division\n        end\n      end\n      visit new_path(model_name: 'fan')\n    end\n\n    it 'changes selection candidates based on value of the specified field' do\n      expect(all('#fan_team_ids option', visible: false).map(&:value).filter(&:present?)).to be_empty\n      select division.name, from: 'Division', visible: false\n      find('input.ra-multiselect-search').set('e')\n      page.execute_script(\"document.querySelector('input.ra-multiselect-search').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_content 'Dodgers'\n      expect(all('.ra-multiselect-collection option').map(&:text)).to match_array ['Los Angeles Dodgers', 'Texas Rangers']\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/widgets/filtering_select_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Filtering select widget', type: :request, js: true do\n  subject { page }\n\n  let!(:teams) { ['Los Angeles Dodgers', 'Texas Rangers'].map { |name| FactoryBot.create :team, name: name } }\n  let(:player) { FactoryBot.create :player, team: teams[0] }\n  before do\n    RailsAdmin.config Player do\n      field :team\n      field :number\n    end\n  end\n\n  context 'on create' do\n    before { visit new_path(model_name: 'player') }\n\n    it 'is initially unset' do\n      expect(find('input.ra-filtering-select-input').value).to be_empty\n      expect(find('#player_team_id', visible: false).value).to be_empty\n    end\n\n    it 'supports filtering' do\n      find('input.ra-filtering-select-input').set('ge')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      expect(all(:css, 'ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to match_array ['Los Angeles Dodgers', 'Texas Rangers']\n      find('input.ra-filtering-select-input').set('Los')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      expect(all(:css, 'ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to eq ['Los Angeles Dodgers']\n      find('input.ra-filtering-select-input').set('Mets')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      expect(all(:css, 'ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to match_array ['No objects found']\n    end\n\n    it 'sets id of the selected item' do\n      find('input.ra-filtering-select-input').set('Tex')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Texas Rangers\")).click()}\n      expect(find('#player_team_id', visible: false).value).to eq teams[1].id.to_s\n    end\n  end\n\n  context 'on update' do\n    it 'changes the selected value' do\n      visit edit_path(model_name: 'player', id: player.id)\n      expect(find('#player_team_id', visible: false).value).to eq teams[0].id.to_s\n      find('input.ra-filtering-select-input').set('Tex')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Texas Rangers\")).click()}\n      expect(find('#player_team_id', visible: false).value).to eq teams[1].id.to_s\n    end\n\n    it 'clears the current selection with making the search box empty' do\n      visit edit_path(model_name: 'player', id: player.id)\n      find('input.ra-filtering-select-input').set('')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keyup'))\")\n      expect(find('#player_team_id', visible: false).value).to be_empty\n    end\n\n    it 'clears the current selection with selecting the clear option' do\n      visit edit_path(model_name: 'player', id: player.id)\n      within('.filtering-select') { find('.dropdown-toggle').click }\n      find('a.ui-menu-item-wrapper', text: /Clear/).click\n      expect(find('#player_team_id', visible: false).value).to be_empty\n    end\n\n    context 'when the field is required' do\n      before do\n        RailsAdmin.config Player do\n          field(:team) { required true }\n        end\n        visit edit_path(model_name: 'player', id: player.id)\n      end\n\n      it 'does not show the clear option' do\n        within('.filtering-select') { find('.dropdown-toggle').click }\n        is_expected.not_to have_css('a.ui-menu-item-wrapper', text: /Clear/)\n      end\n    end\n  end\n\n  it 'prevents duplication when using browser back and forward' do\n    player\n    visit index_path(model_name: 'player')\n    find(%([href$=\"/admin/player/#{player.id}/edit\"])).click\n    is_expected.to have_content 'Edit Player'\n    page.go_back\n    is_expected.to have_content 'List of Players'\n    page.go_forward\n    is_expected.to have_content 'Edit Player'\n    expect(all(:css, 'input.ra-filtering-select-input').count).to eq 1\n  end\n\n  it 'does not lose options on browser back' do\n    visit edit_path(model_name: 'player', id: player.id)\n    find('.team_field .dropdown-toggle').click\n    find('li.ui-menu-item a', text: /Clear/).click\n    click_link 'Show'\n    is_expected.to have_content 'Details for Player'\n    page.go_back\n    find('.team_field input.ra-filtering-select-input').set('Los')\n    page.execute_script(\"document.querySelector('.team_field input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n    is_expected.to have_selector('ul.ui-autocomplete li.ui-menu-item a', text: 'Los Angeles Dodgers')\n  end\n\n  context 'when using remote requests' do\n    before do\n      RailsAdmin.config Player do\n        field :team do\n          associated_collection_cache_all false\n        end\n      end\n      visit new_path(model_name: 'player')\n    end\n\n    it 'supports filtering' do\n      find('input.ra-filtering-select-input').set('ge')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      expect(all(:css, 'ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to match_array ['Los Angeles Dodgers', 'Texas Rangers']\n      teams[0].update name: 'Cincinnati Reds'\n      find('input.ra-filtering-select-input').set('Red')\n      page.execute_script(\"document.querySelector('input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))\")\n      is_expected.to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n      expect(all(:css, 'ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to eq ['Cincinnati Reds']\n    end\n  end\n\n  describe 'dynamic scoping' do\n    let!(:players) { FactoryBot.create_list :player, 2, team: teams[1] }\n    let!(:freelancer) { FactoryBot.create :player, team: nil }\n\n    context 'with single field' do\n      before do\n        player\n        RailsAdmin.config Draft do\n          field :team\n          field :player do\n            dynamically_scope_by :team\n          end\n        end\n        visit new_path(model_name: 'draft')\n      end\n\n      it 'changes selection candidates based on value of the specified field' do\n        expect(all('#draft_player_id option', visible: false).map(&:value).filter(&:present?)).to be_empty\n        find('[data-input-for=\"draft_team_id\"] input.ra-filtering-select-input').set('Tex')\n        page.execute_script(%{document.querySelector('[data-input-for=\"draft_team_id\"] input.ra-filtering-select-input').dispatchEvent(new KeyboardEvent('keydown'))})\n        is_expected.to have_selector('ul.ui-autocomplete li.ui-menu-item a')\n        page.execute_script %{[...document.querySelectorAll('ul.ui-autocomplete li.ui-menu-item')].find(e => e.innerText.includes(\"Texas Rangers\")).click()}\n        within('[data-input-for=\"draft_player_id\"].filtering-select') { find('.dropdown-toggle').click }\n        expect(all(:css, 'ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to match_array players.map(&:name)\n      end\n\n      it 'allows filtering by blank value' do\n        within('[data-input-for=\"draft_player_id\"].filtering-select') { find('.dropdown-toggle').click }\n        expect(all(:css, 'ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to match_array [freelancer.name]\n      end\n    end\n\n    context 'with multiple fields' do\n      before do\n        player\n        RailsAdmin.config Draft do\n          field :team\n          field :player do\n            dynamically_scope_by [:team, {round: :number}]\n          end\n          field :round\n        end\n        visit new_path(model_name: 'draft', draft: {team_id: teams[1].id})\n      end\n\n      it 'changes selection candidates based on value of the specified fields' do\n        fill_in 'draft[round]', with: players[1].number\n        within('[data-input-for=\"draft_player_id\"].filtering-select') { find('.dropdown-toggle').click }\n        expect(all(:css, 'ul.ui-autocomplete li.ui-menu-item a').map(&:text)).to match_array [players[1].name]\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/widgets/nested_many_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Nested many widget', type: :request, js: true do\n  subject { page }\n\n  let(:field_test) { FactoryBot.create :field_test }\n  let(:nested_field_tests) { %w[1 2].map { |i| NestedFieldTest.create! title: \"title #{i}\", field_test: field_test } }\n  before do\n    RailsAdmin.config(FieldTest) do\n      field :nested_field_tests\n    end\n  end\n\n  it 'adds a new nested item' do\n    visit edit_path(model_name: 'field_test', id: field_test.id)\n\n    find('#field_test_nested_field_tests_attributes_field .add_nested_fields').click\n    expect(page).to have_selector('.fields.tab-pane.active', visible: true)\n\n    # trigger click via JS, workaround for instability in CI\n    execute_script %(document.querySelector('button[name=\"_save\"]').click())\n    is_expected.to have_content('Field test successfully updated')\n\n    expect(field_test.nested_field_tests.length).to eq(1)\n  end\n\n  it 'edits a nested item' do\n    nested_field_tests\n    visit edit_path(model_name: 'field_test', id: field_test.id)\n\n    fill_in 'field_test_nested_field_tests_attributes_0_title', with: 'nested field test title 1 edited', visible: false\n    edited_id = find('#field_test_nested_field_tests_attributes_0_id', visible: false).value\n\n    # trigger click via JS, workaround for instability in CI\n    execute_script %(document.querySelector('button[name=\"_save\"]').click())\n    is_expected.to have_content('Field test successfully updated')\n\n    expect(field_test.nested_field_tests.find(edited_id).title).to eq('nested field test title 1 edited')\n  end\n\n  it 'deletes a nested item' do\n    nested_field_tests\n    visit edit_path(model_name: 'field_test', id: field_test.id)\n\n    find('#field_test_nested_field_tests_attributes_0__destroy', visible: false).set('true')\n\n    # trigger click via JS, workaround for instability in CI\n    execute_script %(document.querySelector('button[name=\"_save\"]').click())\n    is_expected.to have_content('Field test successfully updated')\n\n    expect(field_test.reload.nested_field_tests.map(&:id)).to eq [nested_field_tests[1].id]\n  end\n\n  it 'sets bindings[:object] to nested object', js: false do\n    RailsAdmin.config(NestedFieldTest) do\n      nested do\n        field :title do\n          label do\n            bindings[:object].class.name\n          end\n        end\n      end\n    end\n    nested_field_tests\n    visit edit_path(model_name: 'field_test', id: field_test.id)\n    expect(find('#field_test_nested_field_tests_attributes_0_title_field')).to have_content('NestedFieldTest')\n  end\n\n  it 'is deactivatable' do\n    visit new_path(model_name: 'field_test')\n    is_expected.to have_selector('#field_test_nested_field_tests_attributes_field .add_nested_fields')\n    RailsAdmin.config(FieldTest) do\n      configure :nested_field_tests do\n        nested_form false\n      end\n    end\n    visit new_path(model_name: 'field_test')\n    is_expected.to have_no_selector('#field_test_nested_field_tests_attributes_field .add_nested_fields')\n  end\n\n  it 'is closable after adding a new item' do\n    visit new_path(model_name: 'field_test')\n    within('#field_test_nested_field_tests_attributes_field') do\n      find('.add_nested_fields').click\n      expect(page).to have_selector('.tab-content.collapse.show')\n      expect(page).to have_selector('.nav .nav-link.active', visible: true)\n      expect(page).to have_selector('.fields.tab-pane.active', visible: true)\n      find(':scope > .controls .toggler').click\n      expect(page).not_to have_selector('.tab-content.collapse.show')\n      expect(page).not_to have_selector('.nav .nav-link.active', visible: true)\n      expect(page).not_to have_selector('.fields.tab-pane.active', visible: true)\n    end\n  end\n\n  it 'closes after removing all items' do\n    visit new_path(model_name: 'field_test')\n    within('#field_test_nested_field_tests_attributes_field') do\n      find('.add_nested_fields').click\n      expect(page).to have_selector('.tab-content.collapse.show')\n      find(':scope > .tab-content > .fields > .remove_nested_fields', visible: false).click\n      expect(page).not_to have_selector('.nav .nav-link.active', visible: true)\n      expect(page).not_to have_selector('.fields.tab-pane.active', visible: true)\n    end\n  end\n\n  context 'with nested_attributes_options given' do\n    before do\n      allow(FieldTest.nested_attributes_options).to receive(:[]).with(any_args).\n        and_return(allow_destroy: true)\n    end\n\n    it 'does not show destroy button except for newly created when :allow_destroy is false', js: false do\n      nested_field_tests\n      allow(FieldTest.nested_attributes_options).to receive(:[]).with(:nested_field_tests).\n        and_return(allow_destroy: false)\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      expect(find('#field_test_nested_field_tests_attributes_0_title').value).to eq('title 1')\n      is_expected.not_to have_selector('form .remove_nested_fields')\n      expect(find('div#nested_field_tests_fields_blueprint', visible: false)[:'data-blueprint']).to match(\n        /<a[^>]* class=\"remove_nested_fields\"[^>]*>/,\n      )\n    end\n  end\n\n  context \"when a field which have the same name of nested_in field's\" do\n    it \"does not hide fields which are not associated with nesting parent field's model\" do\n      visit new_path(model_name: 'field_test')\n      is_expected.not_to have_selector('select#field_test_nested_field_tests_attributes_new_nested_field_tests_field_test_id')\n      expect(find('div#nested_field_tests_fields_blueprint', visible: false)[:'data-blueprint']).to match(\n        /<select[^>]* id=\"field_test_nested_field_tests_attributes_new_nested_field_tests_another_field_test_id\"[^>]*>/,\n      )\n    end\n\n    it 'hides fields that are deeply nested with inverse_of' do\n      visit new_path(model_name: 'field_test')\n      expect(page.body).to_not include('field_test_nested_field_tests_attributes_new_nested_field_tests_deeply_nested_field_tests_attributes_new_deeply_nested_field_tests_nested_field_test_id_field')\n      expect(page.body).to include('field_test_nested_field_tests_attributes_new_nested_field_tests_deeply_nested_field_tests_attributes_new_deeply_nested_field_tests_title')\n    end\n  end\n\n  context 'when XSS attack is attempted' do\n    it 'does not break on adding a new item' do\n      allow(I18n).to receive(:t).and_call_original\n      expect(I18n).to receive(:t).with('admin.form.new_model', name: 'Nested field test').and_return('<script>throw \"XSS\";</script>')\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      find('#field_test_nested_field_tests_attributes_field .add_nested_fields').click\n    end\n\n    it 'does not break on editing an existing item' do\n      NestedFieldTest.create! title: '<script>throw \"XSS\";</script>', field_test: field_test\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/widgets/nested_one_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Nested one widget', type: :request, js: true do\n  subject { page }\n\n  let(:field_test) { FactoryBot.create :field_test }\n  before do\n    RailsAdmin.config(FieldTest) do\n      field :comment\n    end\n  end\n\n  it 'adds an nested item' do\n    visit edit_path(model_name: 'field_test', id: field_test.id)\n\n    find('#field_test_comment_attributes_field .add_nested_fields').click\n    fill_in 'field_test_comment_attributes_content', with: 'nested comment content'\n\n    # trigger click via JS, workaround for instability in CI\n    execute_script %(document.querySelector('button[name=\"_save\"]').click())\n    is_expected.to have_content('Field test successfully updated')\n\n    expect(field_test.reload.comment.content.strip).to eq('nested comment content')\n  end\n\n  it 'deletes the nested item' do\n    FactoryBot.create :comment, commentable: field_test\n    visit edit_path(model_name: 'field_test', id: field_test.id)\n\n    find('.comment_field .toggler').click\n    find('.comment_field .remove_nested_fields', visible: false).click\n\n    # trigger click via JS, workaround for instability in CI\n    execute_script %(document.querySelector('button[name=\"_save\"]').click())\n    is_expected.to have_content('Field test successfully updated')\n\n    expect(field_test.reload.comment).to be nil\n  end\n\n  it 'is optional' do\n    visit edit_path(model_name: 'field_test', id: field_test.id)\n    click_button 'Save'\n    expect(field_test.reload.comment).to be_nil\n  end\n\n  it 'is closable after adding a new item' do\n    visit new_path(model_name: 'field_test')\n    within('#field_test_comment_attributes_field') do\n      find('.add_nested_fields').click\n      expect(page).to have_selector('.tab-content.collapse.show')\n      expect(page).to have_selector('.fields.tab-pane.active', visible: true)\n      find(':scope > .controls .toggler').click\n      expect(page).not_to have_selector('.tab-content.collapse.show')\n      expect(page).not_to have_selector('.fields.tab-pane.active', visible: true)\n    end\n  end\n\n  it 'closes after removing the item' do\n    visit new_path(model_name: 'field_test')\n    within('#field_test_comment_attributes_field') do\n      find('.add_nested_fields').click\n      expect(page).to have_selector('.tab-content.collapse.show')\n      find(':scope > .tab-content > .fields > .remove_nested_fields', visible: false).click\n      expect(page).not_to have_selector('.fields.tab-pane.active', visible: true)\n    end\n  end\n\n  context 'when XSS attack is attempted' do\n    it 'does not break on adding a new item' do\n      allow(I18n).to receive(:t).and_call_original\n      expect(I18n).to receive(:t).with('admin.form.new_model', name: 'Comment').and_return('<script>throw \"XSS\";</script>')\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n      find('#field_test_comment_attributes_field .add_nested_fields').click\n    end\n\n    it 'does not break on adding an existing item' do\n      RailsAdmin.config Comment do\n        object_label_method :content\n      end\n      FactoryBot.create :comment, content: '<script>throw \"XSS\";</script>', commentable: field_test\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n    end\n  end\n\n  context 'when the nested field contains a required field' do\n    before do\n      RailsAdmin.config Comment do\n        configure :content do\n          required true\n        end\n      end\n    end\n\n    it 'is not affected by form required validation' do\n      FactoryBot.create :comment, commentable: field_test, content: ''\n      visit edit_path(model_name: 'field_test', id: field_test.id)\n\n      find('.comment_field .toggler').click\n      find('.comment_field .remove_nested_fields', visible: false).click\n\n      # trigger click via JS, workaround for instability in CI\n      execute_script %(document.querySelector('button[name=\"_save\"]').click())\n      is_expected.to have_content('Field test successfully updated')\n\n      expect(field_test.reload.comment).to be nil\n    end\n  end\nend\n"
  },
  {
    "path": "spec/integration/widgets/remote_form_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'Remote form widget', type: :request, js: true do\n  subject { page }\n\n  describe 'modal' do\n    it 'supports focusing on sub-modals' do\n      visit new_path(model_name: 'division')\n      click_link 'Add a new League'\n      is_expected.to have_content 'New League'\n      is_expected.not_to have_css '#modal.modal-static'\n      execute_script %($(document.body).append($('<div id=\"sub-modal\" class=\"modal d-block\"><input type=\"text\" /></div>')))\n      find('#sub-modal input').click\n      is_expected.to have_css '#sub-modal input:focus'\n    end\n  end\n\n  context 'with filtering select widget' do\n    let(:league) { FactoryBot.create :league }\n    let(:division) { FactoryBot.create :division, league: league }\n    before do\n      RailsAdmin.config Division do\n        field :league\n      end\n      RailsAdmin.config League do\n        field :name\n      end\n    end\n\n    it 'creates an associated record' do\n      visit new_path(model_name: 'division')\n      click_link 'Add a new League'\n      is_expected.to have_content 'New League'\n      fill_in 'Name', with: 'National League'\n      find('#modal .save-action').click\n      expect(find('#division_custom_league_id', visible: false).value).to eq League.first.id.to_s\n      expect(League.pluck(:name)).to eq ['National League']\n    end\n\n    it 'updates the associated record' do\n      visit edit_path(model_name: 'division', id: division.id)\n      expect(find('#division_custom_league_id', visible: false).value).to eq league.id.to_s\n      click_link 'Edit this League'\n      is_expected.to have_content \"Edit League '#{league.name}'\"\n      fill_in 'Name', with: 'National League'\n      find('#modal .save-action').click\n      expect(find('#division_custom_league_id', visible: false).value).to eq league.id.to_s\n      expect(league.reload.name).to eq 'National League'\n    end\n  end\n\n  context 'with filtering multi-select widget' do\n    let(:leagues) { FactoryBot.create_list :league, 2 }\n    let!(:division) { FactoryBot.create :division, name: 'National League Central', league: leagues[0] }\n    before do\n      RailsAdmin.config League do\n        field :divisions\n      end\n      RailsAdmin.config Division do\n        field :name\n        field :league\n      end\n    end\n\n    it 'creates an associated record and adds into selection' do\n      visit edit_path(model_name: 'league', id: leagues[1].id)\n      click_link 'Add a new Division'\n      is_expected.to have_content 'New Division'\n      fill_in 'Name', with: 'National League West'\n      find(%(#division_custom_league_id option[value=\"#{leagues[0].id}\"]), visible: false).select_option\n      find('#modal .save-action').click\n      is_expected.to have_css('.ra-multiselect-selection option', text: 'National League West')\n      new_division = Division.where(name: 'National League West').first\n      expect(new_division).not_to be nil\n      expect(find('#league_division_ids', visible: false).value).to eq [new_division.id.to_s]\n    end\n\n    it 'updates an unselected associated record with leaving it unselected' do\n      visit edit_path(model_name: 'league', id: leagues[1].id)\n      find('.ra-multiselect-collection option', text: division.name).double_click\n      is_expected.to have_content \"Edit Division 'National League Central'\"\n      fill_in 'Name', with: 'National League East'\n      find('#modal .save-action').click\n      is_expected.to have_css('.ra-multiselect-collection option', text: 'National League East')\n      expect(find('#league_division_ids', visible: false).value).to eq []\n      expect(division.reload.name).to eq 'National League East'\n    end\n\n    it 'updates a selected associated record' do\n      visit edit_path(model_name: 'league', id: leagues[0].id)\n      find('.ra-multiselect-selection option', text: division.name).double_click\n      is_expected.to have_content \"Edit Division 'National League Central'\"\n      fill_in 'Name', with: 'National League East'\n      find('#modal .save-action').click\n      expect(find('#league_division_ids', visible: false).value).to eq [division.id.to_s]\n      expect(division.reload.name).to eq 'National League East'\n    end\n\n    context 'with inline_edit set to false' do\n      before do\n        RailsAdmin.config League do\n          field :divisions do\n            inline_edit false\n          end\n        end\n      end\n\n      it 'does not open the modal with double click' do\n        visit edit_path(model_name: 'league', id: leagues[1].id)\n        find('.ra-multiselect-collection option', text: division.name).double_click\n        is_expected.not_to have_content \"Edit Division 'National League Central'\"\n      end\n    end\n  end\n\n  context 'with file upload' do\n    before do\n      RailsAdmin.config NestedFieldTest do\n        field :field_test\n      end\n      RailsAdmin.config FieldTest do\n        field :carrierwave_asset\n      end\n    end\n\n    it 'submits successfully' do\n      visit new_path(model_name: 'nested_field_test')\n      click_link 'Add a new Field test'\n      is_expected.to have_content 'New Field test'\n      attach_file 'Carrierwave asset', file_path('test.jpg')\n      find('#modal .save-action').click\n      is_expected.to have_css('option', text: /FieldTest #/, visible: false)\n      expect(FieldTest.first.carrierwave_asset.file.size).to eq 1575\n    end\n  end\n\n  context 'with validation errors' do\n    before do\n      RailsAdmin.config Team do\n        field :players\n      end\n      RailsAdmin.config Player do\n        field :name\n        field :number\n        field :team\n      end\n    end\n\n    context 'on create' do\n      it 'shows the error messages' do\n        visit new_path(model_name: 'team')\n        click_link 'Add a new Player'\n        is_expected.to have_content 'New Player'\n        find('#player_name').set('on steroids')\n        find('#modal .save-action').click\n        is_expected.to have_css('#modal')\n        is_expected.to have_content 'Player is cheating'\n        is_expected.to have_css '.text-danger', text: 'is not a number'\n      end\n    end\n\n    context 'on update' do\n      let!(:player) { FactoryBot.create :player, name: 'Cheater' }\n\n      it 'shows the error messages' do\n        visit new_path(model_name: 'team')\n        find('option', text: 'Cheater').double_click\n        is_expected.to have_content \"Edit Player 'Cheater'\"\n        find('#player_name').set('Cheater on steroids')\n        find('#player_number').set('')\n        find('#modal .save-action').click\n        is_expected.to have_css('#modal')\n        is_expected.to have_content 'Player is cheating'\n        is_expected.to have_css '.text-danger', text: 'is not a number'\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/orm/active_record.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/adapters/active_record'\n\nActiveRecord::Base.connection.data_sources.each do |table|\n  ActiveRecord::Base.connection.drop_table(table)\nend\n\ndef silence_stream(stream)\n  old_stream = stream.dup\n  stream.reopen(/mswin|mingw/.match?(RbConfig::CONFIG['host_os']) ? 'NUL:' : '/dev/null')\n  stream.sync = true\n  yield\nensure\n  stream.reopen(old_stream)\n  old_stream.close\nend\n\nsilence_stream($stdout) do\n  if ActiveRecord::Migrator.respond_to? :migrate\n    ActiveRecord::Migrator.migrate File.expand_path('../dummy_app/db/migrate', __dir__)\n  else\n    ActiveRecord::MigrationContext.new(\n      *([File.expand_path('../dummy_app/db/migrate', __dir__)] +\n          (ActiveRecord::MigrationContext.instance_method(:initialize).arity == 2 ? [ActiveRecord::SchemaMigration] : [])),\n    ).migrate\n  end\nend\n\nclass Tableless < ActiveRecord::Base\n  class << self\n    def load_schema\n      # do nothing\n    end\n\n    def columns\n      @columns ||= []\n    end\n\n    def column(name, sql_type = nil, default = nil, null = true)\n      cast_type = connection.send(:lookup_cast_type, sql_type.to_s)\n      define_attribute(name.to_s, cast_type)\n      columns <<\n        if ActiveRecord.version > Gem::Version.new('6.0')\n          type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(\n            sql_type: sql_type.to_s,\n            type: cast_type.type,\n            limit: cast_type.limit,\n            precision: cast_type.precision,\n            scale: cast_type.scale,\n          )\n          ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, type_metadata, null)\n        else\n          ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, cast_type, sql_type.to_s, null)\n        end\n    end\n\n    def columns_hash\n      @columns_hash ||= columns.collect { |column| [column.name, column] }.to_h\n    end\n\n    def column_names\n      @column_names ||= columns.collect(&:name)\n    end\n\n    def column_defaults\n      @column_defaults ||= columns.collect { |column| [column.name, nil] }.each_with_object({}) do |e, a|\n        a[e[0]] = e[1]\n        a\n      end\n    end\n\n    def attribute_types\n      @attribute_types ||=\n        columns.collect { |column| [column.name, lookup_attribute_type(column.type)] }.to_h\n    end\n\n    def table_exists?\n      true\n    end\n\n    def primary_key\n      'id'\n    end\n\n  private\n\n    def lookup_attribute_type(type)\n      ActiveRecord::Type.lookup({datetime: :time}[type] || type)\n    end\n  end\n\n  # Override the save method to prevent exceptions.\n  def save(validate = true)\n    validate ? valid? : true\n  end\nend\n\n##\n# Column length detection seems to be broken for PostgreSQL.\n# This is a workaround..\n# Refs. https://github.com/rails/rails/commit/b404613c977a5cc31c6748723e903fa5a0709c3b\n#\nif defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)\n  ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do\n    def lookup_cast_type(sql_type)\n      oid = execute(\"SELECT #{quote(sql_type)}::regtype::oid\", 'SCHEMA').first['oid'].to_i\n      type_map.lookup(oid, sql_type)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/orm/mongoid.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'rails_admin/adapters/mongoid'\n\nPaperclip.logger = Logger.new(nil)\n\nclass Tableless\n  include Mongoid::Document\n\n  class << self\n    def column(name, sql_type = 'string', default = nil, _null = true)\n      # ignore length\n      sql_type = sql_type.to_s.sub(/\\(.*\\)/, '').to_sym\n      field(name, type: {integer: Integer, string: String, text: String, date: Date, datetime: DateTime}[sql_type], default: default)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/policies.rb",
    "content": "# frozen_string_literal: true\n\nclass ApplicationPolicy\n  attr_reader :user, :record\n\n  def initialize(user, record)\n    @user = user\n    @record = record\n  end\n\n  def show?\n    user.roles.include? :admin\n  end\n\n  def destroy?\n    false\n  end\n\n  def history?\n    user.roles.include? :admin\n  end\n\n  def show_in_app?\n    user.roles.include? :admin\n  end\n\n  def dashboard?\n    user.roles.include? :admin\n  end\n\n  def index?\n    false\n  end\n\n  def new?\n    user.roles.include? :admin\n  end\n  alias create? new?\n\n  def edit?\n    user.roles.include? :admin\n  end\n  alias update? edit?\n\n  def export?\n    user.roles.include? :admin\n  end\n\n  def rails_admin_index?\n    true\n  end\nend\n\nclass PlayerPolicy < ApplicationPolicy\n  def new?\n    (user.roles.include?(:manage_player) ||\n      (user.roles.include?(:create_player) && (!record.is_a?(Player) || record.suspended)))\n  end\n  alias create? new?\n\n  def edit?\n    (user.roles.include?(:manage_player) ||\n      (user.roles.include?(:update_player) && (!record.is_a?(Player) || !record.retired)))\n  end\n  alias update? edit?\n\n  def destroy?\n    (user.roles.include? :manage_player)\n  end\n\n  def index?\n    user.roles.include? :admin\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/abstract_model_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::AbstractModel do\n  describe '.all' do\n    it 'returns abstract models for all models' do\n      expect(RailsAdmin::AbstractModel.all.map(&:model)).to include Player, Team\n    end\n\n    it 'does not pick up a model without table', active_record: true do\n      expect(RailsAdmin::AbstractModel.all.map(&:model)).not_to include WithoutTable\n    end\n  end\n\n  describe '.new' do\n    context 'on ActiveRecord::NoDatabaseError', active_record: true do\n      before do\n        expect(WithoutTable).to receive(:table_exists?).and_raise(ActiveRecord::NoDatabaseError)\n      end\n\n      it 'does not raise error and returns nil' do\n        expect(RailsAdmin::AbstractModel.new('WithoutTable')).to eq nil\n      end\n    end\n\n    context 'on ActiveRecord::ConnectionNotEstablished', active_record: true do\n      before do\n        expect(WithoutTable).to receive(:table_exists?).and_raise(ActiveRecord::ConnectionNotEstablished)\n      end\n\n      it 'does not raise error and returns nil' do\n        expect(RailsAdmin::AbstractModel.new('WithoutTable')).to eq nil\n      end\n    end\n  end\n\n  describe '#to_s' do\n    it 'returns model\\'s name' do\n      expect(RailsAdmin::AbstractModel.new(Cms::BasicPage).to_s).to eq Cms::BasicPage.to_s\n    end\n  end\n\n  describe '#to_param' do\n    it 'turns namespaces into prefixes with ~' do\n      expect(RailsAdmin::AbstractModel.new('Cms::BasicPage').to_param).to eq('cms~basic_page')\n    end\n  end\n\n  describe 'filters' do\n    before do\n      @abstract_model = RailsAdmin::AbstractModel.new('FieldTest')\n    end\n\n    context 'ActiveModel::ForbiddenAttributesProtection' do\n      it 'is present' do\n        @abstract_model.model.ancestors.collect(&:to_s).include?('ActiveModel::ForbiddenAttributesProtection')\n      end\n    end\n\n    context 'on ActiveRecord native enum', active_record: true do\n      shared_examples 'filter on enum' do\n        before do\n          %w[S M L].each do |size|\n            FactoryBot.create(:field_test, string_enum_field: size)\n          end\n\n          %w[small medium large].each do |size|\n            FactoryBot.create(:field_test, integer_enum_field: size)\n          end\n        end\n        let(:model) { RailsAdmin::AbstractModel.new('FieldTest') }\n        let(:filters) { {enum_field => {'1' => {v: filter_value, o: 'is'}}} }\n        subject(:elements) {  model.all(filters: filters) }\n\n        it 'lists elements by value' do\n          expect(elements.count).to eq(expected_elements_count)\n          expect(elements.map(&enum_field.to_sym)).to all(eq(enum_label))\n        end\n      end\n\n      context 'when enum is integer enum' do\n        it_behaves_like 'filter on enum' do\n          let(:filter_value) { 0 }\n          let(:enum_field) { 'integer_enum_field' }\n          let(:enum_label) { 'small' }\n          let(:expected_elements_count) { 1 }\n        end\n      end\n\n      context 'when enum is string enum where label <> value' do\n        it_behaves_like 'filter on enum' do\n          let(:filter_value) { 's' }\n          let(:enum_field) { 'string_enum_field' }\n          let(:enum_label) { 'S' }\n          let(:expected_elements_count) { 1 }\n        end\n      end\n    end\n\n    context 'on dates' do\n      before do\n        [Date.new(2012, 1, 1), Date.new(2012, 1, 2), Date.new(2012, 1, 3), Date.new(2012, 1, 4)].each do |date|\n          FactoryBot.create(:field_test, date_field: date)\n        end\n      end\n\n      it 'lists elements within outbound limits' do\n        expect(@abstract_model.all(filters: {'date_field' => {'1' => {v: ['', '2012-01-02', '2012-01-03'], o: 'between'}}}).count).to eq(2)\n        expect(@abstract_model.all(filters: {'date_field' => {'1' => {v: ['', '2012-01-02', '2012-01-02'], o: 'between'}}}).count).to eq(1)\n        expect(@abstract_model.all(filters: {'date_field' => {'1' => {v: ['', '2012-01-03', ''], o: 'between'}}}).count).to eq(2)\n        expect(@abstract_model.all(filters: {'date_field' => {'1' => {v: ['', '', '2012-01-02'], o: 'between'}}}).count).to eq(2)\n        expect(@abstract_model.all(filters: {'date_field' => {'1' => {v: ['2012-01-02'], o: 'default'}}}).count).to eq(1)\n      end\n    end\n\n    context 'on datetimes' do\n      before do\n        I18n.locale = :en\n        FactoryBot.create(:field_test, datetime_field: Time.zone.local(2012, 1, 1, 23, 59, 59))\n        FactoryBot.create(:field_test, datetime_field: Time.zone.local(2012, 1, 2, 0, 0, 0))\n        FactoryBot.create(:field_test, datetime_field: Time.zone.local(2012, 1, 3, 23, 59, 59))\n        FactoryBot.create(:field_test, datetime_field: Time.zone.local(2012, 1, 4, 0, 0, 0))\n      end\n\n      it 'lists elements within outbound limits' do\n        expect(@abstract_model.all(filters: {'datetime_field' => {'1' => {v: ['', '2012-01-02T00:00:00', '2012-01-03T23:59:59'], o: 'between'}}}).count).to eq(2)\n        expect(@abstract_model.all(filters: {'datetime_field' => {'1' => {v: ['', '2012-01-02T00:00:00', '2012-01-03T12:00:00'], o: 'between'}}}).count).to eq(1)\n        expect(@abstract_model.all(filters: {'datetime_field' => {'1' => {v: ['', '2012-01-03T12:00:00', ''], o: 'between'}}}).count).to eq(2)\n        expect(@abstract_model.all(filters: {'datetime_field' => {'1' => {v: ['', '', '2012-01-02T12:00:00'], o: 'between'}}}).count).to eq(2)\n        expect(@abstract_model.all(filters: {'datetime_field' => {'1' => {v: ['2012-01-02T00:00:00'], o: 'default'}}}).count).to eq(1)\n      end\n    end\n  end\n\n  context 'with Kaminari' do\n    before do\n      @paged = Player.page(1)\n      Kaminari.config.page_method_name = :per_page_kaminari\n      @abstract_model = RailsAdmin::AbstractModel.new('Player')\n    end\n\n    after do\n      Kaminari.config.page_method_name = :page\n    end\n\n    it \"supports pagination when Kaminari's page_method_name is customized\" do\n      expect(Player).to receive(:per_page_kaminari).once.and_return(@paged)\n      @abstract_model.all(sort: PK_COLUMN, page: 1, per: 2)\n    end\n  end\n\n  describe 'each_associated_children' do\n    before do\n      @abstract_model = RailsAdmin::AbstractModel.new('Player')\n      @draft = FactoryBot.build :draft\n      @comments = FactoryBot.build_list :comment, 2\n      @player = FactoryBot.build :player, draft: @draft, comments: @comments\n    end\n\n    it 'should return has_one and has_many associations with its children' do\n      @abstract_model.each_associated_children(@player) do |association, children|\n        expect(children).to eq case association.name\n                               when :draft\n                                 [@draft]\n                               when :comments\n                                 @comments\n                               end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/active_record_extension_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\nrequire File.expand_path('../../config/initializers/active_record_extensions', __dir__)\n\nRSpec.describe 'ActiveRecord::Base', active_record: true do\n  describe '#safe_send' do\n    it 'only calls #read_attribute once' do\n      @player = Player.new\n      @player.number = 23\n      original_method = @player.method(:read_attribute)\n      expect(@player).to receive(:read_attribute).exactly(1).times do |*args|\n        original_method.call(*args)\n      end\n      expect(@player.safe_send(:number)).to eq(23)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/adapters/active_record/association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\nrequire 'timecop'\n\nRSpec.describe 'RailsAdmin::Adapters::ActiveRecord::Association', active_record: true do\n  before :all do\n    RailsAdmin::AbstractModel.reset_polymorphic_parents\n\n    class ARBlog < Tableless\n      has_many :a_r_posts\n      has_many :a_r_comments, as: :commentable\n      belongs_to :librarian, polymorphic: true\n    end\n\n    class ARPost < Tableless\n      belongs_to :a_r_blog\n      has_and_belongs_to_many :a_r_categories\n      has_many :a_r_comments, as: :commentable\n    end\n\n    class ARCategory < Tableless\n      has_and_belongs_to_many :a_r_posts, -> { readonly }\n      has_and_belongs_to_many :scoped_posts, ->(category) { where(id: category.id) }, class_name: 'ARPost'\n      belongs_to :librarian, polymorphic: true\n    end\n\n    class ARUser < Tableless\n      has_one :a_r_profile\n      has_many :a_r_categories, as: :librarian\n    end\n\n    class ARProfile < Tableless\n      belongs_to :a_r_user\n      has_many :a_r_blogs, as: :librarian\n    end\n\n    class ARComment < Tableless\n      belongs_to :commentable, polymorphic: true\n    end\n\n    @blog = RailsAdmin::AbstractModel.new(ARBlog)\n    @post = RailsAdmin::AbstractModel.new(ARPost)\n    @category = RailsAdmin::AbstractModel.new(ARCategory)\n    @user = RailsAdmin::AbstractModel.new(ARUser)\n    @profile = RailsAdmin::AbstractModel.new(ARProfile)\n    @comment = RailsAdmin::AbstractModel.new(ARComment)\n  end\n\n  after :all do\n    RailsAdmin::AbstractModel.reset_polymorphic_parents\n  end\n\n  it 'lists associations' do\n    expect(@post.associations.collect { |a| a.name.to_s }).to include(*%w[a_r_blog a_r_categories a_r_comments])\n  end\n\n  it 'list associations types in supported [:belongs_to, :has_and_belongs_to_many, :has_many, :has_one]' do\n    # ActiveRecord 4.1 converts has_and_belongs_to_many association to has_many\n    expect((@post.associations + @blog.associations + @user.associations).collect(&:type).uniq.collect(&:to_s)).to include(*%w[belongs_to has_many has_one])\n  end\n\n  describe 'belongs_to association' do\n    subject { @post.associations.detect { |a| a.name == :a_r_blog } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'A r blog'\n      expect(subject.type).to eq :belongs_to\n      expect(subject.klass).to eq ARBlog\n      expect(subject.primary_key).to eq :id\n      expect(subject.foreign_key).to eq :a_r_blog_id\n      expect(subject.foreign_type).to be_nil\n      expect(subject.key_accessor).to eq :a_r_blog_id\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n  end\n\n  describe 'has_many association' do\n    subject { @blog.associations.detect { |a| a.name == :a_r_posts } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'A r posts'\n      expect(subject.type).to eq :has_many\n      expect(subject.klass).to eq ARPost\n      expect(subject.primary_key).to eq :id\n      expect(subject.foreign_key).to eq :ar_blog_id\n      expect(subject.foreign_type).to be_nil\n      expect(subject.key_accessor).to eq :a_r_post_ids\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n  end\n\n  describe 'has_many association' do\n    let(:league) { RailsAdmin::AbstractModel.new(League) }\n\n    context 'for direct has many' do\n      let(:association) { league.associations.detect { |a| a.name == :divisions } }\n\n      it 'returns correct values' do\n        expect(association.type).to eq :has_many\n        expect(association.klass).to eq Division\n        expect(association.read_only?).to be_falsey\n        expect(association.foreign_key_nullable?).to be_truthy\n      end\n    end\n\n    context 'for has many through marked as readonly' do\n      let(:association) { league.associations.detect { |a| a.name == :teams } }\n\n      it 'returns correct values' do\n        expect(association.type).to eq :has_many\n        expect(association.klass).to eq Team\n        expect(association.read_only?).to be_truthy\n        expect(association.foreign_key_nullable?).to be_truthy\n      end\n    end\n\n    context 'for has many through multiple associations' do\n      let(:association) { league.associations.detect { |a| a.name == :players } }\n\n      it 'returns correct values' do\n        expect(association.type).to eq :has_many\n        expect(association.klass).to eq Player\n        expect(association.read_only?).to be_truthy\n      end\n    end\n  end\n\n  describe 'has_many association with not nullable foreign key' do\n    let(:field_test) { RailsAdmin::AbstractModel.new(FieldTest) }\n    let(:association) { field_test.associations.detect { |a| a.name == :nested_field_tests } }\n\n    context 'for direct has many' do\n      it 'returns correct values' do\n        expect(association.foreign_key_nullable?).to be_falsey\n      end\n    end\n\n    context 'when foreign_key is passed as Symbol' do\n      before do\n        class FieldTestWithSymbolForeignKey < FieldTest\n          has_many :nested_field_tests, dependent: :destroy, inverse_of: :field_test, foreign_key: :field_test_id\n        end\n      end\n      let(:field_test) { RailsAdmin::AbstractModel.new(FieldTestWithSymbolForeignKey) }\n\n      it 'does not break' do\n        expect(association.foreign_key_nullable?).to be_falsey\n      end\n    end\n  end\n\n  describe 'has_and_belongs_to_many association' do\n    subject { @post.associations.detect { |a| a.name == :a_r_categories } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'A r categories'\n      expect(subject.klass).to eq ARCategory\n      expect(subject.primary_key).to eq :id\n      expect(subject.foreign_type).to be_nil\n      expect(subject.foreign_key_nullable?).to be_truthy\n      expect(subject.key_accessor).to eq :a_r_category_ids\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n\n    context 'with a scope given' do\n      subject { @category.associations.detect { |a| a.name == :a_r_posts } }\n\n      it 'does not break' do\n        expect(subject.read_only?).to be_truthy\n      end\n    end\n\n    context 'with a scope that receives an argument given' do\n      subject { @category.associations.detect { |a| a.name == :scoped_posts } }\n\n      it 'ignores the scope' do\n        expect(subject.read_only?).to be_falsey\n      end\n    end\n  end\n\n  describe 'polymorphic belongs_to association' do\n    before { allow(RailsAdmin::Config).to receive(:models_pool).and_return(%w[ARBlog ARPost ARCategory ARUser ARProfile ARComment]) }\n    subject { @comment.associations.detect { |a| a.name == :commentable } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Commentable'\n      expect(subject.type).to eq :belongs_to\n      expect(subject.klass).to eq [ARBlog, ARPost]\n      expect(subject.primary_key).to be_nil\n      expect(subject.foreign_key).to eq :commentable_id\n      expect(subject.foreign_type).to eq :commentable_type\n      expect(subject.key_accessor).to eq :commentable_id\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_truthy\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n\n    it 'looks up correct inverse model' do\n      expect(@category.associations.detect { |a| a.name == :librarian }.klass).to eq [ARUser]\n      expect(@blog.associations.detect { |a| a.name == :librarian }.klass).to eq [ARProfile]\n    end\n\n    describe 'on a subclass' do\n      before do\n        class ARReview < ARComment; end\n        allow(RailsAdmin::Config).to receive(:models_pool).and_return(%w[ARBlog ARPost ARCategory ARUser ARProfile ARComment ARReview])\n      end\n      subject { RailsAdmin::AbstractModel.new(ARReview).associations.detect { |a| a.name == :commentable } }\n\n      it 'returns correct target klasses' do\n        expect(subject.klass).to eq [ARBlog, ARPost]\n      end\n    end\n  end\n\n  describe 'polymorphic inverse has_many association' do\n    subject { @blog.associations.detect { |a| a.name == :a_r_comments } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'A r comments'\n      expect(subject.type).to eq :has_many\n      expect(subject.klass).to eq ARComment\n      expect(subject.primary_key).to eq :id\n      expect(subject.foreign_key).to eq :commentable_id\n      expect(subject.foreign_type).to be_nil\n      expect(subject.key_accessor).to eq :a_r_comment_ids\n      expect(subject.as).to eq :commentable\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/adapters/active_record/object_extension_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin::Adapters::ActiveRecord::ObjectExtension', active_record: true do\n  describe '#assign_attributes' do\n    let(:player) { Player.new }\n    let(:object) { player.extend RailsAdmin::Adapters::ActiveRecord::ObjectExtension }\n\n    it 'does not cause error with nil' do\n      expect(object.assign_attributes(nil)).to be nil\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/adapters/active_record/property_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\nrequire 'timecop'\n\nRSpec.describe 'RailsAdmin::Adapters::ActiveRecord::Property', active_record: true do\n  describe 'string field' do\n    subject { RailsAdmin::AbstractModel.new('Player').properties.detect { |f| f.name == :name } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Name'\n      expect(subject.type).to eq :string\n      expect(subject.length).to eq 100\n      expect(subject.nullable?).to be_falsey\n      expect(subject.serial?).to be_falsey\n    end\n  end\n\n  describe 'serialized field' do\n    subject { RailsAdmin::AbstractModel.new('User').properties.detect { |f| f.name == :roles } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Roles'\n      expect(subject.type).to eq :serialized\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n    end\n  end\n\n  describe '#read_only?' do\n    before do\n      class HasReadOnlyColumn < Tableless\n        column :name, :varchar\n        attr_readonly :name\n      end\n    end\n\n    it 'returns correct values' do\n      expect(RailsAdmin::AbstractModel.new('Player').properties.detect { |f| f.name == :name }).not_to be_read_only\n      expect(RailsAdmin::AbstractModel.new('HasReadOnlyColumn').properties.detect { |f| f.name == :name }).to be_read_only\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/adapters/active_record_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\nrequire 'timecop'\n\nRSpec.describe 'RailsAdmin::Adapters::ActiveRecord', active_record: true do\n  let(:activerecord_config) do\n    if ::ActiveRecord::Base.respond_to? :connection_db_config\n      ::ActiveRecord::Base.connection_db_config.configuration_hash\n    else\n      ::ActiveRecord::Base.connection_config\n    end\n  end\n  let(:like) do\n    if %w[postgresql postgis].include? activerecord_config[:adapter]\n      '(field ILIKE ?)'\n    else\n      '(LOWER(field) LIKE ?)'\n    end\n  end\n  let(:not_like) do\n    if %w[postgresql postgis].include? activerecord_config[:adapter]\n      '(field NOT ILIKE ?)'\n    else\n      '(LOWER(field) NOT LIKE ?)'\n    end\n  end\n\n  def predicates_for(scope)\n    scope.where_clause.instance_variable_get(:@predicates)\n    #          .map do |predicate|\n    #       if predicate.is_a? Arel::Nodes::BoundSqlLiteral\n    #         binds = predicate.positional_binds\n    #         predicate.sql_with_placeholders.delete_prefix('(').delete_suffix(')').gsub('?') do |_|\n    #           bind = binds.shift\n    #           case bind\n    #           when Date\n    #             \"'#{bind.to_fs(:db)}'\"\n    #           when DateTime, Time\n    #             \"'#{bind.to_fs(:db)}'\"\n    #           else\n    #             p bind\n    #             bind.to_s\n    #           end\n    #         end\n    #       else\n    #         predicate\n    #       end\n    #          end\n  end\n\n  describe '#associations' do\n    it 'returns Association class' do\n      expect(RailsAdmin::AbstractModel.new(Player).associations.first).\n        to be_a_kind_of RailsAdmin::Adapters::ActiveRecord::Association\n    end\n  end\n\n  describe '#properties' do\n    it 'returns Property class' do\n      expect(RailsAdmin::AbstractModel.new(Player).properties.first).\n        to be_a_kind_of RailsAdmin::Adapters::ActiveRecord::Property\n    end\n  end\n\n  describe '#base_class' do\n    it 'returns inheritance base class' do\n      expect(RailsAdmin::AbstractModel.new(Hardball).base_class).to eq Ball\n    end\n  end\n\n  describe 'data access methods' do\n    let(:abstract_model) { RailsAdmin::AbstractModel.new('Player') }\n\n    before do\n      @players = FactoryBot.create_list(:player, 3) + [\n        # Multibyte players\n        FactoryBot.create(:player, name: 'Антоха'),\n        FactoryBot.create(:player, name: 'Петруха'),\n      ]\n    end\n\n    it '#new returns an ActiveRecord instance' do\n      expect(abstract_model.new).to be_a(ActiveRecord::Base)\n    end\n\n    it '#get returns an ActiveRecord instance' do\n      expect(abstract_model.get(@players.first.id)).to eq(@players.first)\n    end\n\n    it '#get returns nil when id does not exist' do\n      expect(abstract_model.get('abc')).to be_nil\n    end\n\n    it '#get returns an object that can be passed to ActiveJob' do\n      expect { NullJob.perform_later(abstract_model.get(@players.first.id)) }.not_to raise_error\n    end\n\n    it '#first returns a player' do\n      expect(@players).to include abstract_model.first\n    end\n\n    describe '#count' do\n      it 'returns count of items' do\n        expect(abstract_model.count).to eq(@players.count)\n      end\n\n      context 'when default-scoped with select' do\n        before do\n          class PlayerWithDefaultScope < Player\n            self.table_name = 'players'\n            default_scope { select(:id, :name) }\n          end\n        end\n        let(:abstract_model) { RailsAdmin::AbstractModel.new('PlayerWithDefaultScope') }\n\n        it 'does not break' do\n          expect(abstract_model.count).to eq(@players.count)\n        end\n      end\n    end\n\n    it '#destroy destroys multiple items' do\n      abstract_model.destroy(@players[0..1])\n      expect(Player.all).to match_array(@players[2..])\n    end\n\n    it '#where returns filtered results' do\n      expect(abstract_model.where(name: @players.first.name)).to eq([@players.first])\n    end\n\n    describe '#all' do\n      it 'works without options' do\n        expect(abstract_model.all).to match_array @players\n      end\n\n      it 'supports eager loading' do\n        expect(abstract_model.all(include: :team).includes_values).to eq([:team])\n      end\n\n      it 'supports limiting' do\n        expect(abstract_model.all(limit: 2).size).to eq(2)\n      end\n\n      it 'supports retrieval by bulk_ids' do\n        expect(abstract_model.all(bulk_ids: @players[0..1].collect(&:id))).to match_array @players[0..1]\n      end\n\n      it 'supports retrieval by bulk_ids with composite primary keys', composite_primary_keys: true do\n        expect(RailsAdmin::AbstractModel.new(Fanship).all(\n          bulk_ids: %w[1_2 3_4],\n        ).to_sql.tr('`', '\"')).to include 'WHERE (\"fans_teams\".\"fan_id\" = 1 AND \"fans_teams\".\"team_id\" = 2 OR \"fans_teams\".\"fan_id\" = 3 AND \"fans_teams\".\"team_id\" = 4)'\n      end\n\n      it 'supports pagination' do\n        expect(abstract_model.all(sort: 'id', page: 2, per: 1)).to eq(@players[-2, 1])\n        expect(abstract_model.all(sort: 'id', page: 1, per: 2)).to eq(@players[-2, 2].reverse)\n      end\n\n      it 'supports ordering' do\n        expect(abstract_model.all(sort: 'id', sort_reverse: true)).to eq(@players.sort)\n        expect(abstract_model.all(sort: %w[id name], sort_reverse: true).to_sql.tr('`', '\"')).to include('ORDER BY \"players\".\"id\" ASC, \"players\".\"name\" ASC')\n        expect(abstract_model.all(include: :team, sort: {players: :name, teams: :name}, sort_reverse: true).to_sql.tr('`', '\"')).to include('ORDER BY \"players\".\"name\" ASC, \"teams\".\"name\" ASC')\n        expect { abstract_model.all(sort: 1, sort_reverse: true) }.to raise_error ArgumentError, /Unsupported/\n      end\n\n      it 'supports querying' do\n        results = abstract_model.all(query: @players[1].name)\n        expect(results).to eq(@players[1..1])\n      end\n\n      it 'supports multibyte querying' do\n        unless activerecord_config[:adapter] == 'sqlite3'\n          results = abstract_model.all(query: @players[4].name)\n          expect(results).to eq(@players[4, 1])\n        end\n      end\n\n      it 'supports filtering' do\n        expect(abstract_model.all(filters: {'name' => {'0000' => {o: 'is', v: @players[1].name}}})).to eq(@players[1..1])\n      end\n    end\n  end\n\n  describe '#query_scope' do\n    let(:abstract_model) { RailsAdmin::AbstractModel.new('Team') }\n\n    before do\n      @teams = [{}, {name: 'somewhere foos'}, {manager: 'foo junior'}].\n               collect { |h| FactoryBot.create :team, h }\n    end\n\n    it 'makes correct query' do\n      expect(abstract_model.all(query: 'foo')).to match_array @teams[1..2]\n    end\n\n    context \"when field's searchable_columns is empty\" do\n      before do\n        RailsAdmin.config do |c|\n          c.model Team do\n            field :players\n          end\n        end\n      end\n\n      it 'does not break' do\n        expect { abstract_model.all(query: 'foo') }.not_to raise_error\n      end\n    end\n\n    context 'when parsing is not idempotent' do\n      before do\n        RailsAdmin.config do |c|\n          c.model Team do\n            field :name do\n              def parse_value(value)\n                \"#{value}s\"\n              end\n            end\n          end\n        end\n      end\n\n      it 'parses value only once' do\n        expect(abstract_model.all(query: 'foo')).to match_array @teams[1]\n      end\n    end\n  end\n\n  describe '#filter_scope' do\n    let(:abstract_model) { RailsAdmin::AbstractModel.new('Team') }\n\n    before do\n      @division = FactoryBot.create :division, name: 'bar division'\n      @teams = [{}, {division: @division}, {name: 'somewhere foos', division: @division}, {name: 'nowhere foos'}].\n               collect { |h| FactoryBot.create :team, h }\n    end\n\n    context 'without configuration' do\n      before do\n        allow(Rails.configuration).to receive(:database_configuration) { nil }\n      end\n\n      after do\n        allow(Rails.configuration).to receive(:database_configuration).and_call_original\n      end\n\n      it 'does not raise error' do\n        expect { abstract_model.all(filters: {'name' => {'0000' => {o: 'like', v: 'foo'}}}) }.to_not raise_error\n      end\n    end\n\n    it 'makes correct query' do\n      expect(abstract_model.all(filters: {'name' => {'0000' => {o: 'like', v: 'foo'}}, 'division' => {'0001' => {o: 'like', v: 'bar'}}}, include: :division)).to eq([@teams[2]])\n    end\n\n    context 'when parsing is not idempotent' do\n      before do\n        RailsAdmin.config do |c|\n          c.model Team do\n            field :name do\n              def parse_value(value)\n                \"some#{value}\"\n              end\n            end\n          end\n        end\n      end\n\n      it 'parses value only once' do\n        expect(abstract_model.all(filters: {'name' => {'0000' => {o: 'like', v: 'where'}}})).to match_array @teams[2]\n      end\n    end\n\n    context 'when a default_search_operator is set' do\n      before do\n        RailsAdmin.config do |c|\n          c.default_search_operator = 'starts_with'\n        end\n      end\n\n      it 'only matches on prefix' do\n        # Specified operator is honored and matches\n        expect(abstract_model.all(filters: {'name' => {'0000' => {o: 'like', v: 'where'}}})).to match_array @teams[2..3]\n\n        # No operator falls back to the default_search_operator(starts_with) and doesn't match NON-PREFIX\n        expect(abstract_model.all(filters: {'name' => {'0000' => {v: 'where'}}})).to be_empty\n\n        # No operator falls back to the default_search_operator(starts_with) and doesn't match NON-PREFIX\n        expect(abstract_model.all(filters: {'name' => {'0000' => {v: 'somewhere'}}})).to match_array @teams[2]\n      end\n    end\n  end\n\n  describe '#build_statement' do\n    let(:abstract_model) { RailsAdmin::AbstractModel.new('FieldTest') }\n\n    def build_statement(type, value, operator)\n      abstract_model.send(:build_statement, :field, type, value, operator)\n    end\n\n    it \"ignores '_discard' operator or value\" do\n      [['_discard', ''], ['', '_discard']].each do |value, operator|\n        expect(build_statement(:string, value, operator)).to be_nil\n      end\n    end\n\n    describe 'string type queries' do\n      it 'supports string type query' do\n        expect(build_statement(:string, '', nil)).to be_nil\n        expect(build_statement(:string, 'foo', 'was')).to be_nil\n        expect(build_statement(:string, 'foo', 'default')).to eq([like, '%foo%'])\n        expect(build_statement(:string, 'foo', 'like')).to eq([like, '%foo%'])\n        expect(build_statement(:string, 'foo', 'not_like')).to eq([not_like, '%foo%'])\n        expect(build_statement(:string, 'foo', 'starts_with')).to eq([like, 'foo%'])\n        expect(build_statement(:string, 'foo', 'ends_with')).to eq([like, '%foo'])\n        expect(build_statement(:string, 'foo', 'is')).to eq(['(field = ?)', 'foo'])\n      end\n\n      it 'performs case-insensitive searches' do\n        unless %w[postgresql postgis].include?(activerecord_config[:adapter])\n          expect(build_statement(:string, 'foo', 'default')).to eq([like, '%foo%'])\n          expect(build_statement(:string, 'FOO', 'default')).to eq([like, '%foo%'])\n        end\n      end\n\n      it 'chooses like statement in per-model basis' do\n        allow(FieldTest.connection).to receive(:adapter_name).and_return('postgresql')\n        expect(build_statement(:string, 'foo', 'default')).to eq(['(field ILIKE ?)', '%foo%'])\n        allow(FieldTest.connection).to receive(:adapter_name).and_return('sqlite3')\n        expect(build_statement(:string, 'foo', 'default')).to eq(['(LOWER(field) LIKE ?)', '%foo%'])\n      end\n\n      it \"supports '_blank' operator\" do\n        [['_blank', ''], ['', '_blank']].each do |value, operator|\n          expect(build_statement(:string, value, operator)).to eq([\"(field IS NULL OR field = '')\"])\n        end\n      end\n\n      it \"supports '_present' operator\" do\n        [['_present', ''], ['', '_present']].each do |value, operator|\n          expect(build_statement(:string, value, operator)).to eq([\"(field IS NOT NULL AND field != '')\"])\n        end\n      end\n\n      it \"supports '_null' operator\" do\n        [['_null', ''], ['', '_null']].each do |value, operator|\n          expect(build_statement(:string, value, operator)).to eq(['(field IS NULL)'])\n        end\n      end\n\n      it \"supports '_not_null' operator\" do\n        [['_not_null', ''], ['', '_not_null']].each do |value, operator|\n          expect(build_statement(:string, value, operator)).to eq(['(field IS NOT NULL)'])\n        end\n      end\n\n      it \"supports '_empty' operator\" do\n        [['_empty', ''], ['', '_empty']].each do |value, operator|\n          expect(build_statement(:string, value, operator)).to eq([\"(field = '')\"])\n        end\n      end\n\n      it \"supports '_not_empty' operator\" do\n        [['_not_empty', ''], ['', '_not_empty']].each do |value, operator|\n          expect(build_statement(:string, value, operator)).to eq([\"(field != '')\"])\n        end\n      end\n    end\n\n    describe 'boolean type queries' do\n      it 'supports boolean type query' do\n        %w[false f 0].each do |value|\n          expect(build_statement(:boolean, value, nil)).to eq(['(field IS NULL OR field = ?)', false])\n        end\n        %w[true t 1].each do |value|\n          expect(build_statement(:boolean, value, nil)).to eq(['(field = ?)', true])\n        end\n        expect(build_statement(:boolean, 'word', nil)).to be_nil\n      end\n\n      it \"supports '_blank' operator\" do\n        [['_blank', ''], ['', '_blank']].each do |value, operator|\n          expect(build_statement(:boolean, value, operator)).to eq(['(field IS NULL)'])\n        end\n      end\n\n      it \"supports '_present' operator\" do\n        [['_present', ''], ['', '_present']].each do |value, operator|\n          expect(build_statement(:boolean, value, operator)).to eq(['(field IS NOT NULL)'])\n        end\n      end\n\n      it \"supports '_null' operator\" do\n        [['_null', ''], ['', '_null']].each do |value, operator|\n          expect(build_statement(:boolean, value, operator)).to eq(['(field IS NULL)'])\n        end\n      end\n\n      it \"supports '_not_null' operator\" do\n        [['_not_null', ''], ['', '_not_null']].each do |value, operator|\n          expect(build_statement(:boolean, value, operator)).to eq(['(field IS NOT NULL)'])\n        end\n      end\n\n      it \"supports '_empty' operator\" do\n        [['_empty', ''], ['', '_empty']].each do |value, operator|\n          expect(build_statement(:boolean, value, operator)).to eq(['(field IS NULL)'])\n        end\n      end\n\n      it \"supports '_not_empty' operator\" do\n        [['_not_empty', ''], ['', '_not_empty']].each do |value, operator|\n          expect(build_statement(:boolean, value, operator)).to eq(['(field IS NOT NULL)'])\n        end\n      end\n    end\n\n    describe 'numeric type queries' do\n      it 'supports integer type query' do\n        expect(build_statement(:integer, '1', nil)).to eq(['(field = ?)', 1])\n        expect(build_statement(:integer, 'word', nil)).to be_nil\n        expect(build_statement(:integer, '1', 'default')).to eq(['(field = ?)', 1])\n        expect(build_statement(:integer, 'word', 'default')).to be_nil\n        expect(build_statement(:integer, '1', 'between')).to eq(['(field = ?)', 1])\n        expect(build_statement(:integer, 'word', 'between')).to be_nil\n        expect(build_statement(:integer, ['6', '', ''], 'default')).to eq(['(field = ?)', 6])\n        expect(build_statement(:integer, ['7', '10', ''], 'default')).to eq(['(field = ?)', 7])\n        expect(build_statement(:integer, ['8', '', '20'], 'default')).to eq(['(field = ?)', 8])\n        expect(build_statement(:integer, %w[9 10 20], 'default')).to eq(['(field = ?)', 9])\n      end\n\n      it 'supports integer type range query' do\n        expect(build_statement(:integer, ['', '', ''], 'between')).to be_nil\n        expect(build_statement(:integer, ['2', '', ''], 'between')).to be_nil\n        expect(build_statement(:integer, ['', '3', ''], 'between')).to eq(['(field >= ?)', 3])\n        expect(build_statement(:integer, ['', '', '5'], 'between')).to eq(['(field <= ?)', 5])\n        expect(build_statement(:integer, ['', '10', '20'], 'between')).to eq(['(field BETWEEN ? AND ?)', 10, 20])\n        expect(build_statement(:integer, %w[15 10 20], 'between')).to eq(['(field BETWEEN ? AND ?)', 10, 20])\n        expect(build_statement(:integer, ['', 'word1', ''], 'between')).to be_nil\n        expect(build_statement(:integer, ['', '', 'word2'], 'between')).to be_nil\n        expect(build_statement(:integer, ['', 'word3', 'word4'], 'between')).to be_nil\n      end\n\n      it 'supports both decimal and float type queries' do\n        expect(build_statement(:decimal, '1.1', nil)).to eq(['(field = ?)', 1.1])\n        expect(build_statement(:decimal, 'word', nil)).to be_nil\n        expect(build_statement(:decimal, '1.1', 'default')).to eq(['(field = ?)', 1.1])\n        expect(build_statement(:decimal, 'word', 'default')).to be_nil\n        expect(build_statement(:decimal, '1.1', 'between')).to eq(['(field = ?)', 1.1])\n        expect(build_statement(:decimal, 'word', 'between')).to be_nil\n        expect(build_statement(:decimal, ['6.1', '', ''], 'default')).to eq(['(field = ?)', 6.1])\n        expect(build_statement(:decimal, ['7.1', '10.1', ''], 'default')).to eq(['(field = ?)', 7.1])\n        expect(build_statement(:decimal, ['8.1', '', '20.1'], 'default')).to eq(['(field = ?)', 8.1])\n        expect(build_statement(:decimal, ['9.1', '10.1', '20.1'], 'default')).to eq(['(field = ?)', 9.1])\n        expect(build_statement(:decimal, ['', '', ''], 'between')).to be_nil\n        expect(build_statement(:decimal, ['2.1', '', ''], 'between')).to be_nil\n        expect(build_statement(:decimal, ['', '3.1', ''], 'between')).to eq(['(field >= ?)', 3.1])\n        expect(build_statement(:decimal, ['', '', '5.1'], 'between')).to eq(['(field <= ?)', 5.1])\n        expect(build_statement(:decimal, ['', '10.1', '20.1'], 'between')).to eq(['(field BETWEEN ? AND ?)', 10.1, 20.1])\n        expect(build_statement(:decimal, ['15.1', '10.1', '20.1'], 'between')).to eq(['(field BETWEEN ? AND ?)', 10.1, 20.1])\n        expect(build_statement(:decimal, ['', 'word1', ''], 'between')).to be_nil\n        expect(build_statement(:decimal, ['', '', 'word2'], 'between')).to be_nil\n        expect(build_statement(:decimal, ['', 'word3', 'word4'], 'between')).to be_nil\n\n        expect(build_statement(:float, '1.1', nil)).to eq(['(field = ?)', 1.1])\n        expect(build_statement(:float, 'word', nil)).to be_nil\n        expect(build_statement(:float, '1.1', 'default')).to eq(['(field = ?)', 1.1])\n        expect(build_statement(:float, 'word', 'default')).to be_nil\n        expect(build_statement(:float, '1.1', 'between')).to eq(['(field = ?)', 1.1])\n        expect(build_statement(:float, 'word', 'between')).to be_nil\n        expect(build_statement(:float, ['6.1', '', ''], 'default')).to eq(['(field = ?)', 6.1])\n        expect(build_statement(:float, ['7.1', '10.1', ''], 'default')).to eq(['(field = ?)', 7.1])\n        expect(build_statement(:float, ['8.1', '', '20.1'], 'default')).to eq(['(field = ?)', 8.1])\n        expect(build_statement(:float, ['9.1', '10.1', '20.1'], 'default')).to eq(['(field = ?)', 9.1])\n        expect(build_statement(:float, ['', '', ''], 'between')).to be_nil\n        expect(build_statement(:float, ['2.1', '', ''], 'between')).to be_nil\n        expect(build_statement(:float, ['', '3.1', ''], 'between')).to eq(['(field >= ?)', 3.1])\n        expect(build_statement(:float, ['', '', '5.1'], 'between')).to eq(['(field <= ?)', 5.1])\n        expect(build_statement(:float, ['', '10.1', '20.1'], 'between')).to eq(['(field BETWEEN ? AND ?)', 10.1, 20.1])\n        expect(build_statement(:float, ['15.1', '10.1', '20.1'], 'between')).to eq(['(field BETWEEN ? AND ?)', 10.1, 20.1])\n        expect(build_statement(:float, ['', 'word1', ''], 'between')).to be_nil\n        expect(build_statement(:float, ['', '', 'word2'], 'between')).to be_nil\n        expect(build_statement(:float, ['', 'word3', 'word4'], 'between')).to be_nil\n      end\n\n      it \"supports '_blank' operator\" do\n        [['_blank', ''], ['', '_blank']].each do |value, operator|\n          aggregate_failures do\n            expect(build_statement(:integer, value, operator)).to eq(['(field IS NULL)'])\n            expect(build_statement(:decimal, value, operator)).to eq(['(field IS NULL)'])\n            expect(build_statement(:float, value, operator)).to eq(['(field IS NULL)'])\n          end\n        end\n      end\n\n      it \"supports '_present' operator\" do\n        [['_present', ''], ['', '_present']].each do |value, operator|\n          aggregate_failures do\n            expect(build_statement(:integer, value, operator)).to eq(['(field IS NOT NULL)'])\n            expect(build_statement(:decimal, value, operator)).to eq(['(field IS NOT NULL)'])\n            expect(build_statement(:float, value, operator)).to eq(['(field IS NOT NULL)'])\n          end\n        end\n      end\n\n      it \"supports '_null' operator\" do\n        [['_null', ''], ['', '_null']].each do |value, operator|\n          aggregate_failures do\n            expect(build_statement(:integer, value, operator)).to eq(['(field IS NULL)'])\n            expect(build_statement(:decimal, value, operator)).to eq(['(field IS NULL)'])\n            expect(build_statement(:float, value, operator)).to eq(['(field IS NULL)'])\n          end\n        end\n      end\n\n      it \"supports '_not_null' operator\" do\n        [['_not_null', ''], ['', '_not_null']].each do |value, operator|\n          aggregate_failures do\n            expect(build_statement(:integer, value, operator)).to eq(['(field IS NOT NULL)'])\n            expect(build_statement(:decimal, value, operator)).to eq(['(field IS NOT NULL)'])\n            expect(build_statement(:float, value, operator)).to eq(['(field IS NOT NULL)'])\n          end\n        end\n      end\n\n      it \"supports '_empty' operator\" do\n        [['_empty', ''], ['', '_empty']].each do |value, operator|\n          aggregate_failures do\n            expect(build_statement(:integer, value, operator)).to eq(['(field IS NULL)'])\n            expect(build_statement(:decimal, value, operator)).to eq(['(field IS NULL)'])\n            expect(build_statement(:float, value, operator)).to eq(['(field IS NULL)'])\n          end\n        end\n      end\n\n      it \"supports '_not_empty' operator\" do\n        [['_not_empty', ''], ['', '_not_empty']].each do |value, operator|\n          aggregate_failures do\n            expect(build_statement(:integer, value, operator)).to eq(['(field IS NOT NULL)'])\n            expect(build_statement(:decimal, value, operator)).to eq(['(field IS NOT NULL)'])\n            expect(build_statement(:float, value, operator)).to eq(['(field IS NOT NULL)'])\n          end\n        end\n      end\n    end\n\n    describe 'date/time type queries' do\n      let(:scope) { FieldTest.all }\n\n      it 'supports date type query' do\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'date_field' => {'1' => {v: ['', '2012-02-01', '2012-03-01'], o: 'between'}}))).to eq(predicates_for(scope.where('(field_tests.date_field BETWEEN ? AND ?)', Date.new(2012, 2, 1), Date.new(2012, 3, 1))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'date_field' => {'1' => {v: ['', '2012-03-01', ''], o: 'between'}}))).to eq(predicates_for(scope.where('(field_tests.date_field >= ?)', Date.new(2012, 3, 1))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'date_field' => {'1' => {v: ['', '', '2012-02-01'], o: 'between'}}))).to eq(predicates_for(scope.where('(field_tests.date_field <= ?)', Date.new(2012, 2, 1))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'date_field' => {'1' => {v: ['2012-02-01'], o: 'default'}}))).to eq(predicates_for(scope.where('(field_tests.date_field = ?)', Date.new(2012, 2, 1))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'date_field' => {'1' => {v: [], o: 'today'}}))).to eq(predicates_for(scope.where('(field_tests.date_field = ?)', Date.today)))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'date_field' => {'1' => {v: [], o: 'yesterday'}}))).to eq(predicates_for(scope.where('(field_tests.date_field = ?)', Date.yesterday)))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'date_field' => {'1' => {v: [], o: 'this_week'}}))).to eq(predicates_for(scope.where('(field_tests.date_field BETWEEN ? AND ?)', Date.today.beginning_of_week, Date.today.end_of_week)))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'date_field' => {'1' => {v: [], o: 'last_week'}}))).to eq(predicates_for(scope.where('(field_tests.date_field BETWEEN ? AND ?)', 1.week.ago.to_date.beginning_of_week, 1.week.ago.to_date.end_of_week)))\n      end\n\n      it 'supports datetime type query' do\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'datetime_field' => {'1' => {v: ['', '2012-02-01T12:00:00', '2012-03-01T12:00:00'], o: 'between'}}))).to eq(predicates_for(scope.where('(field_tests.datetime_field BETWEEN ? AND ?)', Time.utc(2012, 2, 1, 12), Time.utc(2012, 3, 1, 12))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'datetime_field' => {'1' => {v: ['', '2012-03-01T12:00:00', ''], o: 'between'}}))).to eq(predicates_for(scope.where('(field_tests.datetime_field >= ?)', Time.utc(2012, 3, 1, 12))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'datetime_field' => {'1' => {v: ['', '', '2012-02-01T12:00:00'], o: 'between'}}))).to eq(predicates_for(scope.where('(field_tests.datetime_field <= ?)', Time.utc(2012, 2, 1, 12))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'datetime_field' => {'1' => {v: ['2012-02-01T12:00:00'], o: 'default'}}))).to eq(predicates_for(scope.where('(field_tests.datetime_field = ?)', Time.utc(2012, 2, 1, 12))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'datetime_field' => {'1' => {v: [], o: 'today'}}))).to eq(predicates_for(scope.where('(field_tests.datetime_field BETWEEN ? AND ?)', Date.today.beginning_of_day, Date.today.end_of_day)))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'datetime_field' => {'1' => {v: [], o: 'yesterday'}}))).to eq(predicates_for(scope.where('(field_tests.datetime_field BETWEEN ? AND ?)', Date.yesterday.beginning_of_day, Date.yesterday.end_of_day)))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'datetime_field' => {'1' => {v: [], o: 'this_week'}}))).to eq(predicates_for(scope.where('(field_tests.datetime_field BETWEEN ? AND ?)', Date.today.beginning_of_week.beginning_of_day, Date.today.end_of_week.end_of_day)))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'datetime_field' => {'1' => {v: [], o: 'last_week'}}))).to eq(predicates_for(scope.where('(field_tests.datetime_field BETWEEN ? AND ?)', 1.week.ago.beginning_of_week, 1.week.ago.end_of_week)))\n      end\n\n      it 'supports time type query' do\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'time_field' => {'1' => {v: ['', '2000-01-01T12:00:00', '2000-01-01T14:00:00'], o: 'between'}}))).to eq(predicates_for(scope.where('(field_tests.time_field BETWEEN ? AND ?)', Time.utc(2000, 1, 1, 12), Time.utc(2000, 1, 1, 14))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'time_field' => {'1' => {v: ['', '2000-01-01T14:00:00', ''], o: 'between'}}))).to eq(predicates_for(scope.where('(field_tests.time_field >= ?)', Time.utc(2000, 1, 1, 14))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'time_field' => {'1' => {v: ['', '', '2000-01-01T12:00:00'], o: 'between'}}))).to eq(predicates_for(scope.where('(field_tests.time_field <= ?)', Time.utc(2000, 1, 1, 12))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'time_field' => {'1' => {v: ['2000-01-01T12:00:00'], o: 'default'}}))).to eq(predicates_for(scope.where('(field_tests.time_field = ?)', Time.utc(2000, 1, 1, 12))))\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'time_field' => {'1' => {v: ['2021-02-03T12:00:00'], o: 'default'}}))).to eq(predicates_for(scope.where('(field_tests.time_field = ?)', Time.utc(2000, 1, 1, 12))))\n      end\n    end\n\n    it 'supports enum type query' do\n      expect(build_statement(:enum, '1', nil)).to eq(['(field IN (?))', ['1']])\n    end\n\n    describe 'with ActiveRecord native enum' do\n      let(:scope) { FieldTest.all }\n\n      it 'supports integer enum type query' do\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'integer_enum_field' => {'1' => {v: 2, o: 'default'}}))).to eq(predicates_for(scope.where('(field_tests.integer_enum_field IN (?))', [2])))\n      end\n\n      it 'supports string enum type query' do\n        expect(predicates_for(abstract_model.send(:filter_scope, scope, 'string_enum_field' => {'1' => {v: 'm', o: 'default'}}))).to eq(predicates_for(scope.where('(field_tests.string_enum_field IN (?))', ['m'])))\n      end\n    end\n\n    describe 'uuid type queries' do\n      it 'supports uuid type query' do\n        uuid = SecureRandom.uuid\n        expect(build_statement(:uuid, uuid, nil)).to eq(['(field = ?)', uuid])\n      end\n\n      it \"supports '_blank' operator\" do\n        [['_blank', ''], ['', '_blank']].each do |value, operator|\n          expect(build_statement(:uuid, value, operator)).to eq(['(field IS NULL)'])\n        end\n      end\n\n      it \"supports '_present' operator\" do\n        [['_present', ''], ['', '_present']].each do |value, operator|\n          expect(build_statement(:uuid, value, operator)).to eq(['(field IS NOT NULL)'])\n        end\n      end\n\n      it \"supports '_null' operator\" do\n        [['_null', ''], ['', '_null']].each do |value, operator|\n          expect(build_statement(:uuid, value, operator)).to eq(['(field IS NULL)'])\n        end\n      end\n\n      it \"supports '_not_null' operator\" do\n        [['_not_null', ''], ['', '_not_null']].each do |value, operator|\n          expect(build_statement(:uuid, value, operator)).to eq(['(field IS NOT NULL)'])\n        end\n      end\n\n      it \"supports '_empty' operator\" do\n        [['_empty', ''], ['', '_empty']].each do |value, operator|\n          expect(build_statement(:uuid, value, operator)).to eq(['(field IS NULL)'])\n        end\n      end\n\n      it \"supports '_not_empty' operator\" do\n        [['_not_empty', ''], ['', '_not_empty']].each do |value, operator|\n          expect(build_statement(:uuid, value, operator)).to eq(['(field IS NOT NULL)'])\n        end\n      end\n    end\n  end\n\n  describe 'model attribute method' do\n    let(:abstract_model) { RailsAdmin::AbstractModel.new('Player') }\n\n    it '#scoped returns relation object' do\n      expect(abstract_model.scoped).to be_a_kind_of(ActiveRecord::Relation)\n    end\n\n    it '#table_name works' do\n      expect(abstract_model.table_name).to eq('players')\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/adapters/mongoid/association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin::Adapters::Mongoid::Association', mongoid: true do\n  before :all do\n    RailsAdmin::AbstractModel.reset_polymorphic_parents\n\n    class MongoBlog\n      include Mongoid::Document\n      has_many :mongo_posts\n      has_many :mongo_comments, as: :commentable\n      belongs_to :librarian, polymorphic: true\n      field :mongo_blog_id\n    end\n\n    class MongoPost\n      include Mongoid::Document\n      belongs_to :mongo_blog\n      has_and_belongs_to_many :mongo_categories\n      has_many :mongo_comments, as: :commentable\n      embeds_one :mongo_note\n      accepts_nested_attributes_for :mongo_note\n    end\n\n    class MongoCategory\n      include Mongoid::Document\n      has_and_belongs_to_many :mongo_posts\n      belongs_to :librarian, polymorphic: true\n    end\n\n    class MongoUser\n      include Mongoid::Document\n      has_one :mongo_profile\n      has_many :mongo_categories, as: :librarian\n\n      embeds_many :mongo_notes\n      accepts_nested_attributes_for :mongo_notes\n      field :name, type: String\n      field :message, type: String\n      field :short_text, type: String\n\n      validates :short_text, length: {maximum: 255}\n    end\n\n    class MongoProfile\n      include Mongoid::Document\n      belongs_to :mongo_user\n      has_many :mongo_blogs, as: :librarian\n    end\n\n    class MongoComment\n      include Mongoid::Document\n      belongs_to :commentable, polymorphic: true\n    end\n\n    class MongoNote\n      include Mongoid::Document\n      embedded_in :mongo_post\n      embedded_in :mongo_user\n    end\n\n    @blog     = RailsAdmin::AbstractModel.new MongoBlog\n    @post     = RailsAdmin::AbstractModel.new MongoPost\n    @category = RailsAdmin::AbstractModel.new MongoCategory\n    @user     = RailsAdmin::AbstractModel.new MongoUser\n    @profile  = RailsAdmin::AbstractModel.new MongoProfile\n    @comment  = RailsAdmin::AbstractModel.new MongoComment\n  end\n\n  after :all do\n    RailsAdmin::AbstractModel.reset_polymorphic_parents\n  end\n\n  it 'lists associations' do\n    expect(@post.associations.collect { |a| a.name.to_sym }).to match_array %i[mongo_blog mongo_categories mongo_comments mongo_note]\n  end\n\n  it 'reads correct and know types in [:belongs_to, :has_and_belongs_to_many, :has_many, :has_one]' do\n    expect((@post.associations + @blog.associations + @user.associations).collect { |a| a.type.to_s }.uniq).to match_array %w[belongs_to has_and_belongs_to_many has_many has_one]\n  end\n\n  describe 'belongs_to association' do\n    subject { @post.associations.detect { |a| a.name == :mongo_blog } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Mongo blog'\n      expect(subject.type).to eq :belongs_to\n      expect(subject.klass).to eq MongoBlog\n      expect(subject.primary_key).to eq :_id\n      expect(subject.foreign_key).to eq :mongo_blog_id\n      expect(subject.foreign_key_nullable?).to be_truthy\n      expect(subject.foreign_type).to be_nil\n      expect(subject.foreign_inverse_of).to be_nil\n      expect(subject.key_accessor).to eq :mongo_blog_id\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n\n    it 'distinguishes foreign_key column' do\n      expect(@post.properties.detect { |f| f.name == :mongo_blog_id }.type).to eq(:bson_object_id)\n      expect(@blog.properties.detect { |f| f.name == :mongo_blog_id }.type).to eq(:string)\n    end\n  end\n\n  describe 'has_many association' do\n    subject { @blog.associations.detect { |a| a.name == :mongo_posts } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Mongo posts'\n      expect(subject.type).to eq :has_many\n      expect(subject.klass).to eq MongoPost\n      expect(subject.primary_key).to eq :_id\n      expect(subject.foreign_key).to eq :mongo_blog_id\n      expect(subject.foreign_key_nullable?).to be_truthy\n      expect(subject.foreign_type).to be_nil\n      expect(subject.foreign_inverse_of).to be_nil\n      expect(subject.key_accessor).to eq :mongo_post_ids\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n  end\n\n  describe 'has_and_belongs_to_many association' do\n    subject { @post.associations.detect { |a| a.name == :mongo_categories } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Mongo categories'\n      expect(subject.type).to eq :has_and_belongs_to_many\n      expect(subject.klass).to eq MongoCategory\n      expect(subject.primary_key).to eq :_id\n      expect(subject.foreign_key).to eq :mongo_category_ids\n      expect(subject.foreign_key_nullable?).to be_truthy\n      expect(subject.foreign_type).to be_nil\n      expect(subject.foreign_inverse_of).to be_nil\n      expect(subject.key_accessor).to eq :mongo_category_ids\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n  end\n\n  describe 'polymorphic belongs_to association' do\n    before { allow(RailsAdmin::Config).to receive(:models_pool).and_return(%w[MongoBlog MongoPost MongoCategory MongoUser MongoProfile MongoComment]) }\n    subject { @comment.associations.detect { |a| a.name == :commentable } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Commentable'\n      expect(subject.type).to eq :belongs_to\n      expect(subject.klass).to eq [MongoBlog, MongoPost]\n      expect(subject.primary_key).to eq :_id\n      expect(subject.foreign_key).to eq :commentable_id\n      expect(subject.foreign_key_nullable?).to be_truthy\n      expect(subject.foreign_type).to eq :commentable_type\n      expect(subject.foreign_inverse_of).to be_nil\n      expect(subject.key_accessor).to eq :commentable_id\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_truthy\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n\n    describe 'on a subclass' do\n      before do\n        class MongoReview < MongoComment; end\n        allow(RailsAdmin::Config).to receive(:models_pool).and_return(%w[MongoBlog MongoPost MongoCategory MongoUser MongoProfile MongoComment MongoReview])\n      end\n      subject { RailsAdmin::AbstractModel.new(MongoReview).associations.detect { |a| a.name == :commentable } }\n\n      it 'returns correct target klasses' do\n        expect(subject.klass).to eq [MongoBlog, MongoPost]\n      end\n    end\n  end\n\n  describe 'polymorphic inverse has_many association' do\n    before { allow(RailsAdmin::Config).to receive(:models_pool).and_return(%w[MongoBlog MongoPost MongoCategory MongoUser MongoProfile MongoComment]) }\n    subject { @blog.associations.detect { |a| a.name == :mongo_comments } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Mongo comments'\n      expect(subject.type).to eq :has_many\n      expect(subject.klass).to eq MongoComment\n      expect(subject.primary_key).to eq :_id\n      expect(subject.foreign_key).to eq :commentable_id\n      expect(subject.foreign_key_nullable?).to be_truthy\n      expect(subject.foreign_type).to be_nil\n      expect(subject.foreign_inverse_of).to be_nil\n      expect(subject.key_accessor).to eq :mongo_comment_ids\n      expect(subject.as).to eq :commentable\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to be_nil\n    end\n\n    it 'looks up correct inverse model' do\n      expect(@category.associations.detect { |a| a.name == :librarian }.klass).to eq [MongoUser]\n      expect(@blog.associations.detect { |a| a.name == :librarian }.klass).to eq [MongoProfile]\n    end\n  end\n\n  describe 'embeds_one association' do\n    subject { @post.associations.detect { |a| a.name == :mongo_note } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Mongo note'\n      expect(subject.type).to eq :has_one\n      expect(subject.klass).to eq MongoNote\n      expect(subject.primary_key).to eq :_id\n      expect(subject.foreign_key).to be_nil\n      expect(subject.foreign_key_nullable?).to be_falsey\n      expect(subject.foreign_type).to be_nil\n      expect(subject.foreign_inverse_of).to be_nil\n      expect(subject.key_accessor).to be_nil\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to eq(allow_destroy: false, update_only: false)\n    end\n  end\n\n  describe 'embeds_many association' do\n    subject { @user.associations.detect { |a| a.name == :mongo_notes } }\n\n    it 'returns correct values' do\n      expect(subject.pretty_name).to eq 'Mongo notes'\n      expect(subject.type).to eq :has_many\n      expect(subject.klass).to eq MongoNote\n      expect(subject.primary_key).to eq :_id\n      expect(subject.foreign_key).to be_nil\n      expect(subject.foreign_key_nullable?).to be_falsey\n      expect(subject.foreign_type).to be_nil\n      expect(subject.key_accessor).to be_nil\n      expect(subject.as).to be_nil\n      expect(subject.polymorphic?).to be_falsey\n      expect(subject.inverse_of).to be_nil\n      expect(subject.read_only?).to be_falsey\n      expect(subject.nested_options).to eq(allow_destroy: false, update_only: false)\n    end\n\n    it 'raises error when embeds_* is used without accepts_nested_attributes_for' do\n      class MongoEmbedsOne\n        include Mongoid::Document\n        embeds_one :mongo_embedded\n      end\n\n      class MongoEmbedsMany\n        include Mongoid::Document\n        embeds_many :mongo_embeddeds\n      end\n\n      class MongoEmbedded\n        include Mongoid::Document\n        embedded_in :mongo_embeds_one\n        embedded_in :mongo_embeds_many\n      end\n\n      class MongoRecursivelyEmbedsOne\n        include Mongoid::Document\n        recursively_embeds_one\n      end\n\n      class MongoRecursivelyEmbedsMany\n        include Mongoid::Document\n        recursively_embeds_many\n      end\n\n      expect { RailsAdmin::AbstractModel.new(MongoEmbedsOne).associations.first.nested_options }.to raise_error(RuntimeError, \"Embedded association without accepts_nested_attributes_for can't be handled by RailsAdmin,\\nbecause embedded model doesn't have top-level access.\\nPlease add `accepts_nested_attributes_for :mongo_embedded' line to `MongoEmbedsOne' model.\\n\")\n      expect { RailsAdmin::AbstractModel.new(MongoEmbedsMany).associations.first.nested_options }.to raise_error(RuntimeError, \"Embedded association without accepts_nested_attributes_for can't be handled by RailsAdmin,\\nbecause embedded model doesn't have top-level access.\\nPlease add `accepts_nested_attributes_for :mongo_embeddeds' line to `MongoEmbedsMany' model.\\n\")\n      expect { RailsAdmin::AbstractModel.new(MongoRecursivelyEmbedsOne).associations.first.nested_options }.not_to raise_error\n      expect { RailsAdmin::AbstractModel.new(MongoRecursivelyEmbedsMany).associations.first.nested_options }.not_to raise_error\n    end\n\n    it 'works with inherited embeds_many model' do\n      class MongoEmbedsParent\n        include Mongoid::Document\n        embeds_many :mongo_embeddeds\n        accepts_nested_attributes_for :mongo_embeddeds\n      end\n\n      class MongoEmbedded\n        include Mongoid::Document\n        embedded_in :mongo_embeds_many\n      end\n\n      class MongoEmbedsChild < MongoEmbedsParent; end\n\n      expect { RailsAdmin::AbstractModel.new(MongoEmbedsChild).associations }.not_to raise_error\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/adapters/mongoid/object_extension_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin::Adapters::Mongoid::ObjectExtension', mongoid: true do\n  describe 'has_many association' do\n    let(:players) { FactoryBot.create_list :player, 2 }\n    before do\n      class TeamWithAutoSave < Team\n        has_many :players, inverse_of: :team, autosave: true\n      end\n    end\n\n    context 'on create' do\n      before do\n        team.player_ids = players.collect(&:id)\n        team.players.each { |player| expect(player).to receive(:save).once.and_call_original }\n        team.save\n      end\n\n      context 'with autosave: false' do\n        let(:team) { FactoryBot.build(:team).extend(RailsAdmin::Adapters::Mongoid::ObjectExtension) }\n\n        it 'persists associated documents changes on save' do\n          expect(team.reload.players).to match_array players\n        end\n      end\n\n      context 'with autosave: true' do\n        let(:team) { TeamWithAutoSave.new(FactoryBot.attributes_for(:team)).extend(RailsAdmin::Adapters::Mongoid::ObjectExtension) }\n\n        it 'persists associated documents changes on save' do\n          expect(team.reload.players).to match_array players\n        end\n      end\n    end\n\n    context 'on update' do\n      let(:team) { FactoryBot.create(:team).extend(RailsAdmin::Adapters::Mongoid::ObjectExtension) }\n      before do\n        team.player_ids = players.collect(&:id)\n      end\n\n      context 'with autosave: false' do\n        let(:team) { FactoryBot.create(:team).extend(RailsAdmin::Adapters::Mongoid::ObjectExtension) }\n\n        it 'persists associated documents changes on assignment' do\n          expect(team.reload.players).to match_array players\n        end\n      end\n\n      context 'with autosave: true' do\n        let(:team) { TeamWithAutoSave.create(FactoryBot.attributes_for(:team)).extend(RailsAdmin::Adapters::Mongoid::ObjectExtension) }\n\n        it 'persists associated documents changes on assignment' do\n          expect(team.reload.players).to match_array players\n        end\n      end\n    end\n  end\n\n  describe 'has_one association' do\n    let(:draft) { FactoryBot.create(:draft) }\n    before do\n      class PlayerWithAutoSave < Player\n        has_one :draft, inverse_of: :player, autosave: true\n      end\n    end\n\n    context 'on create' do\n      before do\n        player.draft = draft\n        expect(player.draft._target).to receive(:save).once.and_call_original\n        player.save\n      end\n\n      context 'with autosave: false' do\n        let(:player) { FactoryBot.build(:player).extend(RailsAdmin::Adapters::Mongoid::ObjectExtension) }\n\n        it 'persists associated documents changes on save' do\n          expect(player.reload.draft).to eq draft\n        end\n      end\n\n      context 'with autosave: true' do\n        let(:player) { PlayerWithAutoSave.new(FactoryBot.attributes_for(:player)).extend(RailsAdmin::Adapters::Mongoid::ObjectExtension) }\n\n        it 'persists associated documents changes on save' do\n          expect(player.reload.draft).to eq draft\n        end\n      end\n    end\n\n    context 'on update' do\n      before do\n        player.draft = draft\n      end\n\n      context 'with autosave: false' do\n        let(:player) { FactoryBot.create(:player).extend(RailsAdmin::Adapters::Mongoid::ObjectExtension) }\n\n        it 'persists associated documents changes on assignment' do\n          expect(player.reload.draft).to eq draft\n        end\n      end\n\n      context 'with autosave: true' do\n        let(:player) { PlayerWithAutoSave.create(FactoryBot.attributes_for(:player)).extend(RailsAdmin::Adapters::Mongoid::ObjectExtension) }\n\n        it 'persists associated documents changes on assignment' do\n          expect(player.reload.draft).to eq draft\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/adapters/mongoid/property_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin::Adapters::Mongoid::Property', mongoid: true do\n  subject { RailsAdmin::AbstractModel.new(FieldTest).properties.detect { |p| p.name == field } }\n\n  describe '_id field' do\n    let(:field) { :_id }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq ' id'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_truthy\n      expect(subject.type).to eq :bson_object_id\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'array field' do\n    let(:field) { :array_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Array field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :serialized\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'big decimal field' do\n    let(:field) { :big_decimal_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Big decimal field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :decimal\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'boolean field' do\n    let(:field) { :boolean_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Boolean field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :boolean\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'bson object id field' do\n    let(:field) { :bson_object_id_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Bson object id field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :bson_object_id\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'date field' do\n    let(:field) { :date_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Date field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :date\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'datetime field' do\n    let(:field) { :datetime_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Datetime field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :datetime\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'time with zone field' do\n    let(:field) { :time_with_zone_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Time with zone field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :datetime\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'default field' do\n    let(:field) { :default_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Default field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :string\n      expect(subject.length).to eq 255\n    end\n  end\n\n  describe 'float field' do\n    let(:field) { :float_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Float field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :float\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'hash field' do\n    let(:field) { :hash_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Hash field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :serialized\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'integer field' do\n    let(:field) { :integer_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Integer field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :integer\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'object field' do\n    let(:field) { :object_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Object field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :string\n      expect(subject.length).to eq 255\n    end\n  end\n\n  describe 'string field' do\n    let(:field) { :string_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'String field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :text\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'symbol field' do\n    let(:field) { :symbol_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Symbol field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :string\n      expect(subject.length).to eq 255\n    end\n  end\n\n  describe 'time field' do\n    let(:field) { :time_field }\n\n    it 'has correct values' do\n      expect(subject.pretty_name).to eq 'Time field'\n      expect(subject.nullable?).to be_truthy\n      expect(subject.serial?).to be_falsey\n      expect(subject.type).to eq :datetime\n      expect(subject.length).to be_nil\n    end\n  end\n\n  describe 'aliased field' do\n    let(:field) { :aliased_field }\n\n    it 'has correct values' do\n      expect(subject.name).to eq :aliased_field\n      expect(subject.pretty_name).to eq 'Aliased field'\n    end\n  end\n\n  describe '#length_validation_lookup' do\n    it 'detects validation length properly' do\n      class LengthValiated\n        include Mongoid::Document\n        field :text, type: String\n        validates :text, length: {maximum: 50}\n      end\n      expect(RailsAdmin::AbstractModel.new('LengthValiated').properties.last.send(:length_validation_lookup)).to eq(50)\n    end\n\n    it 'does not cause problem with custom validators' do\n      class MyCustomValidator < ActiveModel::Validator\n        def validate(_r); end\n      end\n\n      class CustomValiated\n        include Mongoid::Document\n        field :text, type: String\n        validates_with MyCustomValidator\n      end\n      expect { RailsAdmin::AbstractModel.new('CustomValiated').properties.last.send(:length_validation_lookup) }.not_to raise_error\n    end\n  end\n\n  describe '#read_only?' do\n    before do\n      class HasReadOnlyColumn\n        include Mongoid::Document\n        field :name, type: String\n        attr_readonly :name\n      end\n    end\n\n    it 'returns correct values' do\n      expect(RailsAdmin::AbstractModel.new('Player').properties.detect { |f| f.name == :name }).not_to be_read_only\n      expect(RailsAdmin::AbstractModel.new('HasReadOnlyColumn').properties.detect { |f| f.name == :name }).to be_read_only\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/adapters/mongoid_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin::Adapters::Mongoid', mongoid: true do\n  describe '#associations' do\n    it 'returns Association class' do\n      expect(RailsAdmin::AbstractModel.new(Player).associations.first).\n        to be_a_kind_of RailsAdmin::Adapters::Mongoid::Association\n    end\n  end\n\n  describe '#properties' do\n    it 'returns Property class' do\n      expect(RailsAdmin::AbstractModel.new(Player).properties.first).\n        to be_a_kind_of RailsAdmin::Adapters::Mongoid::Property\n    end\n  end\n\n  describe '#base_class' do\n    it 'returns inheritance base class' do\n      expect(RailsAdmin::AbstractModel.new(Hardball).base_class).to eq Ball\n    end\n  end\n\n  describe 'data access methods' do\n    before do\n      @players = FactoryBot.create_list(:player, 3)\n      @abstract_model = RailsAdmin::AbstractModel.new('Player')\n    end\n\n    it '#new returns a Mongoid::Document instance' do\n      expect(@abstract_model.new).to be_a(Mongoid::Document)\n    end\n\n    it '#get returns a Mongoid::Document instance' do\n      expect(@abstract_model.get(@players.first.id.to_s)).to eq(@players.first)\n    end\n\n    it '#get returns nil when id does not exist' do\n      expect(@abstract_model.get('4f4f0824dcf2315093000000')).to be_nil\n    end\n\n    context 'when Mongoid.raise_not_found_error is false' do\n      before { allow(Mongoid).to receive(:raise_not_found_error).and_return(false) }\n\n      it '#get returns nil when id does not exist' do\n        expect(@abstract_model.get('4f4f0824dcf2315093000000')).to be_nil\n      end\n    end\n\n    it '#first returns a player' do\n      expect(@players).to include @abstract_model.first\n    end\n\n    it '#count returns count of items' do\n      expect(@abstract_model.count).to eq(@players.count)\n    end\n\n    it '#destroy destroys multiple items' do\n      @abstract_model.destroy(@players[0..1])\n      expect(Player.all).to eq(@players[2..2])\n    end\n\n    it '#where returns filtered results' do\n      expect(@abstract_model.where(name: @players.first.name).to_a).to eq([@players.first])\n    end\n\n    describe '#all' do\n      it 'works without options' do\n        expect(@abstract_model.all.to_a).to match_array @players\n      end\n\n      it 'supports eager loading' do\n        expect(@abstract_model.all(include: :team).inclusions.collect(&:class_name)).to eq(['Team'])\n      end\n\n      it 'supports limiting' do\n        expect(@abstract_model.all(limit: 2).to_a.size).to eq(2)\n      end\n\n      it 'supports retrieval by bulk_ids' do\n        expect(@abstract_model.all(bulk_ids: @players[0..1].collect { |player| player.id.to_s }).to_a).to match_array @players[0..1]\n      end\n\n      it 'supports pagination' do\n        expect(@abstract_model.all(sort: 'players._id', page: 2, per: 1).to_a).to eq(@players.sort_by(&:_id)[1..1])\n        # To prevent RSpec matcher to call Mongoid::Criteria#== method,\n        # (we want to test equality of query result, not of Mongoid criteria)\n        # to_a is added to invoke Mongoid query\n      end\n\n      it 'supports ordering' do\n        expect(@abstract_model.all(sort: 'players._id', sort_reverse: true).to_a).to eq(@players.sort)\n        expect(@abstract_model.all(sort: 'players._id', sort_reverse: false).to_a).to eq(@players.sort.reverse)\n      end\n\n      it 'supports querying' do\n        expect(@abstract_model.all(query: @players[1].name)).to eq(@players[1..1])\n      end\n\n      it 'supports filtering' do\n        expect(@abstract_model.all(filters: {'name' => {'0000' => {o: 'is', v: @players[1].name}}})).to eq(@players[1..1])\n      end\n\n      it 'ignores non-existent field name on filtering' do\n        expect { @abstract_model.all(filters: {'dummy' => {'0000' => {o: 'is', v: @players[1].name}}}) }.not_to raise_error\n      end\n    end\n  end\n\n  describe 'searching on association' do\n    describe 'whose type is belongs_to' do\n      before do\n        RailsAdmin.config Player do\n          field :team do\n            queryable true\n          end\n        end\n        @players = FactoryBot.create_list(:player, 3)\n        @team = FactoryBot.create :team, name: 'foobar'\n        @team.players << @players[1]\n        @abstract_model = RailsAdmin::AbstractModel.new('Player')\n      end\n\n      it 'supports querying' do\n        expect(@abstract_model.all(query: 'foobar').to_a).to eq(@players[1..1])\n      end\n\n      it 'supports filtering' do\n        expect(@abstract_model.all(filters: {'team' => {'0000' => {o: 'is', v: 'foobar'}}}).to_a).to eq(@players[1..1])\n      end\n    end\n\n    describe 'whose type is has_many' do\n      before do\n        RailsAdmin.config Team do\n          field :players do\n            queryable true\n            searchable :name\n          end\n        end\n        @teams = FactoryBot.create_list(:team, 3)\n        @players = [{team: @teams[1]},\n                    {team: @teams[1], name: 'foobar'},\n                    {team: @teams[2]}].collect { |h| FactoryBot.create :player, h }\n        @abstract_model = RailsAdmin::AbstractModel.new('Team')\n      end\n\n      it 'supports querying' do\n        expect(@abstract_model.all(query: 'foobar').to_a).to eq(@teams[1..1])\n      end\n\n      it 'supports filtering' do\n        expect(@abstract_model.all(filters: {'players' => {'0000' => {o: 'is', v: 'foobar'}}}).to_a).to eq(@teams[1..1])\n      end\n    end\n\n    describe 'whose type is has_and_belongs_to_many' do\n      before do\n        RailsAdmin.config Team do\n          field :fans do\n            queryable true\n            searchable :name\n          end\n        end\n        @teams = FactoryBot.create_list(:team, 3)\n        @fans = [{}, {name: 'foobar'}, {}].collect { |h| FactoryBot.create :fan, h }\n        @teams[1].fans = [@fans[0], @fans[1]]\n        @teams[2].fans << @fans[2]\n        @abstract_model = RailsAdmin::AbstractModel.new('Team')\n      end\n\n      it 'supports querying' do\n        expect(@abstract_model.all(query: 'foobar').to_a).to eq(@teams[1..1])\n      end\n\n      it 'supports filtering' do\n        expect(@abstract_model.all(filters: {'fans' => {'0000' => {o: 'is', v: 'foobar'}}}).to_a).to eq(@teams[1..1])\n      end\n    end\n\n    describe 'whose type is embedded has_many' do\n      before do\n        RailsAdmin.config FieldTest do\n          field :embeds do\n            queryable true\n            searchable :all\n          end\n        end\n        @field_tests = FactoryBot.create_list(:field_test, 3)\n        @field_tests[0].embeds.create name: 'foo'\n        @field_tests[1].embeds.create name: 'bar'\n        @abstract_model = RailsAdmin::AbstractModel.new('FieldTest')\n      end\n\n      it 'supports querying' do\n        expect(@abstract_model.all(query: 'bar').to_a).to eq(@field_tests[1..1])\n      end\n\n      it 'supports filtering' do\n        expect(@abstract_model.all(filters: {'embeds' => {'0000' => {o: 'is', v: 'bar'}}}).to_a).to eq(@field_tests[1..1])\n      end\n    end\n  end\n\n  describe '#query_scope' do\n    before do\n      @abstract_model = RailsAdmin::AbstractModel.new('Player')\n      @players = [{}, {name: 'Many foos'}, {position: 'foo shortage'}].\n                 collect { |h| FactoryBot.create :player, h }\n    end\n\n    it 'makes correct query' do\n      expect(@abstract_model.all(query: 'foo').to_a).to match_array @players[1..2]\n    end\n\n    context 'when parsing is not idempotent' do\n      before do\n        RailsAdmin.config do |c|\n          c.model Player do\n            field :name do\n              def parse_value(value)\n                \"#{value}s\"\n              end\n            end\n          end\n        end\n      end\n\n      it 'parses value only once' do\n        expect(@abstract_model.all(query: 'foo')).to match_array @players[1..1]\n      end\n    end\n  end\n\n  describe '#filter_scope' do\n    before do\n      @abstract_model = RailsAdmin::AbstractModel.new('Player')\n      @team = FactoryBot.create :team, name: 'king of bar'\n      @players = [{}, {team: @team}, {name: 'Many foos', team: @team}, {name: 'Great foo'}].\n                 collect { |h| FactoryBot.create :player, h }\n    end\n\n    it 'makes correct query' do\n      expect(@abstract_model.all(filters: {'name' => {'0000' => {o: 'like', v: 'foo'}}, 'team' => {'0001' => {o: 'like', v: 'bar'}}})).to eq([@players[2]])\n    end\n\n    context 'when parsing is not idempotent' do\n      before do\n        RailsAdmin.config do |c|\n          c.model Player do\n            field :name do\n              def parse_value(value)\n                \"#{value}s\"\n              end\n            end\n          end\n        end\n      end\n\n      it 'parses value only once' do\n        expect(@abstract_model.all(filters: {'name' => {'0000' => {o: 'like', v: 'foo'}}})).to match_array @players[2]\n      end\n    end\n  end\n\n  describe '#build_statement' do\n    before do\n      I18n.locale = :en\n      @abstract_model = RailsAdmin::AbstractModel.new('FieldTest')\n    end\n\n    it \"ignores '_discard' operator or value\" do\n      [['_discard', ''], ['', '_discard']].each do |value, operator|\n        expect(@abstract_model.send(:build_statement, :name, :string, value, operator)).to be_nil\n      end\n    end\n\n    it \"supports '_blank' operator\" do\n      [['_blank', ''], ['', '_blank']].each do |value, operator|\n        expect(@abstract_model.send(:build_statement, :name, :string, value, operator)).to eq(name: {'$in' => [nil, '']})\n      end\n    end\n\n    it \"supports '_present' operator\" do\n      [['_present', ''], ['', '_present']].each do |value, operator|\n        expect(@abstract_model.send(:build_statement, :name, :string, value, operator)).to eq(name: {'$nin' => [nil, '']})\n      end\n    end\n\n    it \"supports '_null' operator\" do\n      [['_null', ''], ['', '_null']].each do |value, operator|\n        expect(@abstract_model.send(:build_statement, :name, :string, value, operator)).to eq(name: nil)\n      end\n    end\n\n    it \"supports '_not_null' operator\" do\n      [['_not_null', ''], ['', '_not_null']].each do |value, operator|\n        expect(@abstract_model.send(:build_statement, :name, :string, value, operator)).to eq(name: {'$ne' => nil})\n      end\n    end\n\n    it \"supports '_empty' operator\" do\n      [['_empty', ''], ['', '_empty']].each do |value, operator|\n        expect(@abstract_model.send(:build_statement, :name, :string, value, operator)).to eq(name: '')\n      end\n    end\n\n    it \"supports '_not_empty' operator\" do\n      [['_not_empty', ''], ['', '_not_empty']].each do |value, operator|\n        expect(@abstract_model.send(:build_statement, :name, :string, value, operator)).to eq(name: {'$ne' => ''})\n      end\n    end\n\n    it 'supports boolean type query' do\n      %w[false f 0].each do |value|\n        expect(@abstract_model.send(:build_statement, :field, :boolean, value, nil)).to eq(field: false)\n      end\n      %w[true t 1].each do |value|\n        expect(@abstract_model.send(:build_statement, :field, :boolean, value, nil)).to eq(field: true)\n      end\n      expect(@abstract_model.send(:build_statement, :field, :boolean, 'word', nil)).to be_nil\n    end\n\n    it 'supports integer type query' do\n      expect(@abstract_model.send(:build_statement, :field, :integer, '1', nil)).to eq(field: 1)\n      expect(@abstract_model.send(:build_statement, :field, :integer, 'word', nil)).to be_nil\n    end\n\n    it 'supports integer type range query' do\n      expect(@abstract_model.send(:build_statement, :field, :integer, ['', '', ''], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :integer, ['2', '', ''], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :integer, ['', '3', ''], 'between')).to eq(field: {'$gte' => 3})\n      expect(@abstract_model.send(:build_statement, :field, :integer, ['', '', '5'], 'between')).to eq(field: {'$lte' => 5})\n      expect(@abstract_model.send(:build_statement, :field, :integer, ['', '10', '20'], 'between')).to eq(field: {'$gte' => 10, '$lte' => 20})\n      expect(@abstract_model.send(:build_statement, :field, :integer, %w[15 10 20], 'between')).to eq(field: {'$gte' => 10, '$lte' => 20})\n      expect(@abstract_model.send(:build_statement, :field, :integer, ['', 'word1', ''], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :integer, ['', '', 'word2'], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :integer, ['', 'word3', 'word4'], 'between')).to be_nil\n    end\n\n    it 'supports both decimal and float type queries' do\n      expect(@abstract_model.send(:build_statement, :field, :decimal, '1.1', nil)).to eq(field: 1.1)\n      expect(@abstract_model.send(:build_statement, :field, :decimal, 'word', nil)).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :decimal, '1.1', 'default')).to eq(field: 1.1)\n      expect(@abstract_model.send(:build_statement, :field, :decimal, 'word', 'default')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :decimal, '1.1', 'between')).to eq(field: 1.1)\n      expect(@abstract_model.send(:build_statement, :field, :decimal, 'word', 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['6.1', '', ''], 'default')).to eq(field: 6.1)\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['7.1', '10.1', ''], 'default')).to eq(field: 7.1)\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['8.1', '', '20.1'], 'default')).to eq(field: 8.1)\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['9.1', '10.1', '20.1'], 'default')).to eq(field: 9.1)\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['', '', ''], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['2.1', '', ''], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['', '3.1', ''], 'between')).to eq(field: {'$gte' => 3.1})\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['', '', '5.1'], 'between')).to eq(field: {'$lte' => 5.1})\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['', '10.1', '20.1'], 'between')).to eq(field: {'$gte' => 10.1, '$lte' => 20.1})\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['15.1', '10.1', '20.1'], 'between')).to eq(field: {'$gte' => 10.1, '$lte' => 20.1})\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['', 'word1', ''], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['', '', 'word2'], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :decimal, ['', 'word3', 'word4'], 'between')).to be_nil\n\n      expect(@abstract_model.send(:build_statement, :field, :float, '1.1', nil)).to eq(field: 1.1)\n      expect(@abstract_model.send(:build_statement, :field, :float, 'word', nil)).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :float, '1.1', 'default')).to eq(field: 1.1)\n      expect(@abstract_model.send(:build_statement, :field, :float, 'word', 'default')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :float, '1.1', 'between')).to eq(field: 1.1)\n      expect(@abstract_model.send(:build_statement, :field, :float, 'word', 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :float, ['6.1', '', ''], 'default')).to eq(field: 6.1)\n      expect(@abstract_model.send(:build_statement, :field, :float, ['7.1', '10.1', ''], 'default')).to eq(field: 7.1)\n      expect(@abstract_model.send(:build_statement, :field, :float, ['8.1', '', '20.1'], 'default')).to eq(field: 8.1)\n      expect(@abstract_model.send(:build_statement, :field, :float, ['9.1', '10.1', '20.1'], 'default')).to eq(field: 9.1)\n      expect(@abstract_model.send(:build_statement, :field, :float, ['', '', ''], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :float, ['2.1', '', ''], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :float, ['', '3.1', ''], 'between')).to eq(field: {'$gte' => 3.1})\n      expect(@abstract_model.send(:build_statement, :field, :float, ['', '', '5.1'], 'between')).to eq(field: {'$lte' => 5.1})\n      expect(@abstract_model.send(:build_statement, :field, :float, ['', '10.1', '20.1'], 'between')).to eq(field: {'$gte' => 10.1, '$lte' => 20.1})\n      expect(@abstract_model.send(:build_statement, :field, :float, ['15.1', '10.1', '20.1'], 'between')).to eq(field: {'$gte' => 10.1, '$lte' => 20.1})\n      expect(@abstract_model.send(:build_statement, :field, :float, ['', 'word1', ''], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :float, ['', '', 'word2'], 'between')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :float, ['', 'word3', 'word4'], 'between')).to be_nil\n    end\n\n    it 'supports string type query' do\n      expect(@abstract_model.send(:build_statement, :field, :string, '', nil)).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :string, 'foo', 'was')).to be_nil\n      expect(@abstract_model.send(:build_statement, :field, :string, 'foo', 'default')).to eq(field: /foo/i)\n      expect(@abstract_model.send(:build_statement, :field, :string, 'foo', 'like')).to eq(field: /foo/i)\n      expect(@abstract_model.send(:build_statement, :field, :string, 'foo', 'not_like')).to eq(field: /^((?!foo).)*$/i)\n      expect(@abstract_model.send(:build_statement, :field, :string, 'foo', 'starts_with')).to eq(field: /^foo/i)\n      expect(@abstract_model.send(:build_statement, :field, :string, 'foo', 'ends_with')).to eq(field: /foo$/i)\n      expect(@abstract_model.send(:build_statement, :field, :string, 'foo', 'is')).to eq(field: 'foo')\n    end\n\n    it 'supports date type query' do\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'date_field' => {'1' => {v: ['', '2012-01-02', '2012-01-03'], o: 'between'}}).selector).to eq('$and' => [{'date_field' => {'$gte' => Date.new(2012, 1, 2), '$lte' => Date.new(2012, 1, 3)}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'date_field' => {'1' => {v: ['', '2012-01-03', ''], o: 'between'}}).selector).to eq('$and' => [{'date_field' => {'$gte' => Date.new(2012, 1, 3)}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'date_field' => {'1' => {v: ['', '', '2012-01-02'], o: 'between'}}).selector).to eq('$and' => [{'date_field' => {'$lte' => Date.new(2012, 1, 2)}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'date_field' => {'1' => {v: ['2012-01-02'], o: 'default'}}).selector).to eq('$and' => [{'date_field' => Date.new(2012, 1, 2)}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'date_field' => {'1' => {v: [], o: 'today'}}).selector).to eq('$and' => [{'date_field' => Date.today}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'date_field' => {'1' => {v: [], o: 'yesterday'}}).selector).to eq('$and' => [{'date_field' => Date.yesterday}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'date_field' => {'1' => {v: [], o: 'this_week'}}).selector).to eq('$and' => [{'date_field' => {'$gte' => Date.today.beginning_of_week, '$lte' => Date.today.end_of_week}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'date_field' => {'1' => {v: [], o: 'last_week'}}).selector).to eq('$and' => [{'date_field' => {'$gte' => 1.week.ago.to_date.beginning_of_week, '$lte' => 1.week.ago.to_date.end_of_week}}])\n    end\n\n    it 'supports datetime type query' do\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'datetime_field' => {'1' => {v: ['', '2012-01-02T12:00:00', '2012-01-03T12:00:00'], o: 'between'}}).selector).to eq('$and' => [{'datetime_field' => {'$gte' => Time.zone.local(2012, 1, 2, 12), '$lte' => Time.zone.local(2012, 1, 3, 12)}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'datetime_field' => {'1' => {v: ['', '2012-01-03T12:00:00', ''], o: 'between'}}).selector).to eq('$and' => [{'datetime_field' => {'$gte' => Time.zone.local(2012, 1, 3, 12)}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'datetime_field' => {'1' => {v: ['', '', '2012-01-02T12:00:00'], o: 'between'}}).selector).to eq('$and' => [{'datetime_field' => {'$lte' => Time.zone.local(2012, 1, 2, 12)}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'datetime_field' => {'1' => {v: ['2012-01-02T12:00:00'], o: 'default'}}).selector).to eq('$and' => [{'datetime_field' => Time.zone.local(2012, 1, 2, 12)}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'datetime_field' => {'1' => {v: [], o: 'today'}}).selector).to eq('$and' => [{'datetime_field' => {'$gte' => Date.today.beginning_of_day, '$lte' => Date.today.end_of_day}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'datetime_field' => {'1' => {v: [], o: 'yesterday'}}).selector).to eq('$and' => [{'datetime_field' => {'$gte' => Date.yesterday.beginning_of_day, '$lte' => Date.yesterday.end_of_day}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'datetime_field' => {'1' => {v: [], o: 'this_week'}}).selector).to eq('$and' => [{'datetime_field' => {'$gte' => Date.today.beginning_of_week.beginning_of_day, '$lte' => Date.today.end_of_week.end_of_day}}])\n      expect(@abstract_model.send(:filter_scope, FieldTest, 'datetime_field' => {'1' => {v: [], o: 'last_week'}}).selector).to eq('$and' => [{'datetime_field' => {'$gte' => 1.week.ago.to_date.beginning_of_week.beginning_of_day, '$lte' => 1.week.ago.to_date.end_of_week.end_of_day}}])\n    end\n\n    it 'supports enum type query' do\n      expect(@abstract_model.send(:build_statement, :field, :enum, '1', nil)).to eq(field: {'$in' => ['1']})\n    end\n  end\n\n  describe 'model attribute method' do\n    before do\n      @abstract_model = RailsAdmin::AbstractModel.new('Player')\n    end\n\n    it '#scoped returns relation object' do\n      expect(@abstract_model.scoped).to be_instance_of(Mongoid::Criteria)\n    end\n\n    it '#table_name works' do\n      expect(@abstract_model.table_name).to eq('players')\n    end\n  end\n\n  describe 'serialization' do\n    before do\n      @abstract_model = RailsAdmin::AbstractModel.new('FieldTest')\n      @controller = RailsAdmin::MainController.new\n    end\n\n    it 'accepts array value' do\n      params = HashWithIndifferentAccess.new(array_field: '[1, 3]')\n      @controller.send(:sanitize_params_for!, 'create', @abstract_model.config, params)\n      expect(params[:array_field]).to eq([1, 3])\n    end\n\n    it 'accepts hash value' do\n      params = HashWithIndifferentAccess.new(hash_field: '{a: 1, b: 3}')\n      @controller.send(:sanitize_params_for!, 'create', @abstract_model.config, params)\n      expect(params[:hash_field]).to eq('a' => 1, 'b' => 3)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/actions/base_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Actions::Base do\n  describe '#enabled?' do\n    it 'excludes models not referenced in the only array' do\n      RailsAdmin.config do |config|\n        config.actions do\n          index do\n            only [Player, Cms::BasicPage]\n          end\n        end\n      end\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Player))).to be_enabled\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Team))).to be_nil\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Cms::BasicPage))).to be_enabled\n    end\n\n    it 'excludes models referenced in the except array' do\n      RailsAdmin.config do |config|\n        config.actions do\n          index do\n            except [Player, Cms::BasicPage]\n          end\n        end\n      end\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Player))).to be_nil\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Team))).to be_enabled\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Cms::BasicPage))).to be_nil\n    end\n\n    it 'is always true for a writable model' do\n      RailsAdmin.config do |config|\n        config.actions do\n          index\n          show\n          new\n          edit\n          delete\n        end\n      end\n      %i[index show new edit delete].each do |action|\n        expect(RailsAdmin::Config::Actions.find(action, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Player), object: Player.new)).to be_enabled\n      end\n    end\n\n    it 'is false for write operations of a read-only model' do\n      RailsAdmin.config do |config|\n        config.actions do\n          index\n          show\n          new\n          edit\n          delete\n        end\n      end\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(ReadOnlyComment))).to be_enabled\n      expect(RailsAdmin::Config::Actions.find(:show, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(ReadOnlyComment), object: ReadOnlyComment.new)).to be_enabled\n      expect(RailsAdmin::Config::Actions.find(:new, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(ReadOnlyComment))).to be_enabled\n      expect(RailsAdmin::Config::Actions.find(:edit, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(ReadOnlyComment), object: ReadOnlyComment.new)).to be_nil\n      expect(RailsAdmin::Config::Actions.find(:delete, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(ReadOnlyComment), object: ReadOnlyComment.new)).to be_nil\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/actions_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Actions do\n  describe 'default' do\n    it 'is as before' do\n      expect(RailsAdmin::Config::Actions.all.collect(&:key)).to eq(%i[dashboard index show new edit export delete bulk_delete history_show history_index show_in_app])\n    end\n  end\n\n  describe 'find' do\n    it 'finds by custom key' do\n      RailsAdmin.config do |config|\n        config.actions do\n          dashboard do\n            custom_key :custom_dashboard\n          end\n\n          collection :custom_collection, :index\n\n          show\n        end\n      end\n\n      expect(RailsAdmin::Config::Actions.find(:custom_dashboard)).to be_a(RailsAdmin::Config::Actions::Dashboard)\n      expect(RailsAdmin::Config::Actions.find(:custom_collection)).to be_a(RailsAdmin::Config::Actions::Index)\n      expect(RailsAdmin::Config::Actions.find(:show)).to be_a(RailsAdmin::Config::Actions::Show)\n    end\n\n    it 'returns nil when no action is found by the custom key' do\n      expect(RailsAdmin::Config::Actions.find(:non_existent_action_key)).to be_nil\n    end\n\n    it 'returns visible action passing binding if controller binding is given, and pass action visible or not if no' do\n      RailsAdmin.config do |config|\n        config.actions do\n          root :custom_root do\n            visible do\n              bindings[:controller] == 'controller'\n            end\n          end\n        end\n      end\n      expect(RailsAdmin::Config::Actions.find(:custom_root)).to be_a(RailsAdmin::Config::Actions::Base)\n      expect(RailsAdmin::Config::Actions.find(:custom_root, controller: 'not_controller')).to be_nil\n      expect(RailsAdmin::Config::Actions.find(:custom_root, controller: 'controller')).to be_a(RailsAdmin::Config::Actions::Base)\n    end\n\n    it \"ignores bindings[:abstract_model] visibility while checking action\\'s visibility\" do\n      RailsAdmin.config Team do\n        hide\n      end\n\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Comment))).to be_a(RailsAdmin::Config::Actions::Index) # decoy\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Team))).to be_a(RailsAdmin::Config::Actions::Index)\n    end\n\n    it \"checks bindings[:abstract_model] presence while checking action\\'s visibility\" do\n      RailsAdmin.config do |config|\n        config.excluded_models << Team\n      end\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Comment))).to be_a(RailsAdmin::Config::Actions::Index) # decoy\n      expect(RailsAdmin::Config::Actions.find(:index, controller: double(authorized?: true), abstract_model: RailsAdmin::AbstractModel.new(Team))).to be_nil\n    end\n  end\n\n  describe 'all' do\n    it 'returns all defined actions' do\n      RailsAdmin.config do |config|\n        config.actions do\n          dashboard\n          index\n        end\n      end\n\n      expect(RailsAdmin::Config::Actions.all.collect(&:key)).to eq(%i[dashboard index])\n    end\n\n    it 'restricts by scope' do\n      RailsAdmin.config do |config|\n        config.actions do\n          root :custom_root\n          collection :custom_collection\n          member :custom_member\n        end\n      end\n      expect(RailsAdmin::Config::Actions.all(:root).collect(&:key)).to eq([:custom_root])\n      expect(RailsAdmin::Config::Actions.all(:collection).collect(&:key)).to eq([:custom_collection])\n      expect(RailsAdmin::Config::Actions.all(:member).collect(&:key)).to eq([:custom_member])\n    end\n\n    it 'returns all visible actions passing binding if controller binding is given, and pass all actions if no' do\n      RailsAdmin.config do |config|\n        config.actions do\n          root :custom_root do\n            visible do\n              bindings[:controller] == 'controller'\n            end\n          end\n        end\n      end\n      expect(RailsAdmin::Config::Actions.all(:root).collect(&:custom_key)).to eq([:custom_root])\n      expect(RailsAdmin::Config::Actions.all(:root, controller: 'not_controller').collect(&:custom_key)).to eq([])\n      expect(RailsAdmin::Config::Actions.all(:root, controller: 'controller').collect(&:custom_key)).to eq([:custom_root])\n    end\n  end\n\n  describe 'customized through DSL' do\n    it 'adds the one asked' do\n      RailsAdmin.config do |config|\n        config.actions do\n          dashboard\n          index\n          show\n        end\n      end\n\n      expect(RailsAdmin::Config::Actions.all.collect(&:key)).to eq(%i[dashboard index show])\n    end\n\n    it 'allows to customize the custom_key when customizing an existing action' do\n      RailsAdmin.config do |config|\n        config.actions do\n          dashboard do\n            custom_key :my_dashboard\n          end\n        end\n      end\n      expect(RailsAdmin::Config::Actions.all.collect(&:custom_key)).to eq([:my_dashboard])\n      expect(RailsAdmin::Config::Actions.all.collect(&:key)).to eq([:dashboard])\n    end\n\n    it 'allows to change the key and the custom_key when subclassing an existing action' do\n      RailsAdmin.config do |config|\n        config.actions do\n          root :my_dashboard_key, :dashboard do\n            custom_key :my_dashboard_custom_key\n          end\n        end\n      end\n      expect(RailsAdmin::Config::Actions.all.collect(&:custom_key)).to eq([:my_dashboard_custom_key])\n      expect(RailsAdmin::Config::Actions.all.collect(&:key)).to eq([:my_dashboard_key])\n      expect(RailsAdmin::Config::Actions.all.collect(&:class)).to eq([RailsAdmin::Config::Actions::Dashboard])\n    end\n\n    it 'does not add the same custom_key twice' do\n      expect do\n        RailsAdmin.config do |config|\n          config.actions do\n            dashboard\n            dashboard\n          end\n        end\n      end.to raise_error('Action dashboard already exists. Please change its custom key.')\n\n      expect do\n        RailsAdmin.config do |config|\n          config.actions do\n            index\n            collection :index\n          end\n        end\n      end.to raise_error('Action index already exists. Please change its custom key.')\n    end\n\n    it 'adds the same key with different custom key' do\n      RailsAdmin.config do |config|\n        config.actions do\n          dashboard\n          dashboard do\n            custom_key :my_dashboard\n          end\n        end\n      end\n\n      expect(RailsAdmin::Config::Actions.all.collect(&:custom_key)).to eq(%i[dashboard my_dashboard])\n      expect(RailsAdmin::Config::Actions.all.collect(&:key)).to eq(%i[dashboard dashboard])\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/configurable_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Configurable do\n  class ConfigurableTest\n    include RailsAdmin::Config::Configurable\n\n    register_instance_option :foo do\n      'default'\n    end\n  end\n\n  subject { ConfigurableTest.new }\n\n  describe 'recursion tracking' do\n    it 'works and use default value' do\n      subject.instance_eval do\n        foo { foo }\n      end\n      expect(subject.foo).to eq 'default'\n    end\n\n    describe 'with parallel execution' do\n      before do\n        subject.instance_eval do\n          foo do\n            sleep 0.15\n            'value'\n          end\n        end\n      end\n\n      it 'ensures thread-safety' do\n        threads = Array.new(2) do |i|\n          Thread.new do\n            sleep i * 0.1\n            expect(subject.foo).to eq 'value'\n          end\n        end\n        threads.each(&:join)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/const_load_suppressor_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::ConstLoadSuppressor do\n  describe '.suppressing' do\n    it 'suppresses constant loading' do\n      expect do\n        subject.suppressing { UnknownConstant }\n      end.not_to raise_error\n    end\n\n    it 'raises the error on recursion' do\n      expect do\n        subject.suppressing do\n          subject.suppressing {}\n        end\n      end.to raise_error(/already suppressed/)\n    end\n  end\n\n  describe '.allowing' do\n    it 'suspends constant loading suppression' do\n      expect do\n        subject.suppressing do\n          subject.allowing { UnknownConstant }\n        end\n      end.to raise_error NameError\n    end\n\n    it 'does not break when suppression is disabled' do\n      expect do\n        subject.allowing {}\n      end.not_to raise_error\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Association do\n  describe '#pretty_value' do\n    let(:player) { FactoryBot.create(:player, name: '<br />', team: FactoryBot.create(:team)) }\n    let(:field) { RailsAdmin.config('Team').fields.detect { |f| f.name == :players } }\n    let(:view) { ActionView::Base.empty }\n    subject { field.with(object: player.team, view: view).pretty_value }\n\n    context 'when the link is disabled' do\n      let(:view) { ActionView::Base.empty.tap { |d| allow(d).to receive(:action).and_return(nil) } }\n\n      it 'does not expose non-HTML-escaped string' do\n        is_expected.to be_html_safe\n        is_expected.to eq '&lt;br /&gt;'\n      end\n    end\n\n    context 'when the value is empty' do\n      let(:team) { FactoryBot.build :team }\n      subject { field.with(object: team, view: view).pretty_value }\n\n      it \"returns '-' to show emptiness\" do\n        is_expected.to eq '-'\n      end\n    end\n  end\n\n  describe '#dynamic_scope_relationships' do\n    let(:player) { FactoryBot.create(:player, team: FactoryBot.create(:team)) }\n    let(:field) { RailsAdmin.config('Draft').fields.detect { |f| f.name == :player } }\n\n    it 'returns the relationship of fields in this model and in the associated model' do\n      RailsAdmin.config Draft do\n        field :team\n        field :player do\n          dynamically_scope_by :team\n        end\n      end\n      expect(field.dynamic_scope_relationships).to eq({team_id: :team})\n    end\n\n    it 'accepts Array' do\n      RailsAdmin.config Draft do\n        field :team\n        field :notes\n        field :player do\n          dynamically_scope_by %i[team notes]\n        end\n      end\n      expect(field.dynamic_scope_relationships).to eq({team_id: :team, notes: :notes})\n    end\n\n    it 'accepts Hash' do\n      RailsAdmin.config Draft do\n        field :round\n        field :player do\n          dynamically_scope_by({round: :number})\n        end\n      end\n      expect(field.dynamic_scope_relationships).to eq({round: :number})\n    end\n\n    it 'accepts mixture of Array and Hash' do\n      RailsAdmin.config Draft do\n        field :team\n        field :round\n        field :player do\n          dynamically_scope_by [:team, {round: :number}]\n        end\n      end\n      expect(field.dynamic_scope_relationships).to eq({team_id: :team, round: :number})\n    end\n\n    it 'raises error if the field does not exist in this model' do\n      RailsAdmin.config Draft do\n        field :player do\n          dynamically_scope_by :team\n        end\n      end\n      expect { field.dynamic_scope_relationships }.to raise_error \"Field 'team' was given for #dynamically_scope_by but not found in 'Draft'\"\n    end\n\n    it 'raises error if the field does not exist in the associated model' do\n      RailsAdmin.config Player do\n        field :name\n      end\n      RailsAdmin.config Draft do\n        field :team\n        field :player do\n          dynamically_scope_by :team\n        end\n      end\n      expect { field.dynamic_scope_relationships }.to raise_error \"Field 'team' was given for #dynamically_scope_by but not found in 'Player'\"\n    end\n\n    it 'raises error if the target field is not filterable' do\n      RailsAdmin.config Player do\n        field :name\n        field :team do\n          filterable false\n        end\n      end\n      RailsAdmin.config Draft do\n        field :team\n        field :player do\n          dynamically_scope_by :team\n        end\n      end\n      expect { field.dynamic_scope_relationships }.to raise_error \"Field 'team' in 'Player' can't be used for dynamic scoping because it's not filterable\"\n    end\n  end\n\n  describe '#removable?', active_record: true do\n    context 'with non-nullable foreign key' do\n      let(:field) { RailsAdmin.config('FieldTest').fields.detect { |f| f.name == :nested_field_tests } }\n      it 'is false' do\n        expect(field.removable?).to be false\n      end\n    end\n\n    context 'with nullable foreign key' do\n      let(:field) { RailsAdmin.config('Team').fields.detect { |f| f.name == :players } }\n      it 'is true' do\n        expect(field.removable?).to be true\n      end\n    end\n\n    context 'with polymorphic has_many' do\n      let(:field) { RailsAdmin.config('Player').fields.detect { |f| f.name == :comments } }\n      it 'does not break' do\n        expect(field.removable?).to be true\n      end\n    end\n\n    context 'with has_many through' do\n      before do\n        class TeamWithHasManyThrough < Team\n          has_many :drafts\n          has_many :draft_players, through: :drafts, source: :player\n        end\n      end\n      let(:field) { RailsAdmin.config('TeamWithHasManyThrough').fields.detect { |f| f.name == :draft_players } }\n      it 'does not break' do\n        expect(field.removable?).to be true\n      end\n    end\n  end\n\n  describe '#value' do\n    context 'when using `system` as the association name' do\n      before do\n        class System < Tableless; end\n\n        class BelongsToSystem < Tableless\n          column :system_id, :integer\n          belongs_to :system\n        end\n      end\n      let(:record) { BelongsToSystem.new(system: System.new) }\n      let(:field) { RailsAdmin.config(BelongsToSystem).fields.detect { |f| f.name == :system } }\n      subject { field.with(object: record).value }\n\n      it 'does not break' do\n        expect(subject).to be_a_kind_of System\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/base_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Base do\n  describe '#required' do\n    it 'reads the on: :create/:update validate option' do\n      RailsAdmin.config Ball do\n        field 'color'\n      end\n\n      expect(RailsAdmin.config('Ball').fields.first.with(object: Ball.new)).to be_required\n      expect(RailsAdmin.config('Ball').fields.first.with(object: FactoryBot.create(:ball))).not_to be_required\n    end\n\n    context 'without validation' do\n      it 'is optional' do\n        # draft.notes is nullable and has no validation\n        field = RailsAdmin.config('Draft').edit.fields.detect { |f| f.name == :notes }\n        expect(field.properties.nullable?).to be_truthy\n        expect(field.required?).to be_falsey\n      end\n    end\n\n    context 'with presence validation' do\n      it 'is required' do\n        # draft.date is nullable in the schema but has an AR\n        # validates_presence_of validation that makes it required\n        field = RailsAdmin.config('Draft').edit.fields.detect { |f| f.name == :date }\n        expect(field.properties.nullable?).to be_truthy\n        expect(field.required?).to be_truthy\n      end\n    end\n\n    context 'with numericality validation' do\n      it 'is required' do\n        # draft.round is nullable in the schema but has an AR\n        # validates_numericality_of validation that makes it required\n        field = RailsAdmin.config('Draft').edit.fields.detect { |f| f.name == :round }\n        expect(field.properties.nullable?).to be_truthy\n        expect(field.required?).to be_truthy\n      end\n    end\n\n    context 'with validation marked as allow_nil or allow_blank' do\n      it 'is optional' do\n        # team.revenue is nullable in the schema but has an AR\n        # validates_numericality_of validation that allows nil\n        field = RailsAdmin.config('Team').edit.fields.detect { |f| f.name == :revenue }\n        expect(field.properties.nullable?).to be_truthy\n        expect(field.required?).to be_falsey\n\n        # team.founded is nullable in the schema but has an AR\n        # validates_numericality_of validation that allows blank\n        field = RailsAdmin.config('Team').edit.fields.detect { |f| f.name == :founded }\n        expect(field.properties.nullable?).to be_truthy\n        expect(field.required?).to be_falsey\n      end\n    end\n\n    context 'with conditional validation' do\n      before do\n        class ConditionalValidationTest < Tableless\n          column :foo, :varchar\n          column :bar, :varchar\n          validates :foo, presence: true, if: :persisted?\n          validates :bar, presence: true, unless: :persisted?\n        end\n      end\n\n      it 'is optional' do\n        expect(RailsAdmin.config('ConditionalValidationTest').fields.detect { |f| f.name == :foo }).not_to be_required\n        expect(RailsAdmin.config('ConditionalValidationTest').fields.detect { |f| f.name == :bar }).not_to be_required\n      end\n    end\n\n    context 'on a Paperclip installation' do\n      it 'should detect required fields' do\n        expect(RailsAdmin.config('Image').fields.detect { |f| f.name == :file }.with(object: Image.new)).to be_required\n      end\n    end\n\n    describe 'associations' do\n      before do\n        class RelTest < Tableless\n          column :league_id, :integer\n          column :division_id, :integer, nil, false\n          column :player_id, :integer\n          belongs_to :league, optional: true\n          belongs_to :division, optional: true\n          belongs_to :player, optional: true\n          validates_numericality_of(:player_id, only_integer: true)\n        end\n        @fields = RailsAdmin.config(RelTest).create.fields\n      end\n\n      describe 'for column with nullable foreign key and no model validations' do\n        it 'is optional' do\n          expect(@fields.detect { |f| f.name == :league }.required?).to be_falsey\n        end\n      end\n\n      describe 'for column with non-nullable foreign key and no model validations' do\n        it 'is optional' do\n          expect(@fields.detect { |f| f.name == :division }.required?).to be_falsey\n        end\n      end\n\n      describe 'for column with nullable foreign key and a numericality model validation' do\n        it 'is required' do\n          expect(@fields.detect { |f| f.name == :player }.required?).to be_truthy\n        end\n      end\n    end\n  end\n\n  describe '#name' do\n    it 'is normalized to Symbol' do\n      RailsAdmin.config Team do\n        field 'name'\n      end\n      expect(RailsAdmin.config('Team').fields.first.name).to eq(:name)\n    end\n  end\n\n  describe '#children_fields' do\n    POLYMORPHIC_CHILDREN = %i[commentable_id commentable_type].freeze\n\n    it 'is empty by default' do\n      expect(RailsAdmin.config(Team).fields.detect { |f| f.name == :name }.children_fields).to eq([])\n    end\n\n    it 'contains child key for belongs to associations' do\n      expect(RailsAdmin.config(Team).fields.detect { |f| f.name == :division }.children_fields).to eq([:division_id])\n    end\n\n    it 'contains child keys for polymorphic belongs to associations' do\n      expect(RailsAdmin.config(Comment).fields.detect { |f| f.name == :commentable }.children_fields).to match_array POLYMORPHIC_CHILDREN\n    end\n\n    it 'has correct fields when polymorphic_type column comes ahead of polymorphic foreign_key column' do\n      class CommentReversed < Tableless\n        column :commentable_type, :varchar\n        column :commentable_id, :integer\n        belongs_to :commentable, polymorphic: true\n      end\n      expect(RailsAdmin.config(CommentReversed).fields.collect { |f| f.name.to_s }.select { |f| /^comment/ =~ f }).to match_array ['commentable'].concat(POLYMORPHIC_CHILDREN.collect(&:to_s))\n    end\n\n    context 'of a Paperclip installation' do\n      it 'is a _file_name field' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :paperclip_asset }.children_fields.include?(:paperclip_asset_file_name)).to be_truthy\n      end\n\n      it 'is hidden, not filterable' do\n        field = RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :paperclip_asset_file_name }\n        expect(field.hidden?).to be_truthy\n        expect(field.filterable?).to be_falsey\n      end\n    end\n\n    context 'of a Dragonfly installation' do\n      it 'is a _name field and _uid field' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :dragonfly_asset }.children_fields).to eq(%i[dragonfly_asset_name dragonfly_asset_uid])\n      end\n    end\n\n    context 'of a Carrierwave installation' do\n      it 'is the parent field itself' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :carrierwave_asset }.children_fields).to eq([:carrierwave_asset])\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :carrierwave_asset }.hidden?).to be_falsey\n      end\n    end\n\n    context 'of a Carrierwave installation with multiple file support' do\n      it 'is the parent field itself' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :carrierwave_assets }.children_fields).to eq([:carrierwave_assets])\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :carrierwave_assets }.hidden?).to be_falsey\n      end\n    end\n\n    if defined?(ActiveStorage)\n      context 'of a ActiveStorage installation' do\n        it 'is _attachment and _blob fields' do\n          expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :active_storage_asset }.children_fields).to match_array %i[active_storage_asset_attachment active_storage_asset_blob]\n        end\n\n        it 'is hidden, not filterable' do\n          fields = RailsAdmin.config(FieldTest).fields.select { |f| %i[active_storage_asset_attachment active_storage_asset_blob].include?(f.name) }\n          expect(fields).to all(be_hidden)\n          expect(fields).not_to include(be_filterable)\n        end\n      end\n\n      context 'of a ActiveStorage installation with multiple file support' do\n        it 'is _attachment and _blob fields' do\n          expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :active_storage_assets }.children_fields).to match_array %i[active_storage_assets_attachments active_storage_assets_blobs]\n        end\n\n        it 'is hidden, not filterable' do\n          fields = RailsAdmin.config(FieldTest).fields.select { |f| %i[active_storage_assets_attachments active_storage_assets_blobs].include?(f.name) }\n          expect(fields).to all(be_hidden)\n          expect(fields).not_to include(be_filterable)\n        end\n      end\n    end\n\n    if defined?(Shrine)\n      context 'of a Shrine installation' do\n        it 'is the parent field itself' do\n          expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :shrine_asset }.children_fields).to eq([:shrine_asset_data])\n          expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :shrine_asset }.hidden?).to be_falsey\n        end\n\n        it 'is not filterable' do\n          fields = RailsAdmin.config(FieldTest).fields.select { |f| [:shrine_asset_data].include?(f.name) }\n          expect(fields).to all(be_hidden)\n          expect(fields).not_to include(be_filterable)\n        end\n      end\n    end\n  end\n\n  describe '#form_default_value' do\n    it 'is default_value for new records when value is nil' do\n      RailsAdmin.config Team do\n        list do\n          field :name do\n            default_value 'default value'\n          end\n        end\n      end\n      @team = Team.new\n      expect(RailsAdmin.config('Team').list.fields.detect { |f| f.name == :name }.with(object: @team).form_default_value).to eq('default value')\n      @team.name = 'set value'\n      expect(RailsAdmin.config('Team').list.fields.detect { |f| f.name == :name }.with(object: @team).form_default_value).to be_nil\n      @team = FactoryBot.create :team\n      @team.name = nil\n      expect(RailsAdmin.config('Team').list.fields.detect { |f| f.name == :name }.with(object: @team).form_default_value).to be_nil\n    end\n  end\n\n  describe '#default_value' do\n    it 'is nil by default' do\n      expect(RailsAdmin.config('Team').list.fields.detect { |f| f.name == :name }.default_value).to be_nil\n    end\n  end\n\n  describe '#hint' do\n    it 'is user customizable' do\n      RailsAdmin.config Team do\n        list do\n          field :division do\n            hint 'Great Division'\n          end\n          field :name\n        end\n      end\n      expect(RailsAdmin.config('Team').list.fields.detect { |f| f.name == :division }.hint).to eq('Great Division') # custom\n      expect(RailsAdmin.config('Team').list.fields.detect { |f| f.name == :name }.hint).to eq('') # default\n    end\n  end\n\n  describe '#help' do\n    it 'has a default and be user customizable via i18n' do\n      RailsAdmin.config Team do\n        list do\n          field :division\n          field :name\n        end\n      end\n      field_specific_i18n = RailsAdmin.config('Team').list.fields.detect { |f| f.name == :name }\n      expect(field_specific_i18n.help).to eq(I18n.translate('admin.help.team.name')) # custom via locales yml\n      field_no_specific_i18n = RailsAdmin.config('Team').list.fields.detect { |f| f.name == :division }\n      expect(field_no_specific_i18n.help).to eq(field_no_specific_i18n.generic_help) # rails_admin generic fallback\n    end\n  end\n\n  describe '#css_class' do\n    it 'has a default and be user customizable' do\n      RailsAdmin.config Team do\n        list do\n          field :division do\n            css_class 'custom'\n          end\n          field :name\n        end\n      end\n      expect(RailsAdmin.config('Team').list.fields.detect { |f| f.name == :division }.css_class).to eq('custom') # custom\n      expect(RailsAdmin.config('Team').list.fields.detect { |f| f.name == :division }.type_css_class).to eq('belongs_to_association_type') # type css class, non-customizable\n      expect(RailsAdmin.config('Team').list.fields.detect { |f| f.name == :name }.css_class).to eq('name_field') # default\n    end\n  end\n\n  describe '#associated_collection_cache_all' do\n    it 'defaults to true if associated collection count < 100' do\n      expect(RailsAdmin.config(Team).edit.fields.detect { |f| f.name == :players }.associated_collection_cache_all).to be_truthy\n    end\n\n    it 'defaults to false if associated collection count >= 100' do\n      @players = Array.new(100) do\n        FactoryBot.create :player\n      end\n      expect(RailsAdmin.config(Team).edit.fields.detect { |f| f.name == :players }.associated_collection_cache_all).to be_falsey\n    end\n\n    context 'with custom configuration' do\n      before do\n        RailsAdmin.config.default_associated_collection_limit = 5\n      end\n      it 'defaults to true if associated collection count less than than limit' do\n        @players = Array.new(4) do\n          FactoryBot.create :player\n        end\n        expect(RailsAdmin.config(Team).edit.fields.detect { |f| f.name == :players }.associated_collection_cache_all).to be_truthy\n      end\n\n      it 'defaults to false if associated collection count >= that limit' do\n        @players = Array.new(5) do\n          FactoryBot.create :player\n        end\n        expect(RailsAdmin.config(Team).edit.fields.detect { |f| f.name == :players }.associated_collection_cache_all).to be_falsey\n      end\n    end\n  end\n\n  describe '#searchable_columns' do\n    describe 'for belongs_to fields' do\n      it 'finds label method on the opposite side for belongs_to associations by default' do\n        expect(RailsAdmin.config(Team).fields.detect { |f| f.name == :division }.searchable_columns.collect { |c| c[:column] }).to eq(['divisions.name', 'teams.division_id'])\n      end\n\n      it 'searches on opposite table for belongs_to' do\n        RailsAdmin.config(Team) do\n          field :division do\n            searchable :custom_id\n          end\n        end\n        expect(RailsAdmin.config(Team).fields.detect { |f| f.name == :division }.searchable_columns.collect { |c| c[:column] }).to eq(['divisions.custom_id'])\n      end\n\n      it 'searches on asked table with model name' do\n        RailsAdmin.config(Team) do\n          field :division do\n            searchable League => :name\n          end\n        end\n        expect(RailsAdmin.config(Team).fields.detect { |f| f.name == :division }.searchable_columns).to eq([{column: 'leagues.name', type: :string}])\n      end\n\n      it 'searches on asked table with table name' do\n        RailsAdmin.config(Team) do\n          field :division do\n            searchable leagues: :name\n          end\n        end\n        expect(RailsAdmin.config(Team).fields.detect { |f| f.name == :division }.searchable_columns).to eq([{column: 'leagues.name', type: :string}])\n      end\n    end\n\n    describe 'for basic type fields' do\n      it 'uses base table and find correct column type' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :text_field }.searchable_columns).to eq([{column: 'field_tests.text_field', type: :text}])\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :integer_field }.searchable_columns).to eq([{column: 'field_tests.integer_field', type: :integer}])\n      end\n\n      it 'is customizable to another field on the same table' do\n        RailsAdmin.config(FieldTest) do\n          field :time_field do\n            searchable :date_field\n          end\n        end\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :time_field }.searchable_columns).to eq([{column: 'field_tests.date_field', type: :date}])\n      end\n\n      it 'is customizable to another field on another table with :table_name' do\n        RailsAdmin.config(FieldTest) do\n          field :string_field do\n            searchable nested_field_tests: :title\n          end\n        end\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :string_field }.searchable_columns).to eq([{column: 'nested_field_tests.title', type: :string}])\n      end\n\n      it 'is customizable to another field on another model with ModelClass' do\n        RailsAdmin.config(FieldTest) do\n          field :string_field do\n            searchable NestedFieldTest => :title\n          end\n        end\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :string_field }.searchable_columns).to eq([{column: 'nested_field_tests.title', type: :string}])\n      end\n    end\n\n    describe 'for mapped fields' do\n      it 'of paperclip should find the underlying column on the base table' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :paperclip_asset }.searchable_columns.collect { |c| c[:column] }).to eq(['field_tests.paperclip_asset_file_name'])\n      end\n\n      it 'of dragonfly should find the underlying column on the base table' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :dragonfly_asset }.searchable_columns.collect { |c| c[:column] }).to eq(['field_tests.dragonfly_asset_name'])\n      end\n\n      it 'of carrierwave should find the underlying column on the base table' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :carrierwave_asset }.searchable_columns.collect { |c| c[:column] }).to eq(['field_tests.carrierwave_asset'])\n      end\n    end\n  end\n\n  describe '#searchable and #sortable' do\n    it 'is false if column is virtual, true otherwise' do\n      RailsAdmin.config League do\n        field :virtual_column\n        field :name\n      end\n      @league = FactoryBot.create :league\n      expect(RailsAdmin.config('League').export.fields.detect { |f| f.name == :virtual_column }.sortable).to be_falsey\n      expect(RailsAdmin.config('League').export.fields.detect { |f| f.name == :virtual_column }.searchable).to be_falsey\n      expect(RailsAdmin.config('League').export.fields.detect { |f| f.name == :name }.sortable).to be_truthy\n      expect(RailsAdmin.config('League').export.fields.detect { |f| f.name == :name }.searchable).to be_truthy\n    end\n\n    context 'of a virtual field with children fields' do\n      it 'of paperclip should target the first children field' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :paperclip_asset }.searchable).to eq(:paperclip_asset_file_name)\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :paperclip_asset }.sortable).to eq(:paperclip_asset_file_name)\n      end\n\n      it 'of dragonfly should target the first children field' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :dragonfly_asset }.searchable).to eq(:dragonfly_asset_name)\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :dragonfly_asset }.sortable).to eq(:dragonfly_asset_name)\n      end\n\n      it 'of carrierwave should target the first children field' do\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :carrierwave_asset }.searchable).to eq(:carrierwave_asset)\n        expect(RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :carrierwave_asset }.sortable).to eq(:carrierwave_asset)\n      end\n    end\n  end\n\n  describe '#virtual?' do\n    it 'is true if column has no properties, false otherwise' do\n      RailsAdmin.config League do\n        field :virtual_column\n        field :name\n      end\n      @league = FactoryBot.create :league\n      expect(RailsAdmin.config('League').export.fields.detect { |f| f.name == :virtual_column }.virtual?).to be_truthy\n      expect(RailsAdmin.config('League').export.fields.detect { |f| f.name == :name }.virtual?).to be_falsey\n    end\n  end\n\n  describe '#default_search_operator' do\n    let(:abstract_model) { RailsAdmin::AbstractModel.new('Player') }\n    let(:model_config) { RailsAdmin.config(abstract_model) }\n    let(:queryable_fields) { model_config.list.fields.select(&:queryable?) }\n\n    context 'when no search operator is specified for the field' do\n      it \"uses 'default' search operator\" do\n        expect(queryable_fields.size).to be >= 1\n        expect(queryable_fields.first.search_operator).to eq(RailsAdmin::Config.default_search_operator)\n      end\n\n      it 'uses config.default_search_operator if set' do\n        RailsAdmin.config do |config|\n          config.default_search_operator = 'starts_with'\n        end\n        expect(queryable_fields.size).to be >= 1\n        expect(queryable_fields.first.search_operator).to eq(RailsAdmin::Config.default_search_operator)\n      end\n    end\n\n    context 'when search operator is specified for the field' do\n      it 'uses specified search operator' do\n        RailsAdmin.config Player do\n          list do\n            fields do\n              search_operator 'starts_with'\n            end\n          end\n        end\n        expect(queryable_fields.size).to be >= 1\n        expect(queryable_fields.first.search_operator).to eq('starts_with')\n      end\n\n      it 'uses specified search operator even if config.default_search_operator set' do\n        RailsAdmin.config do |config|\n          config.default_search_operator = 'starts_with'\n\n          config.model Player do\n            list do\n              fields do\n                search_operator 'ends_with'\n              end\n            end\n          end\n        end\n        expect(queryable_fields.size).to be >= 1\n        expect(queryable_fields.first.search_operator).to eq('ends_with')\n      end\n    end\n  end\n\n  describe '#render' do\n    it 'is configurable' do\n      RailsAdmin.config Team do\n        field :name do\n          render do\n            'rendered'\n          end\n        end\n      end\n      expect(RailsAdmin.config(Team).field(:name).render).to eq('rendered')\n    end\n  end\n\n  describe '#active' do\n    it 'is false by default' do\n      expect(RailsAdmin.config(Team).field(:division).active?).to be_falsey\n    end\n  end\n\n  describe '#visible?' do\n    it 'is false when fields have specific name ' do\n      class FieldVisibilityTest < Tableless\n        column :id, :integer\n        column :_id, :integer\n        column :_type, :varchar\n        column :name, :varchar\n        column :created_at, :timestamp\n        column :updated_at, :timestamp\n        column :deleted_at, :timestamp\n        column :created_on, :timestamp\n        column :updated_on, :timestamp\n        column :deleted_on, :timestamp\n      end\n      expect(RailsAdmin.config(FieldVisibilityTest).base.fields.select(&:visible?).collect(&:name)).to match_array %i[_id created_at created_on deleted_at deleted_on id name updated_at updated_on]\n      expect(RailsAdmin.config(FieldVisibilityTest).list.fields.select(&:visible?).collect(&:name)).to match_array %i[_id created_at created_on deleted_at deleted_on id name updated_at updated_on]\n      expect(RailsAdmin.config(FieldVisibilityTest).edit.fields.select(&:visible?).collect(&:name)).to match_array [:name]\n      expect(RailsAdmin.config(FieldVisibilityTest).show.fields.select(&:visible?).collect(&:name)).to match_array [:name]\n    end\n  end\n\n  describe '#allowed_methods' do\n    it 'includes method_name' do\n      RailsAdmin.config do |config|\n        config.model Team do\n          field :name\n        end\n      end\n\n      expect(RailsAdmin.config(Team).field(:name).allowed_methods).to eq [:name]\n    end\n  end\n\n  describe '#default_filter_operator' do\n    it 'has a default and be user customizable' do\n      RailsAdmin.config Team do\n        list do\n          field :division\n          field :name do\n            default_filter_operator 'is'\n          end\n        end\n      end\n      name_field = RailsAdmin.config('Team').list.fields.detect { |f| f.name == :name }\n      expect(name_field.default_filter_operator).to eq('is') # custom via user specification\n      division_field = RailsAdmin.config('Team').list.fields.detect { |f| f.name == :division }\n      expect(division_field.default_filter_operator).to be nil # rails_admin generic fallback\n    end\n  end\n\n  describe '#eager_load' do\n    let(:field) { RailsAdmin.config('Team').fields.detect { |f| f.name == :players } }\n\n    it 'can be set to true' do\n      RailsAdmin.config Team do\n        field :players do\n          eager_load true\n        end\n      end\n      expect(field.eager_load_values).to eq [:players]\n    end\n\n    it 'can be set to false' do\n      RailsAdmin.config Team do\n        field :players do\n          eager_load false\n        end\n      end\n      expect(field.eager_load_values).to eq []\n    end\n\n    it 'can be set to a custom value' do\n      RailsAdmin.config Team do\n        field :players do\n          eager_load [{players: :draft}, :fans]\n        end\n      end\n      expect(field.eager_load_values).to eq [{players: :draft}, :fans]\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/action_text_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nif defined?(ActionText)\n  RSpec.describe RailsAdmin::Config::Fields::Types::ActionText do\n    it_behaves_like 'a generic field type', :action_text_field\n\n    it_behaves_like 'a string-like field type', :action_text_field\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/active_record_enum_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::ActiveRecordEnum, active_record: true do\n  it_behaves_like 'a generic field type', :string_enum_field\n\n  describe '#pretty_value' do\n    context 'when column name is format' do\n      before do\n        class FormatAsEnum < FieldTest\n          if ActiveRecord.gem_version >= Gem::Version.new('7.0')\n            enum :format, {Text: 'txt', Markdown: 'md'}\n          else\n            enum format: {Text: 'txt', Markdown: 'md'}\n          end\n        end\n      end\n      let(:field) do\n        RailsAdmin.config(FormatAsEnum).fields.detect do |f|\n          f.name == :format\n        end.with(object: FormatAsEnum.new(format: 'md'))\n      end\n\n      it 'does not break' do\n        expect(field.pretty_value).to eq 'Markdown'\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/active_storage_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nif defined?(ActiveStorage)\n  RSpec.describe RailsAdmin::Config::Fields::Types::ActiveStorage do\n    it_behaves_like 'a generic field type', :string_field, :active_storage\n\n    let(:record) { FactoryBot.create :field_test }\n    let(:field) do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :active_storage_asset\n      end.with(object: record)\n    end\n\n    describe '#thumb_method' do\n      it 'returns corresponding value which is to be passed to image_processing(ActiveStorage >= 6.0) or mini_magick(ActiveStorage 5.2)' do\n        expect(field.thumb_method).to eq(resize_to_limit: [100, 100])\n      end\n    end\n\n    describe '#image?' do\n      context 'configured Mime::Types' do\n        before { Mime::Type.register 'image/webp', :webp }\n        after { Mime::Type.unregister :webp }\n\n        %w[jpg jpeg png gif svg webp].each do |image_type_ext|\n          context \"when attachment is a '#{image_type_ext}' file\" do\n            let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: \"test.#{image_type_ext}\"} }\n\n            it 'returns true' do\n              expect(field.image?).to be_truthy\n            end\n          end\n        end\n      end\n\n      context 'when attachment is not an image' do\n        let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: 'test.txt', content_type: 'text/plain'} }\n\n        it 'returns false' do\n          expect(field.image?).to be_falsy\n        end\n      end\n\n      context 'when attachment is a PDF file' do\n        let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: 'test.pdf', content_type: 'application/pdf'} }\n        before { allow(ActiveStorage::Previewer::PopplerPDFPreviewer).to receive(:accept?).and_return(true) }\n\n        it 'returns true' do\n          expect(field.image?).to be_truthy\n        end\n      end\n    end\n\n    describe '#resource_url' do\n      context 'when calling with thumb = false' do\n        let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: 'test.jpg', content_type: 'image/jpeg'} }\n\n        it 'returns original url' do\n          expect(field.resource_url).not_to match(/representations/)\n        end\n      end\n\n      context 'when attachment is an image' do\n        let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: 'test.jpg', content_type: 'image/jpeg'} }\n\n        it 'returns variant\\'s url' do\n          expect(field.resource_url(true)).to match(/representations/)\n        end\n      end\n\n      context 'when attachment is not an image' do\n        let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: 'test.txt', content_type: 'text/plain'} }\n\n        it 'returns original url' do\n          expect(field.resource_url(true)).not_to match(/representations/)\n        end\n      end\n\n      context 'when attachment is a PDF file' do\n        let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: 'test.pdf', content_type: 'application/pdf'} }\n        before { allow(ActiveStorage::Previewer::PopplerPDFPreviewer).to receive(:accept?).and_return(true) }\n\n        it 'returns variant\\'s url' do\n          expect(field.resource_url(true)).to match(/representations/)\n        end\n      end\n    end\n\n    describe '#value' do\n      context 'when attachment exists' do\n        let(:record) { FactoryBot.create :field_test, active_storage_asset: {io: StringIO.new('dummy'), filename: 'test.jpg', content_type: 'image/jpeg'} }\n\n        it 'returns attached object' do\n          expect(field.value).to be_a(ActiveStorage::Attached::One)\n        end\n      end\n\n      context 'when attachment does not exist' do\n        let(:record) { FactoryBot.create :field_test }\n\n        it 'returns nil' do\n          expect(field.value).to be_nil\n        end\n      end\n    end\n\n    describe '#eager_load' do\n      it 'points to associations to be eager-loaded' do\n        expect(field.eager_load).to eq({active_storage_asset_attachment: :blob})\n      end\n    end\n\n    describe '#direct' do\n      let(:view) { double }\n      let(:field) do\n        RailsAdmin.config('FieldTest').fields.detect do |f|\n          f.name == :active_storage_asset\n        end.with(view: view)\n      end\n      before do\n        allow(view).to receive_message_chain(:main_app, :rails_direct_uploads_url) { 'http://www.example.com/rails/active_storage/direct_uploads' }\n      end\n\n      context 'when false' do\n        it \"doesn't put the direct upload url in html_attributes\" do\n          expect(field.html_attributes[:data]&.[](:direct_upload_url)).to be_nil\n        end\n      end\n\n      context 'when true' do\n        before do\n          RailsAdmin.config FieldTest do\n            field(:active_storage_asset) { direct true }\n          end\n        end\n\n        it 'puts the direct upload url in html_attributes' do\n          expect(field.html_attributes[:data]&.[](:direct_upload_url)).to eq 'http://www.example.com/rails/active_storage/direct_uploads'\n        end\n      end\n    end\n\n    describe '#searchable' do\n      it 'is false' do\n        expect(field.searchable).to be false\n      end\n    end\n\n    describe '#sortable' do\n      it 'is false' do\n        expect(field.sortable).to be false\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/belongs_to_association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::BelongsToAssociation do\n  it_behaves_like 'a generic field type', :integer_field, :belongs_to_association\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/boolean_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Boolean do\n  it_behaves_like 'a generic field type', :boolean_field, :boolean\n\n  subject do\n    RailsAdmin.config(FieldTest).fields.detect do |f|\n      f.name == :boolean_field\n    end.with(object: test_object)\n  end\n\n  describe '#pretty_value' do\n    {\n      false => %(<span class=\"badge bg-danger\"><span class=\"fas fa-times\"></span></span>),\n      true => %(<span class=\"badge bg-success\"><span class=\"fas fa-check\"></span></span>),\n      nil => %(<span class=\"badge bg-default\"><span class=\"fas fa-minus\"></span></span>),\n    }.each do |field_value, expected_result|\n      context \"when field value is '#{field_value.inspect}'\" do\n        let(:test_object) { FieldTest.new(boolean_field: field_value) }\n\n        it 'returns the appropriate html result' do\n          expect(subject.pretty_value).to eq(expected_result)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/bson_object_id_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::BsonObjectId do\n  it_behaves_like 'a generic field type', :string_field, :bson_object_id\n\n  describe '#parse_value' do\n    let(:bson) { RailsAdmin::Adapters::Mongoid::Bson::OBJECT_ID.new }\n    let(:field) do\n      RailsAdmin.config(FieldTest).fields.detect do |f|\n        f.name == :bson_object_id_field\n      end\n    end\n\n    before :each do\n      RailsAdmin.config do |config|\n        config.model FieldTest do\n          field :bson_object_id_field, :bson_object_id\n        end\n      end\n    end\n\n    it 'parse valid bson_object_id', mongoid: true do\n      expect(field.parse_value(bson.to_s)).to eq bson\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/carrierwave_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Carrierwave do\n  it_behaves_like 'a generic field type', :string_field, :carrierwave\n\n  describe '#thumb_method' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :carrierwave_asset, :carrierwave\n      end\n    end\n\n    let :rails_admin_field do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :carrierwave_asset\n      end.with(\n        object: FieldTest.new(string_field: 'dummy.txt'),\n        view: ApplicationController.new.view_context,\n      )\n    end\n\n    it 'auto-detects thumb-like version name' do\n      expect(rails_admin_field.thumb_method).to eq :thumb\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/citext_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Citext do\n  it_behaves_like 'a generic field type', :string_field\n\n  it_behaves_like 'a string-like field type', :string_field\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/ck_editor_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::CKEditor do\n  it_behaves_like 'a generic field type', :text_field, :ck_editor\n\n  it_behaves_like 'a string-like field type', :text_field, :ck_editor\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/code_mirror_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::CodeMirror do\n  it_behaves_like 'a generic field type', :text_field, :code_mirror\n\n  it_behaves_like 'a string-like field type', :text_field, :code_mirror\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/color_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Color do\n  it_behaves_like 'a generic field type', :string_field, :color\n\n  it_behaves_like 'a string-like field type', :string_field, :color\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/date_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Date do\n  it_behaves_like 'a generic field type', :date_field, :date\n\n  describe '#formatted_value' do\n    it 'gets object value' do\n      field = RailsAdmin.config(FieldTest).fields.detect do |f|\n        f.name == :date_field\n      end.with(object: FieldTest.new(date_field: DateTime.parse('02/01/2012')))\n\n      expect(field.formatted_value).to eq 'January 02, 2012'\n    end\n\n    it 'gets default value for new objects if value is nil' do\n      RailsAdmin.config(FieldTest) do |_config|\n        field :date_field do\n          default_value DateTime.parse('01/01/2012')\n        end\n      end\n\n      field = RailsAdmin.config(FieldTest).fields.detect do |f|\n        f.name == :date_field\n      end.with(object: FieldTest.new)\n\n      expect(field.formatted_value).to eq 'January 01, 2012'\n    end\n  end\n\n  describe '#parse_input' do\n    let(:field) { RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :date_field } }\n\n    before :each do\n      @object = FactoryBot.create(:field_test)\n      @time = ::Time.now.getutc\n    end\n\n    after :each do\n      Time.zone = 'UTC'\n    end\n\n    it 'reads %B %d, %Y by default' do\n      @object.date_field = field.parse_input(date_field: @time.strftime('%B %d, %Y'))\n      expect(@object.date_field).to eq(::Date.parse(@time.to_s))\n    end\n\n    it 'covers a timezone lag even if in UTC+n:00 timezone.' do\n      Time.zone = 'Tokyo' # +09:00\n\n      @object.date_field = field.parse_input(date_field: @time.strftime('%B %d, %Y'))\n      expect(@object.date_field).to eq(::Date.parse(@time.to_s))\n    end\n\n    it 'has a simple customization option' do\n      RailsAdmin.config FieldTest do\n        field :date_field do\n          date_format do\n            :default\n          end\n        end\n      end\n\n      @object.date_field = field.parse_input(date_field: @time.strftime('%Y-%m-%d'))\n      expect(@object.date_field).to eq(::Date.parse(@time.to_s))\n    end\n\n    it 'has a customization option' do\n      RailsAdmin.config FieldTest do\n        field :date_field do\n          strftime_format '%Y/%m/%d'\n        end\n      end\n\n      @object.date_field = field.parse_input(date_field: @time.strftime('%Y/%m/%d'))\n      expect(@object.date_field).to eq(::Date.parse(@time.to_s))\n    end\n  end\n\n  describe '#default_value' do\n    let(:field) do\n      field = RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :date_field }\n      field.bindings = {object: @object}\n      field\n    end\n\n    before :each do\n      RailsAdmin.config FieldTest do\n        field :date_field do\n          default_value Date.current\n        end\n      end\n      @object = FactoryBot.create(:field_test)\n      @time = ::Time.now.getutc\n    end\n\n    it 'should contain the default value' do\n      expect(field.default_value).to eq(Date.current)\n    end\n\n    it 'should propagate to the field formatted_value when the object is a new record' do\n      object = FactoryBot.build(:field_test)\n      field.bindings = {object: object}\n      expect(field.formatted_value).to eq(Date.current.strftime('%B %d, %Y'))\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/datetime_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Datetime do\n  it_behaves_like 'a generic field type', :datetime_field, :datetime\n\n  describe '#formatted_value' do\n    it 'gets object value' do\n      field = RailsAdmin.config(FieldTest).fields.detect do |f|\n        f.name == :datetime_field\n      end.with(object: FieldTest.new(datetime_field: DateTime.parse('02/01/2012')))\n\n      expect(field.formatted_value).to eq 'January 02, 2012 00:00'\n    end\n\n    it 'gets default value for new objects if value is nil' do\n      RailsAdmin.config(FieldTest) do |_config|\n        field :datetime_field do\n          default_value DateTime.parse('01/01/2012')\n        end\n      end\n\n      field = RailsAdmin.config(FieldTest).fields.detect do |f|\n        f.name == :datetime_field\n      end.with(object: FieldTest.new)\n\n      expect(field.formatted_value).to eq 'January 01, 2012 00:00'\n    end\n  end\n\n  describe '#parse_input' do\n    let(:field) { RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :datetime_field } }\n\n    before :each do\n      @object = FactoryBot.create(:field_test)\n      @time = ::Time.now.getutc\n    end\n\n    after :each do\n      Time.zone = 'UTC'\n    end\n\n    it 'is able to read %B %-d, %Y %H:%M' do\n      @object = FactoryBot.create(:field_test)\n      @object.datetime_field = field.parse_input(datetime_field: @time.strftime('%B %-d, %Y %H:%M'))\n      expect(@object.datetime_field.strftime('%Y-%m-%d %H:%M')).to eq(@time.strftime('%Y-%m-%d %H:%M'))\n    end\n\n    it 'is able to read %a, %d %b %Y %H:%M:%S %z' do\n      RailsAdmin.config FieldTest do\n        field :datetime_field do\n          date_format do\n            :default\n          end\n        end\n      end\n\n      @object = FactoryBot.create(:field_test)\n      @object.datetime_field = field.parse_input(datetime_field: @time.strftime('%a, %d %b %Y %H:%M:%S %z'))\n      expect(@object.datetime_field.to_formatted_s(:rfc822)).to eq(@time.to_formatted_s(:rfc822))\n    end\n\n    it 'has a customization option' do\n      RailsAdmin.config FieldTest do\n        field :datetime_field do\n          strftime_format do\n            '%Y-%m-%d %H:%M:%S'\n          end\n        end\n      end\n\n      @object = FactoryBot.create(:field_test)\n      @object.datetime_field = field.parse_input(datetime_field: @time.strftime('%Y-%m-%d %H:%M:%S'))\n      expect(@object.datetime_field.to_formatted_s(:rfc822)).to eq(@time.to_formatted_s(:rfc822))\n    end\n\n    it 'does round-trip saving properly with non-UTC timezones' do\n      RailsAdmin.config FieldTest do\n        field :datetime_field do\n          date_format do\n            :default\n          end\n        end\n      end\n\n      Time.zone = 'Vienna'\n      @object = FactoryBot.create(:field_test)\n      @object.datetime_field = field.parse_input(datetime_field: 'Sat, 01 Sep 2012 12:00:00 +0200')\n      expect(@object.datetime_field).to eq(Time.zone.parse('2012-09-01 12:00:00 +02:00'))\n    end\n\n    it 'changes formats when the locale changes' do\n      french_format = '%A %d %B %Y %H:%M'\n      allow(I18n).to receive(:t).with(:long, scope: %i[time formats], raise: true).and_return(french_format)\n      @object = FactoryBot.create(:field_test)\n      @object.datetime_field = field.parse_input(datetime_field: @time.strftime(french_format))\n      expect(@object.datetime_field.strftime(french_format)).to eq(@time.strftime(french_format))\n\n      american_format = '%B %d, %Y %H:%M'\n      allow(I18n).to receive(:t).with(:long, scope: %i[time formats], raise: true).and_return(american_format)\n      @object = FactoryBot.create(:field_test)\n      @object.datetime_field = field.parse_input(datetime_field: @time.strftime(american_format))\n      expect(@object.datetime_field.strftime(american_format)).to eq(@time.strftime(american_format))\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/decimal_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Decimal do\n  it_behaves_like 'a float-like field type', :float_field\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/drangonfly_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Dragonfly do\n  it_behaves_like 'a generic field type', :string_field, :dragonfly\n\n  let(:field) do\n    RailsAdmin.config('FieldTest').fields.detect do |f|\n      f.name == :dragonfly_asset\n    end.with(object: record)\n  end\n\n  describe '#image?' do\n    let(:file) { File.open(file_path('test.jpg')) }\n    let(:record) { FactoryBot.create :field_test, dragonfly_asset: file }\n\n    it 'returns true' do\n      expect(field.image?).to be true\n    end\n\n    context 'with non-image' do\n      let(:file) { File.open(file_path('test.txt')) }\n\n      it 'returns false' do\n        expect(field.image?).to be false\n      end\n    end\n  end\n\n  describe 'with a model which does not extend Dragonfly::Model' do\n    before do\n      class NonDragonflyTest < Tableless\n        column :asset_uid, :varchar\n      end\n    end\n\n    it 'does not break' do\n      expect { RailsAdmin.config(NonDragonflyTest).fields }.not_to raise_error\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/enum_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Enum do\n  it_behaves_like 'a generic field type', :string_field, :enum\n\n  subject { RailsAdmin.config(Team).field(:color) }\n\n  describe \"when object responds to '\\#{method}_enum'\" do\n    before do\n      allow_any_instance_of(Team).to receive(:color_enum).and_return(%w[blue green red])\n      RailsAdmin.config Team do\n        edit do\n          field :color\n        end\n      end\n    end\n\n    it 'auto-detects enumeration' do\n      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)\n      is_expected.not_to be_multiple\n      expect(subject.with(object: Team.new).enum).to eq %w[blue green red]\n    end\n  end\n\n  describe \"when class responds to '\\#{method}_enum'\" do\n    before do\n      allow(Team).to receive(:color_enum).and_return(%w[blue green red])\n      Team.instance_eval do\n        def color_enum\n          %w[blue green red]\n        end\n      end\n      RailsAdmin.config Team do\n        edit do\n          field :color\n        end\n      end\n    end\n\n    it 'auto-detects enumeration' do\n      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)\n      expect(subject.with(object: Team.new).enum).to eq %w[blue green red]\n    end\n  end\n\n  describe 'the enum instance method' do\n    before do\n      Team.class_eval do\n        def color_list\n          %w[blue green red]\n        end\n      end\n      RailsAdmin.config Team do\n        field :color, :enum do\n          enum_method :color_list\n        end\n      end\n    end\n\n    after do\n      Team.send(:remove_method, :color_list)\n    end\n\n    it 'allows configuration' do\n      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)\n      expect(subject.with(object: Team.new).enum).to eq %w[blue green red]\n    end\n  end\n\n  describe 'the enum class method' do\n    before do\n      Team.instance_eval do\n        def color_list\n          %w[blue green red]\n        end\n      end\n      RailsAdmin.config Team do\n        field :color, :enum do\n          enum_method :color_list\n        end\n      end\n    end\n\n    after do\n      Team.instance_eval { undef :color_list }\n    end\n\n    it 'allows configuration' do\n      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)\n      expect(subject.with(object: Team.new).enum).to eq %w[blue green red]\n    end\n  end\n\n  describe 'when overriding enum configuration' do\n    before do\n      Team.class_eval do\n        def color_list\n          %w[blue green red]\n        end\n      end\n      RailsAdmin.config Team do\n        field :color, :enum do\n          enum_method :color_list\n          enum do\n            %w[yellow black]\n          end\n        end\n      end\n    end\n\n    after do\n      Team.send(:remove_method, :color_list)\n    end\n\n    it 'allows direct listing of enumeration options and override enum method' do\n      is_expected.to be_a(RailsAdmin::Config::Fields::Types::Enum)\n      expect(subject.with(object: Team.new).enum).to eq %w[yellow black]\n    end\n  end\n\n  describe 'when serialize is enabled in ActiveRecord model', active_record: true do\n    subject { RailsAdmin.config(TeamWithSerializedEnum).field(:color) }\n\n    before do\n      class TeamWithSerializedEnum < Team\n        self.table_name = 'teams'\n        if ActiveRecord.gem_version < Gem::Version.new('7.1')\n          serialize :color\n        else\n          serialize :color, coder: JSON\n        end\n        def color_enum\n          %w[blue green red]\n        end\n      end\n      RailsAdmin.config do |c|\n        c.included_models = [TeamWithSerializedEnum]\n      end\n    end\n\n    it 'makes enumeration multi-selectable' do\n      is_expected.to be_multiple\n    end\n  end\n\n  describe 'when serialize is enabled in Mongoid model', mongoid: true do\n    before do\n      allow(Team).to receive(:color_enum).and_return(%w[blue green red])\n      Team.instance_eval do\n        field :color, type: Array\n      end\n    end\n\n    after do\n      Team.instance_eval do\n        field :color, type: String\n      end\n    end\n\n    it 'makes enumeration multi-selectable' do\n      is_expected.to be_multiple\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/file_upload_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::FileUpload do\n  it_behaves_like 'a generic field type', :string_field, :file_upload\n\n  describe '#allowed_methods' do\n    it 'includes delete_method and cache_method' do\n      RailsAdmin.config do |config|\n        config.model FieldTest do\n          field :carrierwave_asset\n          field :dragonfly_asset\n          field :paperclip_asset do\n            delete_method :delete_paperclip_asset\n          end\n          if defined?(ActiveStorage)\n            field :active_storage_asset do\n              delete_method :remove_active_storage_asset\n            end\n          end\n          if defined?(Shrine)\n            field :shrine_asset do\n              delete_method :remove_shrine_asset\n              cache_method :cached_shrine_asset_data\n            end\n          end\n        end\n      end\n      expect(RailsAdmin.config(FieldTest).field(:carrierwave_asset).allowed_methods.collect(&:to_s)).to eq %w[carrierwave_asset remove_carrierwave_asset carrierwave_asset_cache]\n      expect(RailsAdmin.config(FieldTest).field(:dragonfly_asset).allowed_methods.collect(&:to_s)).to eq %w[dragonfly_asset remove_dragonfly_asset retained_dragonfly_asset]\n      expect(RailsAdmin.config(FieldTest).field(:paperclip_asset).allowed_methods.collect(&:to_s)).to eq %w[paperclip_asset delete_paperclip_asset]\n      expect(RailsAdmin.config(FieldTest).field(:active_storage_asset).allowed_methods.collect(&:to_s)).to eq %w[active_storage_asset remove_active_storage_asset] if defined?(ActiveStorage)\n      expect(RailsAdmin.config(FieldTest).field(:shrine_asset).allowed_methods.collect(&:to_s)).to eq %w[shrine_asset remove_shrine_asset cached_shrine_asset_data] if defined?(Shrine)\n    end\n  end\n\n  describe '#html_attributes' do\n    context 'when the field is required and value is already set' do\n      before do\n        RailsAdmin.config FieldTest do\n          field :string_field, :file_upload do\n            required true\n          end\n        end\n      end\n\n      let :rails_admin_field do\n        RailsAdmin.config('FieldTest').fields.detect do |f|\n          f.name == :string_field\n        end.with(object: FieldTest.new(string_field: 'dummy.jpg'))\n      end\n\n      it 'does not have a required attribute' do\n        expect(rails_admin_field.html_attributes[:required]).to be_falsy\n      end\n    end\n  end\n\n  describe '#pretty_value' do\n    context 'when the field is not image' do\n      before do\n        RailsAdmin.config FieldTest do\n          field :string_field, :file_upload do\n            def resource_url\n              'http://example.com/dummy.txt'\n            end\n          end\n        end\n      end\n\n      let :rails_admin_field do\n        RailsAdmin.config('FieldTest').fields.detect do |f|\n          f.name == :string_field\n        end.with(\n          object: FieldTest.new(string_field: 'dummy.txt'),\n          view: ApplicationController.new.view_context,\n        )\n      end\n\n      it 'uses filename as link text' do\n        expect(Nokogiri::HTML(rails_admin_field.pretty_value).text).to eq 'dummy.txt'\n      end\n    end\n  end\n\n  describe '#image?' do\n    let(:filename) { 'dummy.txt' }\n    let :rails_admin_field do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :string_field\n      end.with(\n        object: FieldTest.new(string_field: filename),\n        view: ApplicationController.new.view_context,\n      )\n    end\n    before do\n      RailsAdmin.config FieldTest do\n        field :string_field, :file_upload do\n          def resource_url\n            \"http://example.com/#{value}\"\n          end\n        end\n      end\n    end\n\n    context 'when the file is not an image' do\n      let(:filename) { 'dummy.txt' }\n\n      it 'returns false' do\n        expect(rails_admin_field.image?).to be false\n      end\n    end\n\n    context 'when the file is an image' do\n      let(:filename) { 'dummy.jpg' }\n\n      it 'returns true' do\n        expect(rails_admin_field.image?).to be true\n      end\n    end\n\n    context 'when the file is an image but suffixed with a query string' do\n      let(:filename) { 'dummy.jpg?foo=bar' }\n\n      it 'returns true' do\n        expect(rails_admin_field.image?).to be true\n      end\n    end\n\n    context \"when the filename can't be represented as a valid URI\" do\n      let(:filename) { 'du mmy.jpg' }\n\n      it 'returns false' do\n        expect(rails_admin_field.image?).to be false\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/float_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Float do\n  it_behaves_like 'a float-like field type', :float_field\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/froala_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Froala do\n  it_behaves_like 'a generic field type', :text_field, :froala\n\n  it_behaves_like 'a string-like field type', :text_field, :froala\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/has_and_belongs_to_many_association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::HasAndBelongsToManyAssociation do\n  it_behaves_like 'a generic field type', :integer_field, :has_and_belongs_to_many_association\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/has_many_association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::HasManyAssociation do\n  it_behaves_like 'a generic field type', :integer_field, :has_many_association\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/has_one_association_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::HasOneAssociation do\n  it_behaves_like 'a generic field type', :integer_field, :has_one_association\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/hidden_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Hidden do\n  it_behaves_like 'a generic field type', :integer_field, :hidden\n\n  it_behaves_like 'a string-like field type', :string_field, :hidden\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/inet_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Inet do\n  it_behaves_like 'a generic field type', :string_field, :inet\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/integer_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Integer do\n  it_behaves_like 'a generic field type', :integer_field, :integer\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/json_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Json do\n  let(:field) { RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :json_field } }\n  let(:object) { FieldTest.new }\n  let(:bindings) do\n    {\n      object: object,\n      view: ApplicationController.new.view_context,\n    }\n  end\n\n  describe '#formatted_value' do\n    before do\n      RailsAdmin.config do |config|\n        config.model FieldTest do\n          field :json_field, :json\n        end\n      end\n    end\n\n    it 'returns correct value for empty json' do\n      allow(object).to receive(:json_field) { {} }\n      actual = field.with(bindings).formatted_value\n      expect(actual).to match(/{\\n*}/)\n    end\n\n    it 'retuns correct value' do\n      allow(object).to receive(:json_field) { {sample_key: 'sample_value'} }\n      actual = field.with(bindings).formatted_value\n      expected = [\n        '{',\n        '  \"sample_key\": \"sample_value\"',\n        '}',\n      ].join(\"\\n\")\n      expect(actual).to eq(expected)\n    end\n  end\n\n  describe '#pretty_value' do\n    before do\n      RailsAdmin.config do |config|\n        config.model FieldTest do\n          field :json_field, :json\n        end\n      end\n    end\n\n    it 'retuns correct value' do\n      allow(object).to receive(:json_field) { {sample_key: 'sample_value'} }\n      actual = field.with(bindings).pretty_value\n      expected = [\n        '<pre>{',\n        '  &quot;sample_key&quot;: &quot;sample_value&quot;',\n        '}</pre>',\n      ].join(\"\\n\")\n      expect(actual).to eq(expected)\n    end\n  end\n\n  describe '#export_value' do\n    before do\n      RailsAdmin.config do |config|\n        config.model FieldTest do\n          field :json_field, :json\n        end\n      end\n    end\n\n    it 'returns correct value for empty json' do\n      allow(object).to receive(:json_field) { {} }\n      actual = field.with(bindings).export_value\n      expect(actual).to match(/{\\n*}/)\n    end\n\n    it 'returns correct value' do\n      allow(object).to receive(:json_field) { {sample_key: 'sample_value'} }\n      actual = field.with(bindings).export_value\n      expected = [\n        '{',\n        '  \"sample_key\": \"sample_value\"',\n        '}',\n      ].join(\"\\n\")\n      expect(actual).to eq(expected)\n    end\n  end\n\n  describe '#parse_input' do\n    before :each do\n      RailsAdmin.config do |config|\n        config.model FieldTest do\n          field :json_field, :json\n        end\n      end\n    end\n\n    it 'parse valid json string' do\n      data = {string: 'string', integer: 1, array: [1, 2, 3], object: {bla: 'foo'}}.as_json\n      expect(field.parse_input(json_field: data.to_json)).to eq data\n    end\n\n    it 'raise JSON::ParserError with invalid json string' do\n      expect { field.parse_input(json_field: '{{') }.to raise_error(JSON::ParserError)\n    end\n  end\n\n  describe 'aliasing' do\n    before :each do\n      RailsAdmin.config do |config|\n        config.model FieldTest do\n          field :json_field, :jsonb\n        end\n      end\n    end\n\n    it 'allows use of :jsonb fieldtype' do\n      expect(field.class).to eq RailsAdmin::Config::Fields::Types::Json\n    end\n  end\n\n  it_behaves_like 'a generic field type', :text, :json\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/multiple_active_storage_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nif defined?(ActiveStorage)\n  RSpec.describe RailsAdmin::Config::Fields::Types::MultipleActiveStorage do\n    it_behaves_like 'a generic field type', :string_field, :multiple_active_storage\n\n    let(:record) { FactoryBot.create :field_test }\n    let(:field) do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :active_storage_assets\n      end.with(\n        object: record,\n        view: ApplicationController.new.view_context,\n      )\n    end\n\n    describe RailsAdmin::Config::Fields::Types::MultipleActiveStorage::ActiveStorageAttachment do\n      describe '#thumb_method' do\n        let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.txt', content_type: 'text/plain'}] }\n        subject { field.attachments[0] }\n\n        it 'returns corresponding value which is to be passed to image_processing(ActiveStorage >= 6.0) or mini_magick(ActiveStorage 5.2)' do\n          expect(subject.thumb_method).to eq(resize_to_limit: [100, 100])\n        end\n      end\n\n      describe '#pretty_value' do\n        subject { field.pretty_value }\n\n        context 'when attachment is not an image' do\n          let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.txt', content_type: 'text/plain'}] }\n\n          it 'uses filename as link text' do\n            expect(Nokogiri::HTML(subject).text).to eq 'test.txt'\n          end\n        end\n\n        context 'when the field is an image' do\n          let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.jpg', content_type: 'image/jpeg'}] }\n\n          it 'shows thumbnail image with a link' do\n            expect(Nokogiri::HTML(subject).css('img').attribute('src').value).to match(%r{rails/active_storage/representations})\n            expect(Nokogiri::HTML(subject).css('a').attribute('href').value).to match(%r{rails/active_storage/blobs})\n          end\n        end\n      end\n\n      describe '#image?' do\n        context 'when attachment is an image' do\n          let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.jpg', content_type: 'image/jpeg'}] }\n\n          it 'returns true' do\n            expect(field.attachments[0].image?).to be_truthy\n          end\n        end\n\n        context 'when attachment is not an image' do\n          let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.txt', content_type: 'text/plain'}] }\n\n          it 'returns false' do\n            expect(field.attachments[0].image?).to be_falsy\n          end\n        end\n\n        context 'when attachment is a PDF file' do\n          let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.pdf', content_type: 'application/pdf'}] }\n          before { allow(ActiveStorage::Previewer::PopplerPDFPreviewer).to receive(:accept?).and_return(true) }\n\n          it 'returns true' do\n            expect(field.attachments[0].image?).to be_truthy\n          end\n        end\n      end\n\n      describe '#resource_url' do\n        context 'when calling with thumb = false' do\n          let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.jpg', content_type: 'image/jpeg'}] }\n\n          it 'returns original url' do\n            expect(field.attachments[0].resource_url).not_to match(/representations/)\n          end\n        end\n\n        context 'when attachment is an image' do\n          let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.jpg', content_type: 'image/jpeg'}] }\n\n          it 'returns variant\\'s url' do\n            expect(field.attachments[0].resource_url(true)).to match(/representations/)\n          end\n        end\n\n        context 'when attachment is not an image' do\n          let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.txt', content_type: 'text/plain'}] }\n\n          it 'returns original url' do\n            expect(field.attachments[0].resource_url(true)).not_to match(/representations/)\n          end\n        end\n\n        context 'when attachment is a PDF file' do\n          let(:record) { FactoryBot.create :field_test, active_storage_assets: [{io: StringIO.new('dummy'), filename: 'test.pdf', content_type: 'application/pdf'}] }\n          before { allow(ActiveStorage::Previewer::PopplerPDFPreviewer).to receive(:accept?).and_return(true) }\n\n          it 'returns variant\\'s url' do\n            expect(field.attachments[0].resource_url(true)).to match(/representations/)\n          end\n        end\n      end\n    end\n\n    describe '#eager_load' do\n      it 'points to associations to be eager-loaded' do\n        expect(field.eager_load).to eq({active_storage_assets_attachments: :blob})\n      end\n    end\n\n    describe '#direct' do\n      let(:view) { double }\n      let(:field) do\n        RailsAdmin.config('FieldTest').fields.detect do |f|\n          f.name == :active_storage_assets\n        end.with(view: view)\n      end\n      before do\n        allow(view).to receive_message_chain(:main_app, :rails_direct_uploads_url) { 'http://www.example.com/rails/active_storage/direct_uploads' }\n      end\n\n      context 'when false' do\n        it \"doesn't put the direct upload url in html_attributes\" do\n          expect(field.html_attributes[:data]&.[](:direct_upload_url)).to be_nil\n        end\n      end\n\n      context 'when true' do\n        before do\n          RailsAdmin.config FieldTest do\n            field(:active_storage_assets) { direct true }\n          end\n        end\n\n        it 'puts the direct upload url in html_attributes' do\n          expect(field.html_attributes[:data]&.[](:direct_upload_url)).to eq 'http://www.example.com/rails/active_storage/direct_uploads'\n        end\n      end\n    end\n\n    describe '#searchable' do\n      it 'is false' do\n        expect(field.searchable).to be false\n      end\n    end\n\n    describe '#sortable' do\n      it 'is false' do\n        expect(field.sortable).to be false\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/multiple_carrierwave_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\nrequire 'base64'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::MultipleCarrierwave do\n  it_behaves_like 'a generic field type', :string_field, :multiple_carrierwave\n\n  describe '#thumb_method' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :carrierwave_assets, :multiple_carrierwave\n      end\n    end\n\n    let :rails_admin_field do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :carrierwave_assets\n      end.with(\n        object: FieldTest.new(carrierwave_assets: [File.open(file_path('test.jpg'))]),\n        view: ApplicationController.new.view_context,\n      )\n    end\n\n    it 'auto-detects thumb-like version name' do\n      expect(rails_admin_field.attachments.map(&:thumb_method)).to eq [:thumb]\n    end\n  end\n\n  describe '#delete_value', active_record: true do\n    before do\n      RailsAdmin.config FieldTest do\n        field :carrierwave_assets, :multiple_carrierwave\n      end\n    end\n    let :file do\n      CarrierWave::SanitizedFile.new(\n        tempfile: StringIO.new(Base64.decode64('R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=')),\n        filename: 'dummy.gif',\n      )\n    end\n    let :rails_admin_field do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :carrierwave_assets\n      end.with(\n        object: FieldTest.create(carrierwave_assets: [file]),\n        view: ApplicationController.new.view_context,\n      )\n    end\n\n    it 'does not use file.identifier, which is not available for Fog files' do\n      expect_any_instance_of(CarrierWave::SanitizedFile).not_to receive :identifier\n      expect(rails_admin_field.attachments.map(&:delete_value)).to eq ['dummy.gif']\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/multiple_file_upload_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::MultipleFileUpload do\n  it_behaves_like 'a generic field type', :string_field, :multiple_file_upload\n\n  describe '#allowed_methods' do\n    it 'includes delete_method and cache_method' do\n      RailsAdmin.config do |config|\n        config.model FieldTest do\n          field :carrierwave_assets, :multiple_carrierwave\n          if defined?(ActiveStorage)\n            field :active_storage_assets, :multiple_active_storage do\n              delete_method :remove_active_storage_assets\n            end\n          end\n        end\n      end\n      expect(RailsAdmin.config(FieldTest).field(:carrierwave_assets).with(object: FieldTest.new).allowed_methods.collect(&:to_s)).to eq %w[carrierwave_assets]\n      expect(RailsAdmin.config(FieldTest).field(:active_storage_assets).with(object: FieldTest.new).allowed_methods.collect(&:to_s)).to eq %w[active_storage_assets remove_active_storage_assets] if defined?(ActiveStorage)\n    end\n  end\n\n  describe '#html_attributes' do\n    context 'when the field is required and value is already set' do\n      before do\n        RailsAdmin.config FieldTest do\n          field :string_field, :multiple_file_upload do\n            required true\n          end\n        end\n      end\n\n      let :rails_admin_field do\n        RailsAdmin.config('FieldTest').fields.detect do |f|\n          f.name == :string_field\n        end.with(object: FieldTest.new(string_field: 'dummy.jpg'))\n      end\n\n      it 'does not have a required attribute' do\n        expect(rails_admin_field.html_attributes[:required]).to be_falsy\n      end\n    end\n  end\n\n  describe '#pretty_value' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :string_field, :multiple_file_upload do\n          attachment do\n            thumb_method 'thumb'\n\n            def resource_url(thumb = false)\n              if thumb\n                \"http://example.com/#{thumb}/#{value}\"\n              else\n                \"http://example.com/#{value}\"\n              end\n            end\n          end\n        end\n      end\n    end\n\n    let(:filename) { '' }\n\n    let :rails_admin_field do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :string_field\n      end.with(\n        object: FieldTest.new(string_field: filename),\n        view: ApplicationController.new.view_context,\n      )\n    end\n\n    context 'when the field is not an image' do\n      let(:filename) { 'dummy.txt' }\n\n      it 'uses filename as link text' do\n        expect(Nokogiri::HTML(rails_admin_field.pretty_value).text).to eq 'dummy.txt'\n      end\n    end\n\n    context 'when the field is an image' do\n      let(:filename) { 'dummy.jpg' }\n\n      subject { Nokogiri::HTML(rails_admin_field.pretty_value) }\n\n      it 'shows thumbnail image with a link' do\n        expect(subject.css('img').attribute('src').value).to eq 'http://example.com/thumb/dummy.jpg'\n        expect(subject.css('a').attribute('href').value).to eq 'http://example.com/dummy.jpg'\n      end\n    end\n  end\n\n  describe '#attachment' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :string_field, :multiple_file_upload do\n          attachment do\n            delete_value 'something'\n\n            def resource_url(_thumb = false)\n              \"http://example.com/#{value}\"\n            end\n          end\n\n          def value\n            ['foo.jpg']\n          end\n        end\n      end\n    end\n\n    let :rails_admin_field do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :string_field\n      end.with(\n        view: ApplicationController.new.view_context,\n      )\n    end\n\n    it 'enables configuration' do\n      expect(rails_admin_field.attachments.map(&:delete_value)).to eq ['something']\n      expect(rails_admin_field.attachments.map(&:resource_url)).to eq ['http://example.com/foo.jpg']\n      expect(rails_admin_field.pretty_value).to match(%r{src=\"http://example.com/foo.jpg\"})\n    end\n  end\n\n  describe '#attachments' do\n    before do\n      RailsAdmin.config FieldTest do\n        field :string_field, :multiple_file_upload\n      end\n    end\n\n    let :rails_admin_field do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :string_field\n      end\n    end\n\n    it 'wraps value with Array()' do\n      expect(rails_admin_field.with(object: FieldTest.new(string_field: nil)).attachments).to eq []\n      expect(rails_admin_field.with(object: FieldTest.new(string_field: 'dummy.txt')).attachments.map(&:value)).to eq ['dummy.txt']\n    end\n  end\n\n  describe '#image?' do\n    let(:filename) { 'dummy.txt' }\n    let :rails_admin_field do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :string_field\n      end.with(\n        object: FieldTest.new(string_field: filename),\n        view: ApplicationController.new.view_context,\n      )\n    end\n    before do\n      RailsAdmin.config FieldTest do\n        field :string_field, :multiple_file_upload do\n          attachment do\n            def resource_url\n              \"http://example.com/#{value}\"\n            end\n          end\n        end\n      end\n    end\n\n    context 'when the file is not an image' do\n      let(:filename) { 'dummy.txt' }\n\n      it 'returns false' do\n        expect(rails_admin_field.attachments.first.image?).to be false\n      end\n    end\n\n    context 'when the file is an image' do\n      let(:filename) { 'dummy.jpg' }\n\n      it 'returns true' do\n        expect(rails_admin_field.attachments.first.image?).to be true\n      end\n    end\n\n    context 'when the file is an image but suffixed with a query string' do\n      let(:filename) { 'dummy.jpg?foo=bar' }\n\n      it 'returns true' do\n        expect(rails_admin_field.attachments.first.image?).to be true\n      end\n    end\n\n    context \"when the filename can't be represented as a valid URI\" do\n      let(:filename) { 'du mmy.jpg' }\n\n      it 'returns false' do\n        expect(rails_admin_field.attachments.first.image?).to be false\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/numeric_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Numeric do\n  it_behaves_like 'a generic field type', :integer_field, :integer\n\n  subject do\n    RailsAdmin.config('FieldTest').fields.detect do |f|\n      f.name == :integer_field\n    end.with(object: FieldTest.new)\n  end\n\n  describe '#view_helper' do\n    it \"uses the 'number' type input tag\" do\n      expect(subject.view_helper).to eq(:number_field)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/paperclip_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Paperclip do\n  it_behaves_like 'a generic field type', :string_field, :paperclip\n\n  context 'when a *_file_name field exists but not declared as has_attached_file' do\n    before do\n      class PaperclipTest < Tableless\n        column :some_file_name, :varchar\n      end\n      RailsAdmin.config.included_models = [PaperclipTest]\n    end\n\n    it 'does not break' do\n      expect { RailsAdmin.config(PaperclipTest).fields }.not_to raise_error\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/password_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Password do\n  it_behaves_like 'a generic field type', :string_field, :password\n\n  describe '#parse_input' do\n    let(:field) do\n      RailsAdmin.config(User).fields.detect do |f|\n        f.name == :password\n      end\n    end\n\n    context 'if password is not present' do\n      let(:nil_params) { {password: nil} }\n      let(:blank_params) { {password: ''} }\n\n      it 'cleans nil' do\n        field.parse_input(nil_params)\n        expect(nil_params).to eq({})\n        field.parse_input(blank_params)\n        expect(blank_params).to eq({})\n      end\n    end\n\n    context 'if password is present' do\n      let(:params) { {password: 'aaa'} }\n\n      it 'keeps the value' do\n        field.parse_input(params)\n        expect(params).to eq(password: 'aaa')\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/serialized_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Serialized do\n  it_behaves_like 'a generic field type', :text_field, :serialized\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/shrine_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nif defined?(Shrine)\n  RSpec.describe RailsAdmin::Config::Fields::Types::Shrine do\n    context 'when asset is an image with versions' do\n      let(:record) { FactoryBot.create :field_test, shrine_versioning_asset: FakeIO.new('dummy', filename: 'test.jpg', content_type: 'image/jpeg') }\n\n      let(:field) do\n        RailsAdmin.config('FieldTest').fields.detect do |f|\n          f.name == :shrine_versioning_asset\n        end.with(object: record)\n      end\n\n      before do\n        if Gem.loaded_specs['shrine'].version >= Gem::Version.create('3')\n          if record.shrine_versioning_asset\n            record.shrine_versioning_asset_derivatives!\n            record.save\n          end\n        else\n          skip\n        end\n      end\n\n      describe '#image?' do\n        it 'returns true' do\n          expect(field.image?).to be_truthy\n        end\n      end\n\n      describe '#link_name' do\n        it 'returns filename' do\n          expect(field.link_name).to eq('test.jpg')\n        end\n      end\n\n      describe '#value' do\n        context 'when attachment exists' do\n          it 'returns attached object' do\n            expect(field.value).to be_a(ShrineVersioningUploader::UploadedFile)\n          end\n        end\n\n        context 'when attachment does not exist' do\n          let(:record) { FactoryBot.create :field_test }\n\n          it 'returns nil' do\n            expect(field.value).to be_nil\n          end\n        end\n      end\n\n      describe '#thumb_method' do\n        it 'returns :thumb' do\n          expect(field.thumb_method).to eq(:thumb)\n        end\n      end\n\n      describe '#resource_url' do\n        context 'when calling without thumb' do\n          it 'returns original url' do\n            expect(field.resource_url).to_not match(/thumb-/)\n          end\n        end\n\n        context 'when calling with thumb' do\n          it 'returns thumb url' do\n            expect(field.resource_url(field.thumb_method)).to match(/thumb-/)\n          end\n        end\n      end\n    end\n\n    context 'when asset without versions' do\n      let(:record) { FactoryBot.create :field_test }\n      let(:field) do\n        RailsAdmin.config('FieldTest').fields.detect do |f|\n          f.name == :shrine_asset\n        end.with(object: record)\n      end\n\n      describe '#image?' do\n        context 'when attachment is an image' do\n          let(:record) { FactoryBot.create :field_test, shrine_asset: FakeIO.new('dummy', filename: 'test.jpg', content_type: 'image/jpeg') }\n\n          it 'returns true' do\n            expect(field.image?).to be_truthy\n          end\n        end\n\n        context 'when attachment is not an image' do\n          let(:record) { FactoryBot.create :field_test, shrine_asset: FakeIO.new('dummy', filename: 'test.txt', content_type: 'text/plain') }\n\n          it 'returns false' do\n            expect(field.image?).to be_falsy\n          end\n        end\n      end\n\n      describe '#value' do\n        context 'when attachment exists' do\n          let(:record) { FactoryBot.create :field_test, shrine_asset: FakeIO.new('dummy', filename: 'test.txt', content_type: 'text/plain') }\n\n          it 'returns attached object' do\n            expect(field.value).to be_a(ShrineUploader::UploadedFile)\n          end\n        end\n\n        context 'when attachment does not exist' do\n          it 'returns nil' do\n            expect(field.value).to be_nil\n          end\n        end\n      end\n\n      describe '#thumb_method' do\n        let(:record) { FactoryBot.create :field_test, shrine_asset: FakeIO.new('dummy', filename: 'test.jpg', content_type: 'image/jpeg') }\n\n        it 'returns nil' do\n          expect(field.thumb_method).to eq(nil)\n        end\n      end\n\n      describe '#resource_url' do\n        context 'when calling without thumb' do\n          let(:record) { FactoryBot.create :field_test, shrine_asset: FakeIO.new('dummy', filename: 'test.txt', content_type: 'text/plain') }\n\n          it 'returns url' do\n            expect(field.resource_url).not_to be_nil\n          end\n        end\n\n        context 'when calling with thumb' do\n          let(:record) { FactoryBot.create :field_test, shrine_asset: FakeIO.new('dummy', filename: 'test.jpg', content_type: 'image/jpeg') }\n\n          it 'returns url' do\n            expect(field.resource_url(field.thumb_method)).not_to be_nil\n          end\n        end\n\n        context 'when attachment does not exist' do\n          it 'returns nil' do\n            expect(field.resource_url).to be_nil\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/simple_mde_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::SimpleMDE do\n  it_behaves_like 'a generic field type', :text_field, :simple_mde\n\n  it_behaves_like 'a string-like field type', :text_field, :simple_mde\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/string_like_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::StringLike do\n  describe '#treat_empty_as_nil?', active_record: true do\n    context 'with a nullable field' do\n      subject do\n        RailsAdmin.config('Team').fields.detect do |f|\n          f.name == :name\n        end.with(object: Team.new)\n      end\n\n      it 'is true' do\n        expect(subject.treat_empty_as_nil?).to be true\n      end\n    end\n\n    context 'with a non-nullable field' do\n      subject do\n        RailsAdmin.config('Team').fields.detect do |f|\n          f.name == :manager\n        end.with(object: Team.new)\n      end\n\n      it 'is false' do\n        expect(subject.treat_empty_as_nil?).to be false\n      end\n    end\n  end\n\n  describe '#parse_input' do\n    subject do\n      RailsAdmin.config('FieldTest').fields.detect do |f|\n        f.name == :string_field\n      end.with(object: FieldTest.new)\n    end\n\n    context 'with treat_empty_as_nil being true' do\n      before do\n        RailsAdmin.config FieldTest do\n          field :string_field do\n            treat_empty_as_nil true\n          end\n        end\n      end\n\n      context 'when value is empty' do\n        let(:params) { {string_field: ''} }\n\n        it 'makes the value nil' do\n          subject.parse_input(params)\n          expect(params.key?(:string_field)).to be true\n          expect(params[:string_field]).to be nil\n        end\n      end\n\n      context 'when value does not exist in params' do\n        let(:params) { {} }\n\n        it 'does not touch params' do\n          subject.parse_input(params)\n          expect(params.key?(:string_field)).to be false\n        end\n      end\n    end\n\n    context 'with treat_empty_as_nil being false' do\n      before do\n        RailsAdmin.config FieldTest do\n          field :string_field do\n            treat_empty_as_nil false\n          end\n        end\n      end\n      let(:params) { {string_field: ''} }\n\n      it 'keeps the value untouched' do\n        subject.parse_input(params)\n        expect(params.key?(:string_field)).to be true\n        expect(params[:string_field]).to eq ''\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/string_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::String do\n  describe '#html_attributes' do\n    before :each do\n      RailsAdmin.config Ball do\n        field 'color', :string\n      end\n    end\n\n    let(:string_field) do\n      RailsAdmin.config('Ball').fields.detect do |f|\n        f.name == :color\n      end.with(object: Ball.new)\n    end\n\n    it 'should contain a size attribute' do\n      expect(string_field.html_attributes[:size]).to be_present\n    end\n\n    it 'should not contain a size attribute valorized with 0' do\n      expect(string_field.html_attributes[:size]).to_not be_zero\n    end\n  end\n\n  it_behaves_like 'a generic field type', :string_field\n\n  it_behaves_like 'a string-like field type', :string_field\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/text_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Text do\n  it_behaves_like 'a generic field type', :text_field\n\n  it_behaves_like 'a string-like field type', :text_field\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/time_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Time, active_record: true do\n  it_behaves_like 'a generic field type', :time_field, :time\n\n  describe '#parse_input' do\n    let(:field) do\n      RailsAdmin.config(FieldTest).fields.detect do |f|\n        f.name == :time_field\n      end\n    end\n\n    before do\n      RailsAdmin.config(FieldTest) do\n        field :time_field, :time\n      end\n    end\n\n    before :each do\n      @object = FactoryBot.create(:field_test)\n      @time = ::Time.new(2000, 1, 1, 3, 45)\n    end\n\n    after :each do\n      Time.zone = 'UTC'\n    end\n\n    it 'reads %H:%M' do\n      @object.time_field = field.parse_input(time_field: @time.strftime('%H:%M'))\n      expect(@object.time_field.strftime('%H:%M')).to eq(@time.strftime('%H:%M'))\n    end\n\n    it 'interprets time value as local time when timezone is specified' do\n      Time.zone = 'Eastern Time (US & Canada)' # -05:00\n      @object.time_field = field.parse_input(time_field: '2000-01-01T03:45:00')\n      expect(@object.time_field.strftime('%H:%M')).to eq('03:45')\n    end\n\n    context 'with a custom strftime_format' do\n      let(:field) do\n        RailsAdmin.config(FieldTest).fields.detect do |f|\n          f.name == :time_field\n        end\n      end\n\n      before do\n        RailsAdmin.config(FieldTest) do\n          field :time_field, :time do\n            strftime_format '%I:%M %p'\n          end\n        end\n      end\n\n      it 'has a customization option' do\n        @object.time_field = field.parse_input(time_field: @time.strftime('%I:%M %p'))\n        expect(@object.time_field.strftime('%H:%M')).to eq(@time.strftime('%H:%M'))\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/timestamp_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Timestamp, active_record: true do\n  it_behaves_like 'a generic field type', :timestamp_field, :timestamp\n\n  describe '#parse_input' do\n    before :each do\n      @object = FactoryBot.create(:field_test)\n      @time = ::Time.now.getutc\n      @field = RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :timestamp_field }\n    end\n\n    after :each do\n      Time.zone = 'UTC'\n    end\n\n    it 'reads %B %d, %Y %H:%M' do\n      @object.timestamp_field = @field.parse_input(timestamp_field: @time.strftime('%B %d, %Y %H:%M'))\n      expect(@object.timestamp_field.strftime('%Y-%m-%d %H:%M')).to eq(@time.strftime('%Y-%m-%d %H:%M'))\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/uuid_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Uuid do\n  let(:uuid) { SecureRandom.uuid }\n  let(:object) { FactoryBot.create(:field_test) }\n  let(:field) { RailsAdmin.config(FieldTest).fields.detect { |f| f.name == :uuid_field } }\n\n  before do\n    RailsAdmin.config do |config|\n      config.model FieldTest do\n        field :uuid_field, :uuid\n      end\n    end\n\n    allow(object).to receive(:uuid_field).and_return uuid\n    field.bindings = {object: object}\n  end\n\n  it 'field is a Uuid fieldtype' do\n    expect(field.class).to eq RailsAdmin::Config::Fields::Types::Uuid\n  end\n\n  it 'handles uuid string' do\n    expect(field.value).to eq uuid\n  end\n\n  it_behaves_like 'a generic field type', :string_field, :uuid\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields/types/wysihtml5_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields::Types::Wysihtml5 do\n  it_behaves_like 'a generic field type', :text_field, :wysihtml5\n\n  it_behaves_like 'a string-like field type', :text_field, :wysihtml5\nend\n"
  },
  {
    "path": "spec/rails_admin/config/fields_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Fields, mongoid: true do\n  describe '.factory for self.referentials belongs_to' do\n    it 'associates belongs_to _id foreign_key to a belongs_to association' do\n      class MongoTree\n        include Mongoid::Document\n        has_many :children, class_name: name, foreign_key: :parent_id\n        belongs_to :parent, class_name: name\n      end\n\n      expect(RailsAdmin.config(MongoTree).fields.detect { |f| f.name == :parent }.type).to eq :belongs_to_association\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/has_description_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::HasDescription do\n  it 'shows description message when added through the DSL' do\n    RailsAdmin.config do |config|\n      config.model Team do\n        desc 'Description of Team model'\n      end\n    end\n\n    expect(RailsAdmin.config(Team).description).to eq('Description of Team model')\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/has_fields_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::HasFields do\n  it 'shows hidden fields when added through the DSL' do\n    expect(RailsAdmin.config(Team).fields.detect { |f| f.name == :division_id }).not_to be_visible\n\n    RailsAdmin.config do |config|\n      config.model Team do\n        field :division_id\n      end\n    end\n\n    expect(RailsAdmin.config(Team).fields.detect { |f| f.name == :division_id }).to be_visible\n  end\n\n  it 'does not set visibility for fields with bindings' do\n    RailsAdmin.config do |config|\n      config.model Team do\n        field :division do\n          visible do\n            bindings[:controller].current_user.email == 'test@email.com'\n          end\n        end\n      end\n    end\n    expect { RailsAdmin.config(Team).fields.detect { |f| f.name == :division } }.not_to raise_error\n    expect { RailsAdmin.config(Team).fields.detect { |f| f.name == :division }.visible? }.to raise_error(/undefined method [`']\\[\\]' for nil/)\n  end\n\n  it 'assigns properties to new one on overriding existing field' do\n    RailsAdmin.config do |config|\n      config.model Team do\n        field :players, :has_and_belongs_to_many_association\n      end\n    end\n    expect(RailsAdmin.config(Team).fields.detect { |f| f.name == :players }.properties).not_to be_nil\n  end\n\n  describe '#configure' do\n    it 'does not change the order of existing fields, if some field types of them are changed' do\n      original_fields_order = RailsAdmin.config(Team).fields.map(&:name)\n\n      RailsAdmin.config do |config|\n        config.model Team do\n          configure :players, :enum do\n            enum { [] }\n          end\n\n          configure :revenue, :integer\n        end\n      end\n\n      expect(RailsAdmin.config(Team).fields.map(&:name)).to eql(original_fields_order)\n    end\n\n    it 'allows passing multiple fields to share the same configuration' do\n      target_field_names = %i[players revenue]\n\n      original_config = RailsAdmin.config(Team).fields.select { |field| target_field_names.include?(field.name) }\n      original_config.each { |field| expect(field).to be_visible }\n\n      RailsAdmin.config do |config|\n        config.model Team do\n          configure target_field_names do\n            visible false\n          end\n        end\n      end\n\n      updated_config = RailsAdmin.config(Team).fields.select { |field| target_field_names.include?(field.name) }\n      updated_config.each { |field| expect(field).to_not be_visible }\n    end\n  end\n\n  describe '#_fields' do\n    let(:config) { RailsAdmin.config(Team) }\n    before do\n      RailsAdmin.config(Team) do\n        field :id\n        field :wins, :boolean\n      end\n    end\n\n    it \"does not cause FrozenError by changing exiting field's type\" do\n      # Reference the fields for readonly\n      config.edit.send(:_fields, true)\n\n      RailsAdmin.config(Team) do\n        field :wins, :integer\n      end\n      expect(config.fields.map(&:name)).to match_array %i[id wins]\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/lazy_model_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::LazyModel do\n  subject { RailsAdmin::Config::LazyModel.new(:Team, &block) }\n  let(:block) { proc { register_instance_option('parameter') } } # an arbitrary instance method we can spy on\n\n  describe '#initialize' do\n    it \"doesn't evaluate the block immediately\" do\n      expect_any_instance_of(RailsAdmin::Config::Model).not_to receive(:register_instance_option)\n      subject\n    end\n\n    it 'evaluates block when reading' do\n      expect_any_instance_of(RailsAdmin::Config::Model).to receive(:register_instance_option).with('parameter')\n      subject.groups # an arbitrary instance method on RailsAdmin::Config::Model to wake up lazy_model\n    end\n\n    it 'evaluates config block only once' do\n      expect_any_instance_of(RailsAdmin::Config::Model).to receive(:register_instance_option).once.with('parameter')\n\n      subject.groups\n      subject.groups\n    end\n  end\n\n  describe '#add_deferred_block' do\n    let(:another_block) { proc { register_instance_option('parameter2') } }\n\n    it \"doesn't evaluate the block immediately\" do\n      expect_any_instance_of(RailsAdmin::Config::Model).not_to receive(:register_instance_option).with('parameter2')\n      subject.add_deferred_block(&another_block)\n    end\n\n    it 'evaluates the block immediately after initialization' do\n      subject.target\n      expect_any_instance_of(RailsAdmin::Config::Model).to receive(:register_instance_option).with('parameter2')\n      subject.add_deferred_block(&another_block)\n    end\n  end\n\n  context 'when a method is defined in Kernel' do\n    before do\n      Kernel.module_eval do\n        def weight\n          42\n        end\n      end\n    end\n\n    after do\n      Kernel.module_eval do\n        undef weight\n      end\n    end\n\n    it 'proxies calls for the method to @object' do\n      expect(subject.weight).to eq 0\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/model_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Model do\n  describe '#excluded?' do\n    before do\n      RailsAdmin.config do |config|\n        config.included_models = [Comment]\n      end\n    end\n\n    it 'returns false when included, true otherwise' do\n      allow(RailsAdmin::AbstractModel).to receive(:all).and_call_original\n\n      player_config = RailsAdmin.config(Player)\n      expect(player_config.excluded?).to be_truthy\n      expect(RailsAdmin::AbstractModel).to have_received(:all).once\n      # Calling a second time uses the cached value.\n      expect(player_config.excluded?).to be_truthy\n      expect(RailsAdmin::AbstractModel).to have_received(:all).once\n\n      comment_config = RailsAdmin.config(Comment)\n      expect(comment_config.excluded?).to be_falsey\n      expect(RailsAdmin::AbstractModel).to have_received(:all).twice\n      # Calling a second time uses the cached value.\n      expect(comment_config.excluded?).to be_falsey\n      expect(RailsAdmin::AbstractModel).to have_received(:all).twice\n    end\n  end\n\n  describe '#object_label' do\n    before do\n      RailsAdmin.config(Comment) do\n        object_label_method :content\n      end\n    end\n\n    it 'sends object_label_method to binding[:object]' do\n      c = Comment.new(content: 'test')\n      expect(RailsAdmin.config(Comment).with(object: c).object_label).to eq('test')\n    end\n\n    context 'when the object_label_method is blank' do\n      it 'uses the rails admin default' do\n        c = Comment.create(content: '', id: '1')\n        expect(RailsAdmin.config(Comment).with(object: c).object_label).to eq('Comment #1')\n      end\n    end\n  end\n\n  describe '#object_label_method' do\n    it 'is first of Config.label_methods if found as a column on model, or :rails_admin_default_object_label_method' do\n      expect(RailsAdmin.config(Comment).object_label_method).to eq(:rails_admin_default_object_label_method)\n      expect(RailsAdmin.config(Division).object_label_method).to eq(:name)\n    end\n  end\n\n  describe '#label' do\n    it 'is pretty' do\n      expect(RailsAdmin.config(Comment).label).to eq('Comment')\n    end\n  end\n\n  describe '#label_plural' do\n    it 'is pretty' do\n      expect(RailsAdmin.config(Comment).label_plural).to eq('Comments')\n    end\n\n    context 'when using i18n as label source', skip_mongoid: true do\n      around do |example|\n        I18n.config.available_locales = I18n.config.available_locales + [:xx]\n        I18n.backend.class.send(:include, I18n::Backend::Pluralization)\n        I18n.backend.store_translations :xx,\n                                        activerecord: {\n                                          models: {\n                                            comment: {\n                                              one: 'one', two: 'two', other: 'other'\n                                            },\n                                          },\n                                        }\n\n        I18n.locale = :xx\n\n        example.run\n\n        I18n.locale = :en\n        I18n.config.available_locales = I18n.config.available_locales - [:xx]\n      end\n\n      context 'and the locale uses a specific pluralization rule' do\n        before do\n          I18n.backend.store_translations :xx,\n                                          i18n: {\n                                            plural: {\n                                              rule: ->(count) do\n                                                case count\n                                                when 0\n                                                  :zero\n                                                when 1\n                                                  :one\n                                                when 2\n                                                  :two\n                                                else\n                                                  :other\n                                                end\n                                              end,\n                                            },\n                                          }\n        end\n\n        it 'always uses :other as pluralization key' do\n          expect(RailsAdmin.config(Comment).label_plural).to eq('other')\n        end\n      end\n    end\n  end\n\n  describe '#weight' do\n    it 'is 0' do\n      expect(RailsAdmin.config(Comment).weight).to eq(0)\n    end\n  end\n\n  describe '#parent' do\n    it 'is nil for ActiveRecord::Base inherited models' do\n      expect(RailsAdmin.config(Comment).parent).to be_nil\n    end\n\n    it 'is parent model otherwise' do\n      expect(RailsAdmin.config(Hardball).parent).to eq(Ball)\n    end\n  end\n\n  describe '#navigation_label' do\n    it 'is nil if parent module is Object' do\n      expect(RailsAdmin.config(Comment).navigation_label).to be_nil\n    end\n\n    it 'is parent module otherwise' do\n      expect(RailsAdmin.config(Cms::BasicPage).navigation_label).to eq('Cms')\n    end\n  end\n\n  describe '#last_created_at', active_record: true do\n    let!(:teams) do\n      [FactoryBot.create(:team, created_at: 1.day.ago), FactoryBot.create(:team, created_at: 2.days.ago)]\n    end\n    before do\n      RailsAdmin.config(Team) do\n        last_created_at { abstract_model.model.maximum(:created_at) }\n      end\n    end\n\n    it 'allow customization' do\n      expect(RailsAdmin.config(Team).last_created_at.to_date).to eq 1.day.ago.to_date\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/proxyable_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Proxyable do\n  class ProxyableTest\n    include RailsAdmin::Config::Proxyable\n\n    def boo\n      sleep 0.15\n      bindings[:foo]\n    end\n\n    def qux\n      'foobar'\n    end\n  end\n\n  let!(:proxyable_test) { ProxyableTest.new }\n  subject do\n    proxyable_test.bindings = {foo: 'bar'}\n    proxyable_test\n  end\n\n  it 'proxies method calls to @object' do\n    expect(subject.bindings).to eq foo: 'bar'\n  end\n\n  it 'preserves initially set @bindings' do\n    expect(subject.with(foo: 'baz').tap(&:qux).bindings).to eq foo: 'bar'\n  end\n\n  context 'when a method is defined in Kernel' do\n    before do\n      Kernel.module_eval do\n        def qux\n          'quux'\n        end\n      end\n    end\n\n    after do\n      Kernel.module_eval do\n        undef qux\n      end\n    end\n\n    it 'proxies calls for the method to @object' do\n      expect(subject.qux).to eq 'foobar'\n    end\n  end\n\n  describe 'with parallel execution' do\n    it 'ensures thread-safety' do\n      threads = Array.new(2) do |i|\n        Thread.new do\n          value = %w[a b][i]\n          proxy = proxyable_test.with foo: value\n          sleep i * 0.1\n          expect(proxy.boo).to eq value\n        end\n      end\n      threads.each(&:join)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/sections/list_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Sections::List do\n  describe '#fields_for_table' do\n    subject { RailsAdmin.config(Player).list }\n\n    it 'brings sticky fields first' do\n      RailsAdmin.config Player do\n        list do\n          field(:number)\n          field(:id)\n          field(:name) { sticky true }\n        end\n      end\n      expect(subject.fields_for_table.map(&:name)).to eq %i[name number id]\n    end\n\n    it 'keep the original order except for stickey ones' do\n      RailsAdmin.config Player do\n        list do\n          configure(:number) { sticky true }\n        end\n      end\n      expect(subject.fields_for_table.map(&:name)).to eq %i[number] + (subject.visible_fields.map(&:name) - %i[number])\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config/sections_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config::Sections do\n  describe 'configure' do\n    it 'configures without changing the section default list' do\n      RailsAdmin.config Team do\n        edit do\n          configure :name do\n            label 'Renamed'\n          end\n        end\n      end\n      fields = RailsAdmin.config(Team).edit.fields\n      expect(fields.detect { |f| f.name == :name }.label).to eq('Renamed')\n      expect(fields.count).to be >= 19 # not 1\n    end\n\n    it 'does not change the section list if set' do\n      RailsAdmin.config Team do\n        edit do\n          field :manager\n          configure :name do\n            label 'Renamed'\n          end\n        end\n      end\n      fields = RailsAdmin.config(Team).edit.fields\n      expect(fields.first.name).to eq(:manager)\n      expect(fields.count).to eq(1) # not 19\n    end\n  end\n\n  describe 'DSL field inheritance' do\n    it 'is tested' do\n      RailsAdmin.config do |config|\n        config.model Fan do\n          field :name do\n            label do\n              @label ||= \"modified base #{label}\"\n            end\n          end\n          list do\n            field :name do\n              label do\n                @label ||= \"modified list #{label}\"\n              end\n            end\n          end\n          edit do\n            field :name do\n              label do\n                @label ||= \"modified edit #{label}\"\n              end\n            end\n          end\n          create do\n            field :name do\n              label do\n                @label ||= \"modified create #{label}\"\n              end\n            end\n          end\n        end\n      end\n      expect(RailsAdmin.config(Fan).visible_fields.count).to eq(1)\n      expect(RailsAdmin.config(Fan).visible_fields.first.label).to eq('modified base Their Name')\n      expect(RailsAdmin.config(Fan).list.visible_fields.first.label).to eq('modified list Their Name')\n      expect(RailsAdmin.config(Fan).export.visible_fields.first.label).to eq('modified base Their Name')\n      expect(RailsAdmin.config(Fan).edit.visible_fields.first.label).to eq('modified edit Their Name')\n      expect(RailsAdmin.config(Fan).create.visible_fields.first.label).to eq('modified create Their Name')\n      expect(RailsAdmin.config(Fan).update.visible_fields.first.label).to eq('modified edit Their Name')\n    end\n  end\n\n  describe 'DSL group inheritance' do\n    it 'is tested' do\n      RailsAdmin.config do |config|\n        config.model Team do\n          list do\n            group 'a' do\n              field :founded\n            end\n\n            group 'b' do\n              field :name\n              field :wins\n            end\n          end\n\n          edit do\n            group 'a' do\n              field :name\n            end\n\n            group 'c' do\n              field :founded\n              field :wins\n            end\n          end\n\n          update do\n            group 'd' do\n              field :wins\n            end\n\n            group 'e' do\n              field :losses\n            end\n          end\n        end\n      end\n\n      expect(RailsAdmin.config(Team).list.visible_groups.collect { |g| g.visible_fields.collect(&:name) }).to eq([[:founded], %i[name wins]])\n      expect(RailsAdmin.config(Team).edit.visible_groups.collect { |g| g.visible_fields.collect(&:name) }).to eq([[:name], %i[founded wins]])\n      expect(RailsAdmin.config(Team).create.visible_groups.collect { |g| g.visible_fields.collect(&:name) }).to eq([[:name], %i[founded wins]])\n      expect(RailsAdmin.config(Team).update.visible_groups.collect { |g| g.visible_fields.collect(&:name) }).to eq([[:name], [:founded], [:wins], [:losses]])\n      expect(RailsAdmin.config(Team).visible_groups.collect { |g| g.visible_fields.collect(&:name) }.flatten.count).to eq(20)\n      expect(RailsAdmin.config(Team).export.visible_groups.collect { |g| g.visible_fields.collect(&:name) }.flatten.count).to eq(20)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/config_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Config do\n  describe '.included_models' do\n    it 'only uses included models' do\n      RailsAdmin.config.included_models = [Team, League]\n      expect(RailsAdmin::AbstractModel.all.collect(&:model)).to eq([League, Team]) # it gets sorted\n    end\n\n    it 'does not restrict models if included_models is left empty' do\n      RailsAdmin.config.included_models = []\n      expect(RailsAdmin::AbstractModel.all.collect(&:model)).to include(Team, League)\n    end\n\n    it 'removes excluded models (whitelist - blacklist)' do\n      RailsAdmin.config.excluded_models = [Team]\n      RailsAdmin.config.included_models = [Team, League]\n      expect(RailsAdmin::AbstractModel.all.collect(&:model)).to eq([League])\n    end\n\n    it 'excluded? returns true for any model not on the list' do\n      RailsAdmin.config.included_models = [Team, League]\n\n      team_config = RailsAdmin::AbstractModel.new('Team').config\n      fan_config = RailsAdmin::AbstractModel.new('Fan').config\n\n      expect(fan_config).to be_excluded\n      expect(team_config).not_to be_excluded\n    end\n  end\n\n  describe '.add_extension' do\n    before do\n      silence_warnings do\n        RailsAdmin.const_set('EXTENSIONS', [])\n      end\n    end\n\n    it 'registers the extension with RailsAdmin' do\n      RailsAdmin.add_extension(:example, ExampleModule)\n      expect(RailsAdmin::EXTENSIONS.count { |name| name == :example }).to eq(1)\n    end\n\n    context 'given an extension with an authorization adapter' do\n      it 'registers the adapter' do\n        RailsAdmin.add_extension(:example, ExampleModule, authorization: true)\n        expect(RailsAdmin::AUTHORIZATION_ADAPTERS[:example]).to eq(ExampleModule::AuthorizationAdapter)\n      end\n    end\n\n    context 'given an extension with an auditing adapter' do\n      it 'registers the adapter' do\n        RailsAdmin.add_extension(:example, ExampleModule, auditing: true)\n        expect(RailsAdmin::AUDITING_ADAPTERS[:example]).to eq(ExampleModule::AuditingAdapter)\n      end\n    end\n\n    context 'given an extension with a configuration adapter' do\n      it 'registers the adapter' do\n        RailsAdmin.add_extension(:example, ExampleModule, configuration: true)\n        expect(RailsAdmin::CONFIGURATION_ADAPTERS[:example]).to eq(ExampleModule::ConfigurationAdapter)\n      end\n    end\n  end\n\n  describe '.main_app_name' do\n    it 'as a default meaningful dynamic value' do\n      expect(RailsAdmin.config.main_app_name.call).to eq(['Dummy App', 'Admin'])\n    end\n\n    it 'can be configured' do\n      RailsAdmin.config do |config|\n        config.main_app_name = %w[static value]\n      end\n      expect(RailsAdmin.config.main_app_name).to eq(%w[static value])\n    end\n  end\n\n  describe '.authorize_with' do\n    context 'given a key for a extension with authorization' do\n      before do\n        RailsAdmin.add_extension(:example, ExampleModule, authorization: true)\n      end\n\n      it 'initializes the authorization adapter' do\n        expect(ExampleModule::AuthorizationAdapter).to receive(:new).with(RailsAdmin::Config)\n        RailsAdmin.config do |config|\n          config.authorize_with(:example)\n        end\n        RailsAdmin.config.authorize_with.call\n      end\n\n      it 'passes through any additional arguments to the initializer' do\n        options = {option: true}\n        expect(ExampleModule::AuthorizationAdapter).to receive(:new).with(RailsAdmin::Config, options)\n        RailsAdmin.config do |config|\n          config.authorize_with(:example, options)\n        end\n        RailsAdmin.config.authorize_with.call\n      end\n    end\n  end\n\n  describe '.audit_with' do\n    context 'given a key for a extension with auditing' do\n      before do\n        RailsAdmin.add_extension(:example, ExampleModule, auditing: true)\n      end\n\n      it 'initializes the auditing adapter' do\n        expect(ExampleModule::AuditingAdapter).to receive(:new).with(RailsAdmin::Config)\n        RailsAdmin.config do |config|\n          config.audit_with(:example)\n        end\n        RailsAdmin.config.audit_with.call\n      end\n\n      it 'passes through any additional arguments to the initializer' do\n        options = {option: true}\n        expect(ExampleModule::AuditingAdapter).to receive(:new).with(RailsAdmin::Config, options)\n        RailsAdmin.config do |config|\n          config.audit_with(:example, options)\n        end\n        RailsAdmin.config.audit_with.call\n      end\n    end\n\n    context 'given paper_trail as the extension for auditing', active_record: true do\n      before do\n        class ControllerMock\n          def set_paper_trail_whodunnit; end\n        end\n\n        module PaperTrail; end\n\n        class Version; end\n        RailsAdmin.add_extension(:example, RailsAdmin::Extensions::PaperTrail, auditing: true)\n      end\n\n      it 'initializes the auditing adapter' do\n        RailsAdmin.config do |config|\n          config.audit_with(:example)\n        end\n        expect { ControllerMock.new.instance_eval(&RailsAdmin.config.audit_with) }.not_to raise_error\n      end\n    end\n  end\n\n  describe '.configure_with' do\n    context 'given a key for a extension with configuration' do\n      before do\n        RailsAdmin.add_extension(:example, ExampleModule, configuration: true)\n      end\n\n      it 'initializes configuration adapter' do\n        expect(ExampleModule::ConfigurationAdapter).to receive(:new)\n        RailsAdmin.config do |config|\n          config.configure_with(:example)\n        end\n      end\n\n      it 'yields the (optionally) provided block, passing the initialized adapter' do\n        configurator = nil\n        RailsAdmin.config do |config|\n          config.configure_with(:example) do |configuration_adapter|\n            configurator = configuration_adapter\n          end\n        end\n        expect(configurator).to be_a(ExampleModule::ConfigurationAdapter)\n      end\n    end\n  end\n\n  describe '.config' do\n    context '.default_search_operator' do\n      it 'sets the default_search_operator' do\n        RailsAdmin.config do |config|\n          config.default_search_operator = 'starts_with'\n        end\n        expect(RailsAdmin::Config.default_search_operator).to eq('starts_with')\n      end\n\n      it 'errors on unrecognized search operator' do\n        expect do\n          RailsAdmin.config do |config|\n            config.default_search_operator = 'random'\n          end\n        end.to raise_error(ArgumentError, \"Search operator 'random' not supported\")\n      end\n\n      it \"defaults to 'default'\" do\n        expect(RailsAdmin::Config.default_search_operator).to eq('default')\n      end\n    end\n  end\n\n  describe '.visible_models' do\n    it 'passes controller bindings, find visible models, order them' do\n      RailsAdmin.config do |config|\n        config.included_models = [Player, Fan, Comment, Team]\n\n        config.model Player do\n          hide\n        end\n        config.model Fan do\n          weight(-1)\n          show\n        end\n        config.model Comment do\n          visible do\n            bindings[:controller]._current_user.role == :admin\n          end\n        end\n        config.model Team do\n          visible do\n            bindings[:controller]._current_user.role != :admin\n          end\n        end\n      end\n\n      expect(RailsAdmin.config.visible_models(controller: double(_current_user: double(role: :admin), authorized?: true)).collect(&:abstract_model).collect(&:model)).to match_array [Fan, Comment]\n    end\n\n    it 'hides unallowed models' do\n      RailsAdmin.config do |config|\n        config.included_models = [Comment]\n      end\n      expect(RailsAdmin.config.visible_models(controller: double(authorization_adapter: double(authorized?: true))).collect(&:abstract_model).collect(&:model)).to eq([Comment])\n      expect(RailsAdmin.config.visible_models(controller: double(authorization_adapter: double(authorized?: false))).collect(&:abstract_model).collect(&:model)).to eq([])\n    end\n\n    it 'does not contain embedded model', mongoid: true do\n      RailsAdmin.config do |config|\n        config.included_models = [FieldTest, Comment, Embed]\n      end\n\n      expect(RailsAdmin.config.visible_models(controller: double(_current_user: double(role: :admin), authorized?: true)).collect(&:abstract_model).collect(&:model)).to match_array [FieldTest, Comment]\n    end\n\n    it 'basically does not contain embedded model except model using recursively_embeds_many or recursively_embeds_one', mongoid: true do\n      class RecursivelyEmbedsOne\n        include Mongoid::Document\n        recursively_embeds_one\n      end\n\n      class RecursivelyEmbedsMany\n        include Mongoid::Document\n        recursively_embeds_many\n      end\n      RailsAdmin.config do |config|\n        config.included_models = [FieldTest, Comment, Embed, RecursivelyEmbedsMany, RecursivelyEmbedsOne]\n      end\n      expect(RailsAdmin.config.visible_models(controller: double(_current_user: double(role: :admin), authorized?: true)).collect(&:abstract_model).collect(&:model)).to match_array [FieldTest, Comment, RecursivelyEmbedsMany, RecursivelyEmbedsOne]\n    end\n  end\n\n  describe '.models_pool' do\n    it 'should not include classnames start with Concerns::' do\n      expect(RailsAdmin::Config.models_pool.select { |m| m.match(/^Concerns::/) }).to be_empty\n    end\n\n    it 'includes models in the directory added by config.eager_load_paths' do\n      expect(RailsAdmin::Config.models_pool).to include('Basketball')\n    end\n\n    it 'should include a model which was configured explicitly' do\n      RailsAdmin::Config.model 'PaperTrail::Version' do\n        visible false\n      end\n\n      expect(RailsAdmin::Config.models_pool).to include('PaperTrail::Version')\n    end\n  end\n\n  describe '.parent_controller' do\n    before do\n      class TestController < ActionController::Base; end\n    end\n\n    it 'uses default class' do\n      expect(RailsAdmin.config.parent_controller).to eq '::ActionController::Base'\n    end\n\n    it 'uses other class' do\n      RailsAdmin.config do |config|\n        config.parent_controller = 'TestController'\n      end\n      expect(RailsAdmin.config.parent_controller).to eq 'TestController'\n    end\n  end\n\n  describe '.parent_controller=' do\n    context 'if RailsAdmin::ApplicationController is already loaded' do\n      before do\n        # preload controllers (e.g. when config.eager_load = true)\n        RailsAdmin::MainController\n      end\n\n      after do\n        RailsAdmin::Config.reset\n        RailsAdmin.send(:remove_const, :ApplicationController)\n        load RailsAdmin::Engine.root.join('app/controllers/rails_admin/application_controller.rb')\n      end\n\n      it 'can be changed' do\n        RailsAdmin.config.parent_controller = 'ApplicationController'\n        expect(RailsAdmin::ApplicationController.superclass).to eq ApplicationController\n        expect(RailsAdmin::MainController.superclass.superclass).to eq ApplicationController\n      end\n    end\n  end\n\n  describe '.forgery_protection_settings' do\n    it 'uses with: :exception by default' do\n      expect(RailsAdmin.config.forgery_protection_settings).to eq(with: :exception)\n    end\n\n    it 'allows to customize settings' do\n      RailsAdmin.config do |config|\n        config.forgery_protection_settings = {with: :null_session}\n      end\n      expect(RailsAdmin.config.forgery_protection_settings).to eq(with: :null_session)\n    end\n  end\n\n  describe '.model' do\n    let(:fields) { described_class.model(Team).fields }\n    before do\n      described_class.model Team do\n        field :players do\n          visible false\n        end\n      end\n    end\n\n    context 'when model expanded' do\n      before do\n        described_class.model(Team) do\n          field :fans\n        end\n      end\n      it 'execute all passed blocks' do\n        expect(fields.map(&:name)).to match_array %i[players fans]\n      end\n    end\n\n    context 'when expand redefine behavior' do\n      before do\n        described_class.model Team do\n          field :players\n        end\n      end\n      it 'execute all passed blocks' do\n        expect(fields.find { |f| f.name == :players }.visible).to be true\n      end\n    end\n\n    context 'when model has no table yet', active_record: true do\n      it 'does not try to apply the configuration block' do\n        described_class.model(WithoutTable) do\n          include_all_fields\n        end\n      end\n    end\n  end\n\n  describe '.reset' do\n    before do\n      RailsAdmin.config do |config|\n        config.included_models = %w[Player Team]\n      end\n      RailsAdmin::AbstractModel.all\n      RailsAdmin::Config.reset\n      RailsAdmin.config do |config|\n        config.excluded_models = ['Player']\n      end\n    end\n    subject { RailsAdmin::AbstractModel.all.map { |am| am.model.name } }\n\n    it 'refreshes the result of RailsAdmin::AbstractModel.all' do\n      expect(subject).not_to include 'Player'\n      expect(subject).to include 'Team'\n    end\n  end\n\n  describe '.reload!' do\n    before do\n      RailsAdmin.config Player do\n        field :name\n      end\n      RailsAdmin.config Team do\n        field :color, :integer\n      end\n    end\n\n    it 'clears current configuration' do\n      RailsAdmin::Config.reload!\n      expect(RailsAdmin::Config.model(Player).fields.map(&:name)).to include :number\n    end\n\n    it 'reloads the configuration from the initializer' do\n      RailsAdmin::Config.reload!\n      expect(RailsAdmin::Config.model(Team).fields.find { |f| f.name == :color }.type).to eq :hidden\n    end\n  end\nend\n\nmodule ExampleModule\n  class AuthorizationAdapter; end\n\n  class ConfigurationAdapter; end\n\n  class AuditingAdapter; end\nend\n"
  },
  {
    "path": "spec/rails_admin/engine_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Engine do\n  context 'on class unload' do\n    let(:fields) { RailsAdmin.config(Player).edit.fields }\n    before do\n      Rails.application.config.cache_classes = false\n      RailsAdmin.config(Player) do\n        field :name\n        field :number\n      end\n    end\n    after { Rails.application.config.cache_classes = true }\n\n    it 'triggers RailsAdmin config to be reloaded' do\n      # this simulates rails code reloading\n      RailsAdmin::Engine.initializers.find do |i|\n        i.name == 'RailsAdmin reload config in development'\n      end.block.call(Rails.application)\n      Rails.application.executor.wrap do\n        ActiveSupport::Reloader.new.tap(&:class_unload!).complete!\n      end\n\n      RailsAdmin.config(Player) do\n        field :number\n      end\n      expect(fields.map(&:name)).to match_array %i[number]\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/extentions/cancancan/authorization_adapter_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Extensions::CanCanCan::AuthorizationAdapter do\n  let(:user) { double }\n  let(:controller) { double(_current_user: user, current_ability: MyAbility.new(user)) }\n\n  class MyAbility\n    include CanCan::Ability\n    def initialize(_user)\n      can :access, :rails_admin\n      can :manage, :all\n    end\n  end\n\n  describe '#initialize' do\n    it 'accepts the ability class as an argument' do\n      expect(described_class.new(controller, MyAbility).ability_class).to eq MyAbility\n    end\n\n    it 'supports block DSL' do\n      adapter = described_class.new(controller) do\n        ability_class MyAbility\n      end\n      expect(adapter.ability_class).to eq MyAbility\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/extentions/paper_trail/auditing_adapter_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Extensions::PaperTrail::AuditingAdapter, active_record: true do\n  let(:controller) { double(set_paper_trail_whodunnit: nil) }\n\n  describe '#initialize' do\n    it 'accepts the user and version classes as arguments' do\n      adapter = described_class.new(controller, User::Confirmed, Trail)\n      expect(adapter.user_class).to eq User::Confirmed\n      expect(adapter.version_class).to eq Trail\n    end\n\n    it 'supports block DSL' do\n      adapter = described_class.new(controller) do\n        user_class User::Confirmed\n        version_class Trail\n        sort_by(created_at: :asc)\n      end\n      expect(adapter.user_class).to eq User::Confirmed\n      expect(adapter.version_class).to eq Trail\n      expect(adapter.sort_by).to eq({created_at: :asc})\n    end\n  end\n\n  describe '#listing_for_model' do\n    subject { RailsAdmin::Extensions::PaperTrail::AuditingAdapter.new(nil) }\n    let(:model) { RailsAdmin::AbstractModel.new(PaperTrailTest) }\n\n    it 'uses the given sort order' do\n      expect_any_instance_of(ActiveRecord::Relation).to receive(:order).with(whodunnit: :asc).and_call_original\n      subject.listing_for_model model, nil, :username, false, true, nil, 20\n    end\n\n    it 'uses the default order when sort is not given' do\n      expect_any_instance_of(ActiveRecord::Relation).to receive(:order).with(id: :desc).and_call_original\n      subject.listing_for_model model, nil, false, false, true, nil, 20\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/extentions/paper_trail/version_proxy_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Extensions::PaperTrail::VersionProxy, active_record: true do\n  describe '#username' do\n    subject { described_class.new(version, user_class).username }\n\n    let(:version) { double(whodunnit: :the_user) }\n    let(:user_class) { double(find: user) }\n\n    context 'when found user has email' do\n      let(:user) { double(email: :mail) }\n      it { is_expected.to eq(:mail) }\n    end\n\n    context 'when found user does not have email' do\n      let(:user) { double } # no email method\n\n      it { is_expected.to eq(:the_user) }\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/install_generator_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\nrequire 'generators/rails_admin/install_generator'\n\nRSpec.describe RailsAdmin::InstallGenerator, type: :generator do\n  destination File.expand_path('../dummy_app/tmp/generator', __dir__)\n  arguments ['admin', \"--asset=#{CI_ASSET}\", '--force']\n\n  before do\n    prepare_destination\n    File.write(File.join(destination_root, 'package.json'), '{\"license\": \"MIT\"}')\n    FileUtils.touch File.join(destination_root, 'Gemfile')\n    FileUtils.mkdir_p(File.join(destination_root, 'config/initializers'))\n    File.write(File.join(destination_root, 'config/routes.rb'), <<~RUBY)\n      Rails.application.routes.draw do\n        # empty\n      end\n    RUBY\n    File.write(File.join(destination_root, 'Rakefile'), <<-RUBY.gsub(/^ {4}/, ''))\n    desc 'Stub for testing'\n    task 'css:install:sass'\n    RUBY\n  end\n\n  after do\n    FileUtils.rm_rf(destination_root)\n  end\n\n  it 'mounts RailsAdmin as Engine and generates RailsAdmin Initializer' do\n    Dir.chdir(destination_root) do\n      run_generator\n    end\n    expect(destination_root).to(\n      have_structure do\n        directory 'config' do\n          directory 'initializers' do\n            file 'rails_admin.rb' do\n              contains 'RailsAdmin.config'\n              contains 'asset_source ='\n            end\n          end\n          file 'routes.rb' do\n            contains \"mount RailsAdmin::Engine => '/admin', as: 'rails_admin'\"\n          end\n        end\n        case CI_ASSET\n        when :webpacker\n          file 'app/javascript/packs/rails_admin.js' do\n            contains 'import \"rails_admin/src/rails_admin/base\"'\n          end\n          file 'app/javascript/stylesheets/rails_admin.scss' do\n            contains '@import \"rails_admin/src/rails_admin/styles/base\"'\n          end\n        when :sprockets\n          file 'Gemfile' do\n            contains 'sassc-rails'\n          end\n        when :importmap\n          file 'app/javascript/rails_admin.js' do\n            contains 'import \"rails_admin/src/rails_admin/base\"'\n          end\n          file 'app/assets/stylesheets/rails_admin.scss' do\n            contains '$fa-font-path: \".\";'\n            contains '@import \"rails_admin/src/rails_admin/styles/base\"'\n          end\n          file 'config/importmap.rails_admin.rb' do\n            contains 'pin \"rails_admin\", preload: true'\n            contains 'pin \"rails_admin/src/rails_admin/base\", to: \"https://ga.jspm.io/npm:rails_admin@'\n            contains 'pin \"bootstrap\", to: \"https://ga.jspm.io/npm:bootstrap@'\n          end\n          file 'config/initializers/assets.rb' do\n            contains 'Rails.root.join(\"node_modules/@fortawesome/fontawesome-free/webfonts\")'\n          end\n          file 'package.json' do\n            contains 'sass ./app/assets/stylesheets/rails_admin.scss:./app/assets/builds/rails_admin.css'\n          end\n        when :webpack\n          file 'app/javascript/rails_admin.js' do\n            contains 'import \"rails_admin/src/rails_admin/base\"'\n          end\n          file 'app/assets/stylesheets/rails_admin.scss' do\n            contains '$fa-font-path: \".\";'\n            contains '@import \"rails_admin/src/rails_admin/styles/base\"'\n          end\n          file 'package.json' do\n            contains 'webpack --config webpack.config.js'\n            contains 'sass ./app/assets/stylesheets/rails_admin.scss:./app/assets/builds/rails_admin.css'\n          end\n        when :vite\n          file 'app/frontend/entrypoints/rails_admin.js' do\n            contains 'import \"~/stylesheets/rails_admin.scss\"'\n            contains 'import \"rails_admin/src/rails_admin/base\"'\n          end\n          file 'app/frontend/stylesheets/rails_admin.scss' do\n            contains '$fa-font-path: \"@fortawesome/fontawesome-free/webfonts\";'\n            contains '@import \"rails_admin/src/rails_admin/styles/base\"'\n          end\n          file 'package.json' do\n            contains 'sass'\n          end\n        end\n      end,\n    )\n  end\n\n  it 'inserts asset_source option to RailsAdmin Initializer' do\n    File.write(File.join(destination_root, 'config/initializers/rails_admin.rb'), <<~RUBY)\n      RailsAdmin.config do |config|\n        # empty\n      end\n    RUBY\n    Dir.chdir(destination_root) do\n      run_generator\n    end\n    expect(File.read(File.join(destination_root, 'config/initializers/rails_admin.rb'))).to include 'config.asset_source ='\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/support/csv_converter_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::CSVConverter do\n  it 'keeps headers ordering' do\n    RailsAdmin.config(Player) do\n      export do\n        field :number\n        field :name\n      end\n    end\n\n    FactoryBot.create :player\n    objects = Player.all\n    schema = {only: %i[number name]}\n    expect(RailsAdmin::CSVConverter.new(objects, schema).to_csv({})[2]).to match(/Number,Name/)\n  end\n\n  describe '#generate_csv_header' do\n    let(:objects) { FactoryBot.create_list :player, 1 }\n    before do\n      RailsAdmin.config(Player) do\n        export do\n          field :number\n          field :name\n        end\n      end\n    end\n\n    it 'does not break when non-existent fields are given' do\n      expect(RailsAdmin::CSVConverter.new(objects, {only: %i[name foo], include: {bar: :baz}}).send(:generate_csv_header)).\n        to eq ['Name']\n    end\n\n    it 'does not break when non-association fields are given to :include' do\n      expect(RailsAdmin::CSVConverter.new(objects, {only: %i[name foo], include: {name: :name}}).send(:generate_csv_header)).\n        to eq ['Name']\n    end\n  end\n\n  describe '#to_csv' do\n    before do\n      RailsAdmin.config(Player) do\n        export do\n          field :number\n          field :name\n        end\n      end\n    end\n\n    let(:objects) { FactoryBot.create_list :player, 1, number: 1, name: 'なまえ' }\n    let(:schema) { {only: %i[number name]} }\n    let(:options) { {encoding_to: encoding} }\n\n    subject { RailsAdmin::CSVConverter.new(objects, schema).to_csv(options) }\n\n    context 'when encoding FROM latin1', active_record: true do\n      let(:connection_config) do\n        if ActiveRecord::Base.respond_to?(:connection_db_config)\n          ActiveRecord::Base.connection_db_config.configuration_hash\n        else\n          ActiveRecord::Base.connection_config\n        end\n      end\n      let(:encoding) { '' }\n      let(:objects) { FactoryBot.create_list :player, 1, number: 1, name: 'Josè'.encode('ISO-8859-1') }\n      before do\n        case connection_config[:adapter]\n        when 'postgresql'\n          @connection = ActiveRecord::Base.connection.raw_connection\n          @connection.set_client_encoding('latin1')\n        when 'mysql2'\n          ActiveRecord::Base.connection.execute('SET NAMES latin1;')\n        end\n      end\n      after do\n        case connection_config[:adapter]\n        when 'postgresql'\n          @connection.set_client_encoding('utf8')\n        when 'mysql2'\n          ActiveRecord::Base.connection.execute('SET NAMES utf8;')\n        end\n      end\n\n      it 'exports to ISO-8859-1' do\n        expect(subject[1]).to eq 'ISO-8859-1'\n        expect(subject[2].encoding).to eq Encoding::ISO_8859_1\n        expect(subject[2].unpack1('H*')).\n          to eq '4e756d6265722c4e616d650a312c4a6f73e80a'\n      end\n    end\n\n    context 'when encoding to UTF-8' do\n      let(:encoding) { 'UTF-8' }\n\n      it 'exports to UTF-8 with BOM' do\n        expect(subject[1]).to eq 'UTF-8'\n        expect(subject[2].encoding).to eq Encoding::UTF_8\n        expect(subject[2].unpack1('H*')).\n          to eq 'efbbbf4e756d6265722c4e616d650a312ce381aae381bee381880a' # have BOM\n      end\n    end\n\n    context 'when encoding to Shift_JIS' do\n      let(:encoding) { 'Shift_JIS' }\n\n      it 'exports to Shift_JIS' do\n        expect(subject[1]).to eq 'Shift_JIS'\n        expect(subject[2].encoding).to eq Encoding::Shift_JIS\n        expect(subject[2].unpack1('H*')).\n          to eq '4e756d6265722c4e616d650a312c82c882dc82a60a'\n      end\n    end\n\n    context 'when encoding to UTF-16(ASCII-incompatible)' do\n      let(:encoding) { 'UTF-16' }\n\n      it 'encodes to expected byte sequence' do\n        expect(subject[1]).to eq 'UTF-16'\n        expect(subject[2].encoding).to eq Encoding::UTF_16\n        expect(subject[2].unpack1('H*').force_encoding('US-ASCII')).\n          to eq 'feff004e0075006d006200650072002c004e0061006d0065000a0031002c306a307e3048000a'\n      end\n    end\n\n    context 'when specifying a column separator' do\n      context 'when options keys are symbolized' do\n        let(:options) { {encoding_to: 'UTF-8', generator: {col_sep: '___'}} }\n        it 'uses the column separator specified' do\n          expect(subject[2].unpack1('H*')).\n            to eq 'efbbbf4e756d6265725f5f5f4e616d650a315f5f5fe381aae381bee381880a'\n        end\n      end\n\n      context 'when options keys are string' do\n        let(:options) { {'encoding_to' => 'UTF-8', 'generator' => {'col_sep' => '___'}} }\n        it 'uses the column separator specified' do\n          expect(subject[2].unpack1('H*')).\n            to eq 'efbbbf4e756d6265725f5f5f4e616d650a315f5f5fe381aae381bee381880a'\n        end\n      end\n    end\n\n    context 'when objects is empty' do\n      let(:objects) { [] }\n      let(:options) { {} }\n\n      it 'generates an empty csv' do\n        expect(subject[2]).to eq(\"\\n\")\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/support/datetime_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::Support::Datetime do\n  describe '#to_flatpickr_format' do\n    {\n      '%D de %M de %Y, %H:%M:%S' => 'm/d/y \\d\\e i \\d\\e Y, H:i:S',\n      '%d/%-m/%Y, %H:%M:%S' => 'd/n/Y, H:i:S',\n      '%d de %B de %Y' => 'd \\d\\e F \\d\\e Y',\n      '%-d %B %Y' => 'j F Y',\n      '%F %T' => 'Y-m-d H:i:S',\n      '%Y-%m-%dT%H:%M:%S%:z' => 'Y-m-d\\TH:i:S+00:00',\n      '%HH%MM%SS' => 'H\\Hi\\MS\\S',\n      'a%-Ha%-Ma%-Sa%:za' => '\\aH\\ai\\as\\a+00:00\\a',\n      '%B %-d at %-l:%M %p' => 'F j \\a\\t h:i K',\n    }.each do |strftime_format, flatpickr_format|\n      it \"convert strftime_format to flatpickr_format - example #{strftime_format}\" do\n        expect(RailsAdmin::Support::Datetime.to_flatpickr_format(strftime_format)).to eq flatpickr_format\n      end\n    end\n\n    it 'raises an error with unsupported directive' do\n      expect do\n        RailsAdmin::Support::Datetime.to_flatpickr_format('%C')\n      end.to raise_error(/Unsupported/)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/support/hash_helper_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.describe RailsAdmin::HashHelper do\n  let(:hash) do\n    {\n      'subject' => 'Test',\n      'user' => {\n        name: 'Dirk',\n        'title' => 'Holistic Detective',\n        'clients' => [\n          {name: 'Zaphod'},\n          {'name' => 'Arthur'},\n        ],\n      },\n    }\n  end\n\n  describe 'symbolize' do\n    let(:symbolized_hash) { RailsAdmin::HashHelper.symbolize(hash) }\n\n    it 'symbolizes top-level hash keys' do\n      %i[subject user].each do |key|\n        expect(symbolized_hash.keys).to include(key)\n      end\n    end\n\n    it 'symbolizes nested hashes' do\n      %i[name title clients].each do |key|\n        expect(symbolized_hash[:user].keys).to include(key)\n      end\n    end\n\n    it 'symbolizes nested hashes inside of array values' do\n      clients = symbolized_hash[:user][:clients]\n      expect(clients.length).to eq(2)\n      expect(clients[0][:name]).to eq(:Zaphod)\n      expect(clients[1][:name]).to eq(:Arthur)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/rails_admin/version_spec.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'fileutils'\nrequire 'spec_helper'\n\nRSpec.describe 'RailsAdmin::Version' do\n  describe '#warn_with_js_version' do\n    it 'does nothing when the versions match' do\n      allow(RailsAdmin::Version).to receive(:actual_js_version).and_return('3.0.0')\n      allow(RailsAdmin::Version).to receive(:js).and_return('3.0.0')\n      expect(RailsAdmin::Version).not_to receive(:warn)\n      RailsAdmin::Version.warn_with_js_version\n    end\n\n    it \"shows a warning when actual_js_version couldn't detected\" do\n      allow(RailsAdmin::Version).to receive(:actual_js_version).and_return(nil)\n      allow(RailsAdmin::Version).to receive(:js).and_return('3.0.1')\n      expect(RailsAdmin::Version).to receive(:warn).with(/yarn install/)\n      RailsAdmin::Version.warn_with_js_version\n    end\n\n    it 'shows a warning when the versions do not match' do\n      allow(RailsAdmin::Version).to receive(:actual_js_version).and_return('3.0.0')\n      allow(RailsAdmin::Version).to receive(:js).and_return('3.0.1')\n      expect(RailsAdmin::Version).to receive(:warn).with(/inconsistency/)\n      RailsAdmin::Version.warn_with_js_version\n    end\n  end\n\n  describe '#js_version_from_node_modules' do\n    unless CI_ASSET == :sprockets\n      let(:path) { Rails.root.join('node_modules/rails_admin/package.json') }\n      before do\n        @backup = File.read(path)\n        FileUtils.rm(path)\n      end\n      after { File.write(path, @backup) }\n\n      it 'returns nil when RailsAdmin package.json is not found' do\n        expect(RailsAdmin::Version.send(:js_version_from_node_modules)).to be_nil\n      end\n\n      it 'shows a warning when RailsAdmin package.json is not found' do\n        File.write(path, '{\"version\": \"0.1.0-alpha\"}')\n        expect(RailsAdmin::Version.send(:js_version_from_node_modules)).to eq '0.1.0-alpha'\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/shared_examples/shared_examples_for_field_types.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'spec_helper'\n\nRSpec.shared_examples 'a generic field type' do |column_name, field_type|\n  describe '#html_attributes' do\n    context 'when the field is required' do\n      before do\n        RailsAdmin.config FieldTest do\n          field column_name, field_type do\n            required true\n          end\n        end\n      end\n      subject do\n        RailsAdmin.config('FieldTest').fields.detect do |f|\n          f.name == column_name\n        end.with(object: FieldTest.new)\n      end\n\n      it 'should contain a required attribute with the string \"required\" as value' do\n        expect(subject.html_attributes[:required]).to be_truthy\n      end\n    end\n  end\nend\n\nRSpec.shared_examples 'a string-like field type' do |column_name, _|\n  subject do\n    RailsAdmin.config('FieldTest').fields.detect do |f|\n      f.name == column_name\n    end.with(object: FieldTest.new)\n  end\n\n  it 'is a StringLike field' do\n    expect(subject).to be_a(RailsAdmin::Config::Fields::Types::StringLike)\n  end\nend\n\nRSpec.shared_examples 'a float-like field type' do |column_name|\n  subject do\n    RailsAdmin.config('FieldTest').fields.detect do |f|\n      f.name == column_name\n    end.with(object: FieldTest.new)\n  end\n\n  describe '#html_attributes' do\n    it 'should contain a step attribute' do\n      expect(subject.html_attributes[:step]).to eq('any')\n    end\n\n    it 'should contain a falsey required attribute' do\n      expect(subject.html_attributes[:required]).to be_falsey\n    end\n\n    context 'when the field is required' do\n      before do\n        RailsAdmin.config FieldTest do\n          field column_name, :float do\n            required true\n          end\n        end\n      end\n\n      it 'should contain a truthy required attribute' do\n        expect(subject.html_attributes[:required]).to be_truthy\n      end\n    end\n  end\n\n  describe '#view_helper' do\n    it \"uses the 'number' type input tag\" do\n      expect(subject.view_helper).to eq(:number_field)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/spec_helper.rb",
    "content": "# frozen_string_literal: true\n\n# Configure Rails Environment\nENV['RAILS_ENV'] = 'test'\nCI_ORM = (ENV['CI_ORM'] || :active_record).to_sym\nPK_COLUMN = {active_record: :id, mongoid: :_id}[CI_ORM]\n\nif RUBY_ENGINE == 'jruby'\n  # Workaround for JRuby CI failure https://github.com/jruby/jruby/issues/6547#issuecomment-774104996\n  require 'i18n/backend'\n  require 'i18n/backend/simple'\nend\n\nrequire 'simplecov'\nrequire 'simplecov-lcov'\n\nSimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, SimpleCov::Formatter::LcovFormatter]\n\nSimpleCov.start do\n  add_filter '/spec/'\n  add_filter '/vendor/bundle/'\nend\n\nSimpleCov::Formatter::LcovFormatter.config do |c|\n  c.report_with_single_file = true\n  c.single_report_path = 'coverage/lcov.info'\nend\n\nrequire File.expand_path('dummy_app/config/environment', __dir__)\n\nrequire 'rspec/rails'\nrequire 'factory_bot'\nrequire 'factories'\nrequire 'policies'\nrequire \"database_cleaner/#{CI_ORM}\"\nrequire \"orm/#{CI_ORM}\"\nrequire 'paper_trail/frameworks/rspec' if defined?(PaperTrail)\n\nDir[File.expand_path('support/**/*.rb', __dir__),\n    File.expand_path('shared_examples/**/*.rb', __dir__)].sort.each { |f| require f }\n\nActionMailer::Base.delivery_method = :test\nActionMailer::Base.perform_deliveries = true\nActionMailer::Base.default_url_options[:host] = 'example.com'\n\nRails.backtrace_cleaner.remove_silencers!\n\nrequire 'capybara/cuprite'\nCapybara.javascript_driver = :cuprite\nCapybara.register_driver(:cuprite) do |app|\n  # Refs. https://github.com/rubycdp/ferrum/issues/470\n  Capybara::Cuprite::Driver.new(app, flatten: RUBY_ENGINE != 'jruby', js_errors: true, logger: ConsoleLogger)\nend\nCapybara.server = :webrick\n\nRailsAdmin.setup_all_extensions\n\nRSpec.configure do |config|\n  config.expect_with :rspec do |c|\n    c.syntax = :expect\n  end\n\n  config.disable_monkey_patching!\n\n  config.include RSpec::Matchers\n  config.include RailsAdmin::Engine.routes.url_helpers\n\n  config.include Warden::Test::Helpers\n\n  config.include Capybara::DSL, type: :request\n  config.include Capybara::RSpecMatchers, type: :request\n\n  config.verbose_retry = true\n  config.display_try_failure_messages = true\n  config.around :each, :js do |example|\n    example.run_with_retry retry: (ENV['CI'] && RUBY_ENGINE == 'jruby' ? 3 : 2)\n  end\n  config.retry_callback = proc do |example|\n    example.metadata[:retry] = 6 if [Ferrum::DeadBrowserError, Ferrum::NoExecutionContextError, Ferrum::TimeoutError].include?(example.exception.class)\n    if example.metadata[:js]\n      attempt = 0\n      begin\n        Capybara.reset!\n      rescue Ferrum::TimeoutError, Ferrum::NoExecutionContextError\n        attempt += 1\n        raise if attempt >= 5\n\n        retry\n      end\n    end\n  end\n\n  config.before(:all) do\n    case CI_ASSET\n    when :webpacker\n      Webpacker.instance.compiler.compile\n    when :vite\n      ViteRuby.instance.commands.build\n    end\n  end\n\n  config.before do |example|\n    DatabaseCleaner.strategy =\n      if CI_ORM == :mongoid || example.metadata[:js]\n        :deletion\n      else\n        :transaction\n      end\n\n    DatabaseCleaner.start\n    RailsAdmin::Config.reset\n    RailsAdmin::Config.asset_source = CI_ASSET\n  end\n\n  config.after(:each) do\n    Warden.test_reset!\n    DatabaseCleaner.clean\n  end\n\n  CI_TARGET_ORMS.each do |orm|\n    if orm == CI_ORM\n      config.filter_run_excluding \"skip_#{orm}\": true\n    else\n      config.filter_run_excluding orm => true\n    end\n  end\n\n  config.filter_run_excluding composite_primary_keys: true unless defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new('7.1') || defined?(CompositePrimaryKeys)\nend\n"
  },
  {
    "path": "spec/support/cuprite_logger.rb",
    "content": "# frozen_string_literal: true\n\nclass ConsoleLogger\n  def self.puts(message)\n    warn(message) unless message.start_with?('    ◀', \"\\n\\n▶\")\n  end\nend\n"
  },
  {
    "path": "spec/support/fakeio.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'forwardable'\nrequire 'stringio'\n\nclass FakeIO\n  attr_reader :original_filename, :content_type\n\n  def initialize(content, filename: nil, content_type: nil)\n    @io = StringIO.new(content)\n    @original_filename = filename\n    @content_type = content_type\n  end\n\n  extend Forwardable\n  delegate %i[read rewind eof? close size] => :@io\nend\n"
  },
  {
    "path": "spec/support/fixtures.rb",
    "content": "# frozen_string_literal: true\n\ndef file_path(*paths)\n  File.expand_path(File.join(File.dirname(__FILE__), '../fixtures', *paths))\nend\n"
  },
  {
    "path": "spec/support/jquery.simulate.drag-sortable.js",
    "content": "(function($) {\n  /*\n   * Simulate drag of a JQuery UI sortable list\n   * Repository: https://github.com/mattheworiordan/jquery.simulate.drag-sortable.js\n   * Author: http://mattheworiordan.com\n   *\n   * options are:\n   * - move: move item up (positive) or down (negative) by Integer amount\n   * - dropOn: move item to a new linked list, move option now represents position in the new list (zero indexed)\n   * - handle: selector for the draggable handle element (optional)\n   * - listItem: selector to limit which sibling items can be used for reordering\n   * - placeHolder: if a placeholder is used during dragging, we need to consider it's height\n   * - tolerance: (optional) number of pixels to overlap by instead of the default 50% of the element height\n   *\n   */\n  $.fn.simulateDragSortable = function(options) {\n    // build main options before element iteration\n    var opts = $.extend({}, $.fn.simulateDragSortable.defaults, options);\n\n    applyDrag = function(options) {\n      // allow for a drag handle if item is not draggable\n      var that = this,\n          options = options || opts, // default to plugin opts unless options explicitly provided\n          handle = options.handle ? $(this).find(options.handle)[0] : $(this)[0],\n          listItem = options.listItem,\n          placeHolder = options.placeHolder,\n          sibling = $(this),\n          moveCounter = Math.floor(options.move),\n          direction = moveCounter > 0 ? 'down' : 'up',\n          moveVerticalAmount = 0,\n          initialVerticalPosition = 0,\n          extraDrag = !isNaN(parseInt(options.tolerance, 10)) ? function() { return Number(options.tolerance); } : function(obj) { return ($(obj).outerHeight() / 2) + 5; },\n          dragPastBy = 0, // represents the additional amount one drags past an element and bounce back\n          dropOn = options.dropOn ? $(options.dropOn) : false,\n          center = findCenter(handle),\n          x = Math.floor(center.x),\n          y = Math.floor(center.y),\n          mouseUpAfter = (opts.debug ? 2500 : 10);\n\n      if (dropOn) {\n        if (dropOn.length === 0) {\n          if (console && console.log) { console.log('simulate.drag-sortable.js ERROR: Drop on target could not be found'); console.log(options.dropOn); }\n          return;\n        }\n        sibling = dropOn.find('>*:last');\n        moveCounter = -(dropOn.find('>*').length + 1) + (moveCounter + 1); // calculate length of list after this move, use moveCounter as a positive index position in list to reverse back up\n        if (dropOn.offset().top - $(this).offset().top < 0) {\n          // moving to a list above this list, so move to just above top of last item (tried moving to top but JQuery UI wouldn't bite)\n          initialVerticalPosition = sibling.offset().top - $(this).offset().top - extraDrag(this);\n        } else {\n          // moving to a list below this list, so move to bottom and work up (JQuery UI does not trigger new list below unless you move past top item first)\n          initialVerticalPosition = sibling.offset().top - $(this).offset().top - $(this).height();\n        }\n      } else if (moveCounter === 0) {\n        if (console && console.log) { console.log('simulate.drag-sortable.js WARNING: Drag with move set to zero has no effect'); }\n        return;\n      } else {\n        while (moveCounter !== 0) {\n          if (direction === 'down') {\n            if (sibling.next(listItem).length) {\n              sibling = sibling.next(listItem);\n              moveVerticalAmount += sibling.outerHeight();\n            }\n            moveCounter -= 1;\n          } else {\n            if (sibling.prev(listItem).length) {\n              sibling = sibling.prev(listItem);\n              moveVerticalAmount -= sibling.outerHeight();\n            }\n            moveCounter += 1;\n          }\n        }\n      }\n\n      dispatchEvent(handle, 'mousedown', createEvent('mousedown', handle, { clientX: x, clientY: y }));\n      // simulate drag start\n      dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x+1, clientY: y+1 }));\n\n      if (dropOn) {\n        // jump to top or bottom of new list but do it in increments so that JQuery UI registers the drag events\n        slideUpTo(x, y, initialVerticalPosition);\n\n        // reset y position to top or bottom of list and move from there\n        y += initialVerticalPosition;\n\n        // now call regular shift/down in a list\n        options = jQuery.extend(options, { move: moveCounter });\n        delete options.dropOn;\n\n        // add some delays to allow JQuery UI to catch up\n        setTimeout(function() {\n          dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y }));\n        }, 5);\n        setTimeout(function() {\n          dispatchEvent(handle, 'mouseup', createEvent('mouseup', handle, { clientX: x, clientY: y }));\n          setTimeout(function() {\n            if (options.move) {\n              applyDrag.call(that, options);\n            }\n          }, 5);\n        }, mouseUpAfter);\n\n        // stop execution as applyDrag has been called again\n        return;\n      }\n\n      // Sortable is using a fixed height placeholder meaning items jump up and down as you drag variable height items into fixed height placeholder\n      placeHolder = placeHolder && $(this).parent().find(placeHolder);\n\n      if (!placeHolder && (direction === 'down')) {\n        // need to move at least as far as this item and or the last sibling\n        if ($(this).outerHeight() > $(sibling).outerHeight()) {\n          moveVerticalAmount += $(this).outerHeight() - $(sibling).outerHeight();\n        }\n        moveVerticalAmount += extraDrag(sibling);\n        dragPastBy += extraDrag(sibling);\n      } else if (direction === 'up') {\n        // move a little extra to ensure item clips into next position\n        moveVerticalAmount -= Math.max(extraDrag(this), 5);\n      } else if (direction === 'down') {\n        // moving down with a place holder\n        if (placeHolder.height() < $(this).height()) {\n          moveVerticalAmount += Math.max(placeHolder.height(), 5);\n        } else {\n          moveVerticalAmount += extraDrag(sibling);\n        }\n      }\n\n      if (sibling[0] !== $(this)[0]) {\n        // step through so that the UI controller can determine when to show the placeHolder\n        slideUpTo(x, y, moveVerticalAmount, dragPastBy);\n      } else {\n        if (window.console) {\n          console.log('simulate.drag-sortable.js WARNING: Could not move as at top or bottom already');\n        }\n      }\n\n      setTimeout(function() {\n        dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + moveVerticalAmount }));\n      }, 5);\n      setTimeout(function() {\n        dispatchEvent(handle, 'mouseup', createEvent('mouseup', handle, { clientX: x, clientY: y + moveVerticalAmount }));\n      }, mouseUpAfter);\n    };\n\n    // iterate and move each matched element\n    return this.each(applyDrag);\n  };\n\n  // fire mouse events, go half way, then the next half, so small mouse movements near target and big at the start\n  function slideUpTo(x, y, targetOffset, goPastBy) {\n    var moveBy, offset;\n\n    if (!goPastBy) { goPastBy = 0; }\n    if ((targetOffset < 0) && (goPastBy > 0)) { goPastBy = -goPastBy; } // ensure go past is in the direction as often passed in from object height so always positive\n\n    // go forwards including goPastBy\n    for (offset = 0; Math.abs(offset) + 1 < Math.abs(targetOffset + goPastBy); offset += ((targetOffset + goPastBy - offset)/2) ) {\n      dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + Math.ceil(offset) }));\n    }\n    offset = targetOffset + goPastBy;\n    dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + offset }));\n\n    // now bounce back\n    for (; Math.abs(offset) - 1 >= Math.abs(targetOffset); offset += ((targetOffset - offset)/2) ) {\n      dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + Math.ceil(offset) }));\n    }\n    dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + targetOffset }));\n  }\n\n  function createEvent(type, target, options) {\n    var evt;\n    var e = $.extend({\n      target: target,\n      preventDefault: function() { },\n      stopImmediatePropagation: function() { },\n      stopPropagation: function() { },\n      isPropagationStopped: function() { return true; },\n      isImmediatePropagationStopped: function() { return true; },\n      isDefaultPrevented: function() { return true; },\n      bubbles: true,\n      cancelable: (type != \"mousemove\"),\n      view: window,\n      detail: 0,\n      screenX: 0,\n      screenY: 0,\n      clientX: 0,\n      clientY: 0,\n      ctrlKey: false,\n      altKey: false,\n      shiftKey: false,\n      metaKey: false,\n      button: 0,\n      relatedTarget: undefined\n    }, options || {});\n\n    if ($.isFunction(document.createEvent)) {\n      evt = document.createEvent(\"MouseEvents\");\n      evt.initMouseEvent(type, e.bubbles, e.cancelable, e.view, e.detail,\n        e.screenX, e.screenY, e.clientX, e.clientY,\n        e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,\n        e.button, e.relatedTarget || document.body.parentNode);\n    } else if (document.createEventObject) {\n      evt = document.createEventObject();\n      $.extend(evt, e);\n        evt.button = { 0:1, 1:4, 2:2 }[evt.button] || evt.button;\n    }\n    return evt;\n  }\n\n  function dispatchEvent(el, type, evt) {\n    if (el.dispatchEvent) {\n      el.dispatchEvent(evt);\n    } else if (el.fireEvent) {\n      el.fireEvent('on' + type, evt);\n    }\n    return evt;\n  }\n\n  function findCenter(el) {\n    var elm = $(el),\n        o = elm.offset();\n    return {\n      x: o.left + elm.outerWidth() / 2,\n      y: o.top + elm.outerHeight() / 2\n    };\n  }\n\n  //\n  // plugin defaults\n  //\n  $.fn.simulateDragSortable.defaults = {\n    move: 0\n  };\n})(jQuery);"
  },
  {
    "path": "src/rails_admin/abstract-select.js",
    "content": "import jQuery from \"jquery\";\nimport \"jquery-ui/ui/widget.js\";\n\n(function ($) {\n  \"use strict\";\n\n  $.widget(\"ra.abstractSelect\", {\n    options: {\n      createQuery: function (query) {\n        if ($.isEmptyObject(this.scopeBy)) {\n          return { query: query };\n        } else {\n          const filterQuery = {};\n          for (var field in this.scopeBy) {\n            const targetField = this.scopeBy[field];\n            const targetValue = $(`[name$=\"[${field}]\"]`).val();\n            if (!filterQuery[targetField]) {\n              filterQuery[targetField] = [];\n            }\n            filterQuery[targetField].push(\n              targetValue ? { o: \"is\", v: targetValue } : { o: \"_blank\" }\n            );\n          }\n          return { query: query, f: filterQuery };\n        }\n      },\n      scopeBy: {},\n    },\n  });\n})(jQuery);\n"
  },
  {
    "path": "src/rails_admin/base.js",
    "content": "import Rails from \"@rails/ujs\";\nimport \"@hotwired/turbo-rails\";\nimport \"./jquery\";\nimport \"./vendor/jquery_nested_form\";\nimport \"bootstrap\";\n\n// These jQuery-UI indirect dependencies need to be preloaded to be used within Import maps\nimport \"jquery-ui/ui/version.js\";\nimport \"jquery-ui/ui/keycode.js\";\nimport \"jquery-ui/ui/position.js\";\nimport \"jquery-ui/ui/safe-active-element.js\";\nimport \"jquery-ui/ui/data.js\";\nimport \"jquery-ui/ui/ie.js\";\nimport \"jquery-ui/ui/scroll-parent.js\";\nimport \"jquery-ui/ui/unique-id.js\";\nimport \"jquery-ui/ui/widget.js\";\nimport \"jquery-ui/ui/widgets/menu.js\";\nimport \"jquery-ui/ui/widgets/mouse.js\";\n\nimport \"./abstract-select\";\nimport \"./filter-box\";\nimport \"./filtering-multiselect\";\nimport \"./filtering-select\";\nimport \"./nested-form-hooks\";\nimport \"./remote-form\";\nimport \"./sidescroll\";\nimport \"./ui\";\nimport \"./widgets\";\n\nif (!window._rails_loaded) {\n  Rails.start();\n}\n"
  },
  {
    "path": "src/rails_admin/filter-box.js",
    "content": "import jQuery from \"jquery\";\nimport I18n from \"./i18n\";\nimport flatpickr from \"flatpickr\";\n\n(function ($) {\n  var filters;\n\n  $.filters = filters = {\n    append: function (options) {\n      var field_label = options[\"label\"];\n      var field_name = options[\"name\"];\n      var field_type = options[\"type\"];\n      var field_value = options[\"value\"] || \"\";\n      var field_operator = options[\"operator\"];\n      var operators = options[\"operators\"];\n      var index = options[\"index\"];\n      var value_name = \"f[\" + field_name + \"][\" + index + \"][v]\";\n      var operator_name = \"f[\" + field_name + \"][\" + index + \"][o]\";\n      var control = null;\n      var additional_control = null;\n\n      if (operators.length > 0) {\n        control = $(\n          '<select class=\"form-control form-select form-select-sm\"></select>'\n        ).prop(\"name\", operator_name);\n\n        operators.forEach((operator) => {\n          var element = this.build_operator(operator, options);\n          if (!element) {\n            return;\n          }\n          if (element.prop(\"value\") === field_operator) {\n            element.prop(\"selected\", true);\n          }\n          control.append(element);\n        });\n\n        if (control.find(\"[data-additional-fieldset]\").length > 0) {\n          control.addClass(\"switch-additional-fieldsets\");\n        }\n      }\n\n      switch (field_type) {\n        case \"boolean\":\n          control &&\n            control\n              .prop(\"name\", value_name)\n              .find(\"option\")\n              .each(function () {\n                if ($(this).attr(\"value\") === field_value)\n                  $(this).attr(\"selected\", true);\n              });\n          break;\n        case \"date\":\n        case \"datetime\":\n        case \"timestamp\":\n        case \"time\":\n          additional_control = $.map(\n            [undefined, \"-∞\", \"∞\"],\n            function (placeholder, index) {\n              var visible =\n                index == 0\n                  ? !field_operator || field_operator == \"default\"\n                  : field_operator == \"between\";\n              return $('<span class=\"additional-fieldset\"></span>')\n                .addClass(index == 0 ? \"default\" : \"between\")\n                .css(\"display\", visible ? \"inline-block\" : \"none\")\n                .html(\n                  $(\n                    '<input class=\"input-sm form-control form-control-sm\" type=\"text\" />'\n                  )\n                    .addClass(field_type == \"date\" ? \"date\" : \"datetime\")\n                    .prop(\"name\", value_name + \"[]\")\n                    .prop(\"value\", field_value[index] || \"\")\n                    .prop(\n                      \"size\",\n                      field_type == \"date\" || field_type == \"time\" ? 20 : 25\n                    )\n                    .prop(\"placeholder\", placeholder)\n                );\n            }\n          );\n          break;\n        case \"enum\":\n          if (control) {\n            var multiple = field_value instanceof Array;\n            control = control\n              .prop(\"name\", multiple ? value_name + \"[]\" : value_name)\n              .prop(\"multiple\", multiple)\n              .add(\n                $('<a href=\"#\" class=\"switch-select\"></a>').append(\n                  $(\"<i></i>\").addClass(\n                    \"fas fa-\" + (multiple ? \"minus\" : \"plus\")\n                  )\n                )\n              );\n            control.find(\"option\").each(function () {\n              const value = $(this).attr(\"value\");\n              if (\n                multiple ? field_value.includes(value) : value === field_value\n              )\n                $(this).attr(\"selected\", true);\n            });\n            if (multiple)\n              control.find(\"option[value^=_],option[disabled]\").hide();\n          }\n          break;\n        case \"citext\":\n        case \"string\":\n        case \"text\":\n        case \"belongs_to_association\":\n        case \"has_one_association\":\n          additional_control = $(\n            '<input class=\"additional-fieldset form-control form-control-sm\" type=\"text\" />'\n          )\n            .css(\n              \"display\",\n              field_operator == \"_present\" || field_operator == \"_blank\"\n                ? \"none\"\n                : \"inline-block\"\n            )\n            .prop(\"name\", value_name)\n            .prop(\"value\", field_value);\n          break;\n        case \"integer\":\n        case \"decimal\":\n        case \"float\":\n          additional_control = $(\n            '<input class=\"additional-fieldset default form-control form-control-sm\" type=\"text\" />'\n          )\n            .css(\n              \"display\",\n              !field_operator || field_operator == \"default\"\n                ? \"inline-block\"\n                : \"none\"\n            )\n            .prop(\"type\", field_type)\n            .prop(\"name\", value_name + \"[]\")\n            .prop(\"value\", field_value[0] || \"\")\n            .add(\n              $(\n                '<input placeholder=\"-∞\" class=\"additional-fieldset between form-control form-control-sm\" />'\n              )\n                .css(\n                  \"display\",\n                  field_operator == \"between\" ? \"inline-block\" : \"none\"\n                )\n                .prop(\"type\", field_type)\n                .prop(\"name\", value_name + \"[]\")\n                .prop(\"value\", field_value[1] || \"\")\n            )\n            .add(\n              $(\n                '<input placeholder=\"∞\" class=\"additional-fieldset between form-control form-control-sm\" />'\n              )\n                .css(\n                  \"display\",\n                  field_operator == \"between\" ? \"inline-block\" : \"none\"\n                )\n                .prop(\"type\", field_type)\n                .prop(\"name\", value_name + \"[]\")\n                .prop(\"value\", field_value[2] || \"\")\n            );\n          break;\n        default:\n          control = $(\n            '<input type=\"text\" class=\"form-control form-control-sm\" />'\n          )\n            .prop(\"name\", value_name)\n            .prop(\"value\", field_value);\n          break;\n      }\n\n      var filterContainerId = field_name + \"-\" + index + \"-filter-container\";\n      $(\"#\" + filterContainerId).remove();\n\n      var $content = $(\"<div>\")\n        .attr(\"id\", filterContainerId)\n        .addClass(\"filter d-inline-block my-1\")\n        .append(\n          $(\n            '<button type=\"button\" class=\"btn btn-info btn-sm delete\"></button>'\n          )\n            .append('<i class=\"fas fa-trash\"></i>')\n            .append(document.createTextNode(field_label))\n        )\n        .append(\"&nbsp;\")\n        .append(control)\n        .append(\"&nbsp;\")\n        .append(additional_control);\n\n      $(\"#filters_box\").append($content);\n\n      $content.find(\".date, .datetime\").each(function () {\n        flatpickr(\n          this,\n          $.extend(\n            {\n              dateFormat: \"Y-m-dTH:i:S\",\n              altInput: true,\n              locale: I18n.locale,\n            },\n            options[\"datetimepicker_options\"]\n          )\n        );\n      });\n\n      $(\"hr.filters_box:hidden\").show(\"slow\");\n    },\n    build_operator: function (operator, options) {\n      if (operator instanceof Object) {\n        var element = $(\"<option></option>\");\n        element.text(operator.label);\n        delete operator.label;\n        for (const key in operator) {\n          element.attr(key, operator[key]);\n        }\n        return element;\n      }\n      switch (operator) {\n        case \"_discard\":\n          return $('<option value=\"_discard\">...</option>');\n        case \"_separator\":\n          return $('<option disabled=\"disabled\">---------</option>');\n        case \"_present\":\n          return $('<option value=\"_present\"></option>').text(\n            I18n.t(\"is_present\")\n          );\n        case \"_blank\":\n          return $('<option value=\"_blank\"></option>').text(I18n.t(\"is_blank\"));\n        case \"_not_null\":\n          return $('<option value=\"_not_null\"></option>').text(\n            I18n.t(\"is_present\")\n          );\n        case \"_null\":\n          return $('<option value=\"_null\"></option>').text(I18n.t(\"is_blank\"));\n\n        case \"true\":\n          return $('<option value=\"true\"></option>').text(I18n.t(\"true\"));\n        case \"false\":\n          return $('<option value=\"false\"></option>').text(I18n.t(\"false\"));\n\n        case \"today\":\n          return $('<option value=\"today\"></option>').text(I18n.t(\"today\"));\n        case \"yesterday\":\n          return $('<option value=\"yesterday\"></option>').text(\n            I18n.t(\"yesterday\")\n          );\n        case \"this_week\":\n          return $('<option value=\"this_week\"></option>').text(\n            I18n.t(\"this_week\")\n          );\n        case \"last_week\":\n          return $('<option value=\"last_week\"></option>').text(\n            I18n.t(\"last_week\")\n          );\n\n        case \"like\":\n          return $(\n            '<option data-additional-fieldset=\"additional-fieldset\" value=\"like\"></option>'\n          ).text(I18n.t(\"contains\"));\n        case \"not_like\":\n          return $(\n            '<option data-additional-fieldset=\"additional-fieldset\" value=\"not_like\"></option>'\n          ).text(I18n.t(\"does_not_contain\"));\n        case \"is\":\n          return $(\n            '<option data-additional-fieldset=\"additional-fieldset\" value=\"is\"></option>'\n          ).text(I18n.t(\"is_exactly\"));\n        case \"starts_with\":\n          return $(\n            '<option data-additional-fieldset=\"additional-fieldset\" value=\"starts_with\"></option>'\n          ).text(I18n.t(\"starts_with\"));\n        case \"ends_with\":\n          return $(\n            '<option data-additional-fieldset=\"additional-fieldset\" value=\"ends_with\"></option>'\n          ).text(I18n.t(\"ends_with\"));\n\n        case \"default\":\n          var label;\n          switch (options.type) {\n            case \"date\":\n            case \"datetime\":\n            case \"timestamp\":\n              label = I18n.t(\"date\");\n              break;\n            case \"time\":\n              label = I18n.t(\"time\");\n              break;\n            case \"integer\":\n            case \"decimal\":\n            case \"float\":\n              label = I18n.t(\"number\");\n              break;\n          }\n          return $(\n            '<option data-additional-fieldset=\"default\" value=\"default\"></option>'\n          ).text(label);\n        case \"between\":\n          return $(\n            '<option data-additional-fieldset=\"between\" value=\"between\"></option>'\n          ).text(I18n.t(\"between_and_\"));\n\n        default:\n          return null;\n      }\n    },\n  };\n\n  $(document).on(\"click\", \"#filters a\", function (e) {\n    e.preventDefault();\n    $.filters.append(\n      $.extend(\n        { index: $.now().toString().slice(6, 11) },\n        $(this).data(\"options\")\n      )\n    );\n  });\n\n  $(document).on(\"click\", \"#filters_box .delete\", function (e) {\n    e.preventDefault();\n    var form = $(this).parents(\"form\");\n    $(this).parents(\".filter\").remove();\n    !$(\"#filters_box\").children().length &&\n      $(\"hr.filters_box:visible\").hide(\"slow\");\n  });\n\n  $(document).on(\"click\", \"#filters_box .switch-select\", function (e) {\n    e.preventDefault();\n    var select = $(this).siblings(\"select\");\n    select.attr(\"multiple\", !select.attr(\"multiple\"));\n    select.attr(\n      \"name\",\n      select.attr(\"multiple\")\n        ? select.attr(\"name\") + \"[]\"\n        : select.attr(\"name\").replace(/\\[\\]$/, \"\")\n    );\n    select.find(\"option[value^=_],option[disabled]\").toggle();\n    $(this).find(\"i\").toggleClass(\"fa-plus fa-minus\");\n  });\n\n  $(document).on(\n    \"change\",\n    \"#filters_box .switch-additional-fieldsets\",\n    function (e) {\n      var selected_option = $(this).find(\"option:selected\");\n      var klass = $(selected_option).data(\"additional-fieldset\");\n      if (klass) {\n        $(this)\n          .siblings(\".additional-fieldset:not(.\" + klass + \")\")\n          .hide(\"slow\");\n        $(this)\n          .siblings(\".\" + klass)\n          .show(\"slow\");\n      } else {\n        $(this).siblings(\".additional-fieldset\").hide(\"slow\");\n      }\n    }\n  );\n})(jQuery);\n"
  },
  {
    "path": "src/rails_admin/filtering-multiselect.js",
    "content": "import jQuery from \"jquery\";\nimport \"jquery-ui/ui/widget.js\";\nimport I18n from \"./i18n\";\n\n(function ($) {\n  $.widget(\"ra.filteringMultiselect\", $.ra.abstractSelect, {\n    _cache: {},\n    options: {\n      sortable: false,\n      removable: true,\n      regional: {\n        add: \"Add\",\n        chooseAll: \"Choose all\",\n        clearAll: \"Clear all\",\n        down: \"Down\",\n        remove: \"Remove\",\n        search: \"Search\",\n        up: \"Up\",\n      },\n      searchDelay: 400,\n      remote_source: null,\n      xhr: false,\n    },\n\n    wrapper: null,\n    filter: null,\n    collection: null,\n    addAll: null,\n    add: null,\n    remove: null,\n    up: null,\n    down: null,\n    selection: null,\n    removeAll: null,\n\n    _create: function () {\n      this._cache = {};\n      this._build();\n      this._buildCache();\n      this._bindEvents();\n    },\n\n    _build: function () {\n      var i;\n\n      this.wrapper = this.element.siblings(\n        '.ra-multiselect[data-input-for=\"' + this.element.attr(\"id\") + '\"]'\n      );\n\n      // Prevent duplication on browser back\n      if (this.wrapper.length > 0) {\n        this.filter = this.wrapper.find(\"input.ra-multiselect-search\");\n        this.collection = this.wrapper.find(\"select.ra-multiselect-collection\");\n        this.addAll = this.wrapper.find(\"a.ra-multiselect-item-add-all\");\n        this.add = this.wrapper.find(\"a.ra-multiselect-item-add\");\n        this.remove = this.wrapper.find(\"a.ra-multiselect-item-remove\");\n        this.up = this.wrapper.find(\"a.ra-multiselect-item-up\");\n        this.down = this.wrapper.find(\"a.ra-multiselect-item-down\");\n        this.selection = this.wrapper.find(\"select.ra-multiselect-selection\");\n        this.removeAll = this.wrapper.find(\"a.ra-multiselect-item-remove-all\");\n        return;\n      }\n\n      this.wrapper = $('<div class=\"ra-multiselect\">').attr(\n        \"data-input-for\",\n        this.element.attr(\"id\")\n      );\n      this.wrapper.insertAfter(this.element);\n      var header = $('<div class=\"ra-multiselect-header\">');\n      this.filter = $(\n        '<input type=\"search\" placeholder=\"' +\n          this.options.regional.search +\n          '\" class=\"form-control ra-multiselect-search\"/>'\n      );\n      header.append(this.filter);\n      this.wrapper.append(header);\n\n      var columns = {\n        left: $('<div class=\"ra-multiselect-column ra-multiselect-left\">'),\n        center: $('<div class=\"ra-multiselect-column ra-multiselect-center\">'),\n        right: $('<div class=\"ra-multiselect-column ra-multiselect-right\">'),\n      };\n\n      for (i in columns) {\n        if (columns.hasOwnProperty(i)) {\n          this.wrapper.append(columns[i]);\n        }\n      }\n\n      this.collection = $('<select multiple=\"multiple\"></select>');\n      this.collection.addClass(\"form-control ra-multiselect-collection\");\n      this.addAll = $(\n        '<a href=\"#\" class=\"ra-multiselect-item-add-all\"><span class=\"fas fa-chevron-circle-right\"></span>' +\n          this.options.regional.chooseAll +\n          \"</a>\"\n      );\n      columns.left.html(this.collection).append(this.addAll);\n      this.collection.wrap('<div class=\"wrapper\"/>');\n\n      this.add = $(\n        '<a href=\"#\" class=\"fas fa-chevron-circle-right ra-multiselect-item-add\"></a>'\n      ).attr(\"title\", this.options.regional.add);\n      columns.center.append(this.add);\n      if (this.options.removable) {\n        this.remove = $(\n          '<a href=\"#\" class=\"fas fa-chevron-circle-left ra-multiselect-item-remove\"></a>'\n        ).attr(\"title\", this.options.regional.remove);\n        columns.center.append(this.remove);\n      }\n      if (this.options.sortable) {\n        this.up = $(\n          '<a href=\"#\" class=\"fas fa-chevron-circle-up ra-multiselect-item-up\"></a>'\n        ).attr(\"title\", this.options.regional.up);\n        this.down = $(\n          '<a href=\"#\" class=\"fas fa-chevron-circle-down ra-multiselect-item-down\"></a>'\n        ).attr(\"title\", this.options.regional.down);\n        columns.center.append(this.up).append(this.down);\n      }\n\n      this.selection = $(\n        '<select class=\"form-control ra-multiselect-selection\" multiple=\"multiple\"></select>'\n      );\n      columns.right.append(this.selection);\n      if (this.options.removable) {\n        this.removeAll = $(\n          '<a href=\"#\" class=\"ra-multiselect-item-remove-all\"><span class=\"fas fa-chevron-circle-left\"></span>' +\n            this.options.regional.clearAll +\n            \"</a>\"\n        );\n        columns.right.append(this.removeAll);\n      }\n      this.selection.wrap('<div class=\"wrapper\"/>');\n\n      this.element.css({ display: \"none\" });\n\n      this.tooManyObjectsPlaceholder = $('<option disabled=\"disabled\" />').text(\n        I18n.t(\"too_many_objects\")\n      );\n      this.noObjectsPlaceholder = $('<option disabled=\"disabled\" />').text(\n        I18n.t(\"no_objects\")\n      );\n\n      if (this.options.xhr) {\n        this.collection.append(this.tooManyObjectsPlaceholder);\n      }\n    },\n\n    _bindEvents: function () {\n      var widget = this;\n\n      /* Add all to selection */\n      this.addAll.click(function (e) {\n        widget._select($(\"option:not(:disabled)\", widget.collection));\n        e.preventDefault();\n        widget.selection.trigger(\"change\");\n      });\n\n      /* Add to selection */\n      this.add.click(function (e) {\n        widget._select($(\":selected\", widget.collection));\n\n        e.preventDefault();\n        widget.selection.trigger(\"change\");\n      });\n\n      if (this.options.removable) {\n        /* Remove all from selection */\n        this.removeAll.click(function (e) {\n          widget._deSelect($(\"option\", widget.selection));\n          e.preventDefault();\n          widget.selection.trigger(\"change\");\n        });\n\n        /* Remove from selection */\n        this.remove.click(function (e) {\n          widget._deSelect($(\":selected\", widget.selection));\n          e.preventDefault();\n          widget.selection.trigger(\"change\");\n        });\n      }\n\n      var timeout = null;\n      if (this.options.sortable) {\n        /* Move selection up */\n        this.up.click(function (e) {\n          widget._move(\"up\", $(\":selected\", widget.selection));\n          e.preventDefault();\n        });\n\n        /* Move selection down */\n        this.down.click(function (e) {\n          widget._move(\"down\", $(\":selected\", widget.selection));\n          e.preventDefault();\n        });\n      }\n\n      /* Typing to the filter */\n      this.filter.bind(\"keyup click\", function (e) {\n        if (timeout) {\n          clearTimeout(timeout);\n        }\n        timeout = setTimeout(function () {\n          widget._queryFilter(widget.filter.val());\n        }, widget.options.searchDelay);\n      });\n    },\n\n    _queryFilter: function (val) {\n      var widget = this;\n      widget._query(val, function (matches) {\n        var filtered = [];\n        var i;\n\n        for (i = 0; i < matches.length; i++) {\n          if (!widget.selected(matches[i].id)) {\n            filtered.push(i);\n          }\n        }\n        if (filtered.length > 0) {\n          widget.collection.html(\"\");\n          for (i = 0; i < filtered.length; i++) {\n            var newOptions = $(\"<option></option>\")\n              .prop(\"value\", matches[filtered[i]].id)\n              .prop(\"title\", matches[filtered[i]].label)\n              .text(matches[filtered[i]].label);\n            widget.collection.append(newOptions);\n          }\n        } else {\n          widget.collection.html(widget.noObjectsPlaceholder);\n        }\n      });\n    },\n\n    /*\n     * Cache key is stored in the format `o_<option value>` to avoid JS\n     * engine coercing string keys to int keys, and thereby preserving\n     * the insertion order. The value for each key is in turn an object\n     * that stores the option tag's HTML text and the value. Example:\n     * cache = {\n     *    'o_271': { id: 271, value: 'CartItem #271'},\n     *    'o_270': { id: 270, value: 'CartItem #270'}\n     * }\n     */\n    _buildCache: function (options) {\n      var widget = this;\n\n      this.element.find(\"option\").each(function (i, option) {\n        widget._cache[\"o_\" + option.value] = {\n          id: option.value,\n          value: $(option).text(),\n        };\n        if (option.selected) {\n          $(option)\n            .clone()\n            .appendTo(widget.selection)\n            .prop(\"selected\", false)\n            .prop(\"title\", $(option).text());\n        } else {\n          $(option)\n            .clone()\n            .appendTo(widget.collection)\n            .prop(\"selected\", false)\n            .prop(\"title\", $(option).text());\n        }\n      });\n    },\n\n    _deSelect: function (options) {\n      var widget = this;\n      options.each(function (i, option) {\n        widget.element\n          .find('option[value=\"' + option.value + '\"]')\n          .prop(\"selected\", false);\n      });\n      $(options).appendTo(this.collection).prop(\"selected\", false);\n    },\n\n    _query: function (query, success) {\n      var i,\n        matches = [];\n\n      if (query === \"\") {\n        if (!this.options.xhr) {\n          for (i in this._cache) {\n            if (this._cache.hasOwnProperty(i)) {\n              var option = this._cache[i];\n              matches.push({ id: option.id, label: option.value });\n            }\n          }\n          success.apply(this, [matches]);\n        } else {\n          this.collection.html(this.tooManyObjectsPlaceholder);\n        }\n      } else {\n        if (this.options.xhr) {\n          $.ajax({\n            beforeSend: function (xhr) {\n              xhr.setRequestHeader(\"Accept\", \"application/json\");\n            },\n            url: this.options.remote_source,\n            data: this.options.createQuery(query),\n            success: success,\n          });\n        } else {\n          query = new RegExp(query + \".*\", \"i\");\n\n          for (i in this._cache) {\n            if (\n              this._cache.hasOwnProperty(i) &&\n              query.test(this._cache[i][\"value\"])\n            ) {\n              var option = this._cache[i];\n              matches.push({ id: option.id, label: option.value });\n            }\n          }\n\n          success.apply(this, [matches]);\n        }\n      }\n    },\n\n    _select: function (options) {\n      var widget = this;\n      options.each(function (i, option) {\n        var el = widget.element.find('option[value=\"' + option.value + '\"]');\n        if (el.length) {\n          el.prop(\"selected\", true);\n        } else {\n          widget.element.append(\n            $(\"<option></option>\")\n              .prop(\"value\", option.value)\n              .prop(\"selected\", true)\n          );\n        }\n      });\n      $(options).appendTo(this.selection).prop(\"selected\", false);\n    },\n\n    _move: function (direction, options) {\n      var widget = this;\n      if (direction == \"up\") {\n        options.each(function (i, option) {\n          var prev = $(option).prev();\n          if (prev.length > 0) {\n            var el = widget.element.find(\n              'option[value=\"' + option.value + '\"]'\n            );\n            var el_prev = widget.element.find(\n              'option[value=\"' + prev[0].value + '\"]'\n            );\n            el_prev.before(el);\n            prev.before($(option));\n          }\n        });\n      } else {\n        $.fn.reverse = [].reverse; // needed to lower last items first\n        options.reverse().each(function (i, option) {\n          var next = $(option).next();\n          if (next.length > 0) {\n            var el = widget.element.find(\n              'option[value=\"' + option.value + '\"]'\n            );\n            var el_next = widget.element.find(\n              'option[value=\"' + next[0].value + '\"]'\n            );\n            el_next.after(el);\n            next.after($(option));\n          }\n        });\n      }\n    },\n\n    selected: function (value) {\n      if (\n        this.selection[0].querySelectorAll('option[value=\"' + value + '\"]')[0]\n      ) {\n        return true;\n      }\n    },\n\n    destroy: function () {\n      this.wrapper.remove();\n      this.element.css({ display: \"inline\" });\n      $.Widget.prototype.destroy.apply(this, arguments);\n    },\n  });\n})(jQuery);\n"
  },
  {
    "path": "src/rails_admin/filtering-select.js",
    "content": "import jQuery from \"jquery\";\nimport \"jquery-ui/ui/widget.js\";\nimport \"jquery-ui/ui/widgets/autocomplete.js\";\nimport I18n from \"./i18n\";\n\n(function ($) {\n  \"use strict\";\n\n  $.widget(\"ra.filteringSelect\", $.ra.abstractSelect, {\n    options: {\n      minLength: 0,\n      searchDelay: 200,\n      remote_source: null,\n      source: null,\n      xhr: false,\n    },\n\n    button: null,\n    input: null,\n    select: null,\n    filtering_select: null,\n\n    _create: function () {\n      this.filtering_select = this.element.siblings(\n        '[data-input-for=\"' + this.element.attr(\"id\") + '\"]'\n      );\n\n      // When using the browser back and forward buttons, it is possible that\n      // the autocomplete field will be cached which causes duplicate fields\n      // to be generated.\n      if (this.filtering_select.length > 0) {\n        this.input = this.filtering_select.children(\"input\");\n        this.button = this.filtering_select.children(\".input-group-btn\");\n      } else {\n        this.element.hide();\n        this.filtering_select = this._inputGroup(this.element.attr(\"id\"));\n        this.input = this._inputField();\n        this.button = this._buttonField();\n      }\n      this.clearOption = $('<span style=\"color: #888\"></span>').append(\n        '<i class=\"fas fa-times\"></i> ' +\n          $(\"<span></span>\").text(I18n.t(\"clear\")).html()\n      );\n      this.noObjectsPlaceholder = $('<option disabled=\"disabled\" />').text(\n        I18n.t(\"no_objects\")\n      );\n\n      this._setOptionsSource();\n      this._initAutocomplete();\n      this._initKeyEvent();\n      this._overloadRenderItem();\n      this._autocompleteDropdownEvent(this.button);\n\n      return this.filtering_select\n        .append(this.input)\n        .append(this.button)\n        .insertAfter(this.element);\n    },\n\n    _getResultSet: function (request, data, xhr) {\n      var matcher = new RegExp(\n        $.ui.autocomplete.escapeRegex(request.term),\n        \"i\"\n      );\n\n      var spannedContent = function (content) {\n        return $(\"<span>\").text(content).html();\n      };\n\n      var highlighter = function (label, word) {\n        if (word.length) {\n          return $.map(label.split(word), function (el) {\n            return spannedContent(el);\n          }).join($(\"<strong>\").text(word)[0].outerHTML);\n        } else {\n          return spannedContent(label);\n        }\n      };\n\n      var matches = $.map(data, function (el) {\n        var id = el.id || el.value;\n        var value = el.label || el.id;\n        // match regexp only for local requests, remote ones are already\n        // filtered, and label may not contain filtered term.\n        if (id && (xhr || matcher.test(el.label))) {\n          return {\n            html: highlighter(value, request.term),\n            value: value,\n            id: id,\n          };\n        }\n      });\n\n      if (request.term.length === 0 && !this.input.attr(\"required\")) {\n        return [{ html: this.clearOption, value: null, id: null }].concat(\n          matches\n        );\n      } else if (matches.length === 0) {\n        return [{ html: this.noObjectsPlaceholder, value: null, id: null }];\n      } else {\n        return matches;\n      }\n    },\n\n    _getSourceFunction: function (source) {\n      var self = this;\n      var requestIndex = 0;\n\n      if ($.isArray(source)) {\n        return function (request, response) {\n          response(self._getResultSet(request, source, false));\n        };\n      } else if (typeof source === \"string\") {\n        return function (request, response) {\n          if (this.xhr) {\n            this.xhr.abort();\n          }\n\n          this.xhr = $.ajax({\n            url: source,\n            data: self.options.createQuery(request.term),\n            dataType: \"json\",\n            autocompleteRequest: ++requestIndex,\n            success: function (data, status) {\n              if (this.autocompleteRequest === requestIndex) {\n                response(self._getResultSet(request, data, true));\n              }\n            },\n            error: function () {\n              if (this.autocompleteRequest === requestIndex) {\n                response([]);\n              }\n            },\n          });\n        };\n      } else {\n        return source;\n      }\n    },\n\n    _setOptionsSource: function () {\n      if (this.options.xhr) {\n        this.options.source = this.options.remote_source;\n      } else {\n        this.options.source = this.element\n          .children(\"option\")\n          .map(function () {\n            return { label: $(this).text(), value: this.value };\n          })\n          .toArray();\n      }\n    },\n\n    _buttonField: function () {\n      return $(\n        '<span class=\"input-group-btn\">' +\n          '<label class=\"btn btn-info dropdown-toggle\" title=\"Show All Items\" role=\"button\">' +\n          \"</label>\" +\n          \"</span>\"\n      );\n    },\n\n    _autocompleteDropdownEvent: function (element) {\n      var self = this;\n\n      return element.click(function () {\n        // close if already visible\n        if (self.input.autocomplete(\"widget\").is(\":visible\")) {\n          self.input.autocomplete(\"close\");\n          return;\n        }\n\n        // pass empty string as value to search for, displaying all results\n        self.input.autocomplete(\"search\", \"\");\n        self.input.focus();\n      });\n    },\n\n    _inputField: function () {\n      var input;\n      var selected = this.element.children(\":selected\");\n      var value = selected.val() ? selected.text() : \"\";\n\n      input = $('<input type=\"text\">')\n        .val(value)\n        .addClass(\"form-control ra-filtering-select-input\")\n        .attr(\"style\", this.element.attr(\"style\"))\n        .show();\n\n      if (this.element.attr(\"placeholder\")) {\n        input.attr(\"placeholder\", this.element.attr(\"placeholder\"));\n      }\n\n      if (this.element.attr(\"required\")) {\n        input.attr(\"required\", this.element.attr(\"required\"));\n        this.element.attr(\"required\", false);\n      }\n\n      return input;\n    },\n\n    _inputGroup: function (inputFor) {\n      return $(\"<div>\")\n        .addClass(\"input-group filtering-select\")\n        .attr(\"data-input-for\", inputFor);\n    },\n\n    _initAutocomplete: function () {\n      var self = this;\n\n      return this.input.autocomplete({\n        delay: this.options.searchDelay,\n        minLength: this.options.minLength,\n        source: this._getSourceFunction(this.options.source),\n        select: function (event, ui) {\n          var option = self.element.find(\n            `option[value=\"${CSS.escape(ui.item.id)}\"]`\n          );\n          self.element.find(\"option[selected]\").attr(\"selected\", false);\n          if (option.length > 0) {\n            option.attr(\"selected\", \"selected\");\n          } else {\n            option = $(\"<option>\")\n              .attr(\"value\", ui.item.id)\n              .attr(\"selected\", true)\n              .text(ui.item.value);\n            self.element.append(option);\n          }\n          self.element.trigger(\"change\", ui.item.id);\n          self._trigger(\"selected\", event, {\n            item: option,\n          });\n          $(self.element.parents(\".controls\")[0])\n            .find(\".update\")\n            .removeClass(\"disabled\");\n        },\n        change: function (event, ui) {\n          if (ui.item) {\n            return;\n          }\n\n          var matcher = new RegExp(\n            \"^\" + $.ui.autocomplete.escapeRegex($(this).val()) + \"$\",\n            \"i\"\n          );\n          var valid = false;\n\n          self.element.children(\"option\").each(function () {\n            if ($(this).text().match(matcher)) {\n              valid = true;\n              return false;\n            }\n          });\n\n          if (valid || $(this).val() !== \"\") {\n            return;\n          }\n\n          // remove invalid value, as it didn't match anything\n          $(this).val(null);\n          self.element.html(\n            $('<option value=\"\" selected=\"selected\"></option>')\n          );\n          self.input.data(\"ui-autocomplete\").term = \"\";\n          $(self.element.parents(\".controls\")[0])\n            .find(\".update\")\n            .addClass(\"disabled\");\n          return false;\n        },\n      });\n    },\n\n    _initKeyEvent: function () {\n      var self = this;\n\n      return this.input.keyup(function () {\n        if ($(this).val().length) {\n          return;\n        }\n\n        /* Clear select options and trigger change if selected item is deleted */\n        return self.element\n          .html($('<option value=\"\" selected=\"selected\"></option>'))\n          .trigger(\"change\");\n      });\n    },\n\n    _overloadRenderItem: function () {\n      this.input.data(\"ui-autocomplete\")._renderItem = function (ul, item) {\n        return $(\"<li></li>\")\n          .data(\"ui-autocomplete-item\", item)\n          .append($(\"<a></a>\").html(item.html || item.id))\n          .appendTo(ul);\n      };\n    },\n\n    destroy: function () {\n      this.input.remove();\n      this.button.remove();\n      this.element.html($('<option value=\"\" selected=\"selected\"></option>'));\n      this.element.show();\n      this.filtering_select.remove();\n      $.Widget.prototype.destroy.call(this);\n    },\n  });\n})(jQuery);\n"
  },
  {
    "path": "src/rails_admin/i18n.js",
    "content": "var I18n = {\n  locale: null,\n  translations: null,\n  init(locale, translations) {\n    this.locale = locale;\n    this.translations = translations;\n    if (typeof this.translations === \"string\") {\n      this.translations = JSON.parse(this.translations);\n    }\n  },\n  t(key) {\n    var humanize;\n    humanize = key.charAt(0).toUpperCase() + key.replace(/_/g, \" \").slice(1);\n    return this.translations[key] || humanize;\n  },\n};\n\nexport { I18n as default };\n"
  },
  {
    "path": "src/rails_admin/jquery.js",
    "content": "import jQuery from \"jquery\";\n\nwindow.$ = window.jQuery = jQuery;\n"
  },
  {
    "path": "src/rails_admin/nested-form-hooks.js",
    "content": "import jQuery from \"jquery\";\nimport * as bootstrap from \"bootstrap\";\n\n(function ($) {\n  $(document).ready(function () {\n    return (window.nestedFormEvents.insertFields = function (\n      content,\n      assoc,\n      link\n    ) {\n      var tab_content;\n      tab_content = $(link).closest(\".controls\").siblings(\".tab-content\");\n      tab_content.append(content);\n      return tab_content.children().last();\n    });\n  });\n\n  $(document).on(\"nested:fieldAdded\", \"form\", function (content) {\n    var controls, field, nav, new_tab, one_to_one, parent_group, toggler;\n    field = content.field\n      .addClass(\"tab-pane\")\n      .attr(\"id\", \"unique-id-\" + new Date().getTime());\n    new_tab = $(\"<li></li>\")\n      .append(\n        $(\"<a></a>\")\n          .addClass(\"nav-link\")\n          .attr(\"data-bs-toggle\", \"tab\")\n          .attr(\"href\", \"#\" + field.attr(\"id\"))\n          .text(field.children(\".object-infos\").data(\"object-label\"))\n      )\n      .addClass(\"nav-item\");\n    parent_group = field.closest(\".control-group\");\n    controls = parent_group.children(\".controls\");\n    one_to_one = controls.data(\"nestedone\") !== void 0;\n    nav = controls.children(\".nav\");\n    content = parent_group.children(\".tab-content\");\n    toggler = controls.find(\".toggler\");\n    nav.append(new_tab);\n\n    const event = new CustomEvent(\"rails_admin.dom_ready\", { detail: field });\n    document.dispatchEvent(event);\n\n    new_tab.children(\"a\").each(function (index, element) {\n      bootstrap.Tab.getOrCreateInstance(element).show();\n    });\n    if (!one_to_one) {\n      new bootstrap.Collapse(nav[0], { toggle: false }).show();\n    }\n    new bootstrap.Collapse(content[0], { toggle: false }).show();\n    toggler\n      .addClass(\"active\")\n      .removeClass(\"disabled\")\n      .children(\"i\")\n      .addClass(\"fa-chevron-down\")\n      .removeClass(\"fa-chevron-right\");\n    if (one_to_one) {\n      controls\n        .find(\".add_nested_fields\")\n        .removeClass(\"add_nested_fields\")\n        .text(field.children(\".object-infos\").data(\"object-label\"));\n    }\n  });\n\n  $(document).on(\"nested:fieldRemoved\", \"form\", function (content) {\n    var add_button,\n      controls,\n      current_li,\n      field,\n      nav,\n      one_to_one,\n      parent_group,\n      toggler;\n    field = content.field;\n    nav = field\n      .closest(\".control-group\")\n      .children(\".controls\")\n      .children(\".nav\");\n    current_li = nav.children(\"li\").has('a[href=\"#' + field.attr(\"id\") + '\"]');\n    parent_group = field.closest(\".control-group\");\n    controls = parent_group.children(\".controls\");\n    one_to_one = controls.data(\"nestedone\") !== void 0;\n    toggler = controls.find(\".toggler\");\n    (current_li.next().length ? current_li.next() : current_li.prev())\n      .children(\"a:first\")\n      .each(function (index, element) {\n        bootstrap.Tab.getOrCreateInstance(element).show();\n      });\n    current_li.remove();\n    if (nav.children().length === 0) {\n      new bootstrap.Collapse(controls.siblings(\".tab-content\")[0], {\n        toggle: false,\n      }).hide();\n      toggler\n        .removeClass(\"active\")\n        .addClass(\"disabled\")\n        .children(\"i\")\n        .removeClass(\"fa-chevron-down\")\n        .addClass(\"fa-chevron-right\");\n    }\n    if (one_to_one) {\n      add_button = toggler.next();\n      add_button\n        .addClass(\"add_nested_fields\")\n        .html(add_button.data(\"add-label\"));\n    }\n    field.find(\"[required]\").each(function () {\n      $(this).prop(\"required\", false);\n    });\n  });\n})(jQuery);\n"
  },
  {
    "path": "src/rails_admin/remote-form.js",
    "content": "import Rails from \"@rails/ujs\";\nimport jQuery from \"jquery\";\nimport \"jquery-ui/ui/widget.js\";\nimport * as bootstrap from \"bootstrap\";\n\n(function ($) {\n  $.widget(\"ra.remoteForm\", {\n    _create: function () {\n      var widget = this;\n      var dom_widget = widget.element;\n\n      var edit_url =\n        dom_widget.find(\"select\").first().data(\"options\") &&\n        dom_widget.find(\"select\").first().data(\"options\")[\"edit-url\"];\n      if (typeof edit_url != \"undefined\" && edit_url.length) {\n        dom_widget.on(\n          \"dblclick\",\n          \".ra-multiselect option:not(:disabled)\",\n          function (e) {\n            widget._bindModalOpening(e, edit_url.replace(\"__ID__\", this.value));\n          }\n        );\n      }\n\n      dom_widget\n        .find(\".create\")\n        .unbind()\n        .bind(\"click\", function (e) {\n          widget._bindModalOpening(e, $(this).data(\"link\"));\n        });\n\n      dom_widget\n        .find(\".update\")\n        .unbind()\n        .bind(\"click\", function (e) {\n          var value = dom_widget.find(\"select\").val();\n          if (value) {\n            widget._bindModalOpening(\n              e,\n              $(this).data(\"link\").replace(\"__ID__\", value)\n            );\n          } else {\n            e.preventDefault();\n          }\n        });\n    },\n\n    _bindModalOpening: function (e, url) {\n      e.preventDefault();\n      var widget = this;\n      if ($(\"#modal\").length) return false;\n\n      var dialog = this._getModal();\n\n      setTimeout(function () {\n        // fix race condition with modal insertion in the dom (Chrome => Team/add a new fan => #modal not found when it should have). Somehow .on('show') is too early, tried it too.\n        $.ajax({\n          url: url,\n          beforeSend: function (xhr) {\n            xhr.setRequestHeader(\"Accept\", \"text/javascript\");\n          },\n          success: function (data, status, xhr) {\n            dialog.find(\".modal-body\").html(data);\n            widget._bindFormEvents();\n          },\n          error: function (xhr, status, error) {\n            dialog.find(\".modal-body\").html(xhr.responseText);\n          },\n          dataType: \"text\",\n        });\n      }, 200);\n    },\n\n    _bindFormEvents: function () {\n      var widget = this,\n        dialog = this._getModal(),\n        form = dialog.find(\"form\"),\n        saveButtonText = dialog.find(\":submit[name=_save]\").html(),\n        cancelButtonText = dialog.find(\":submit[name=_continue]\").html();\n      dialog.find(\".form-actions\").remove();\n\n      form.attr(\"data-remote\", true).attr(\"data-type\", \"json\");\n      dialog.find(\".modal-header-title\").text(form.data(\"title\"));\n      dialog\n        .find(\".cancel-action\")\n        .unbind()\n        .click(function () {\n          dialog.each(function (index, element) {\n            bootstrap.Modal.getInstance(element).hide();\n          });\n          return false;\n        })\n        .html(cancelButtonText);\n\n      dialog\n        .find(\".save-action\")\n        .unbind()\n        .click(function () {\n          Rails.fire(form[0], \"submit\");\n          return false;\n        })\n        .html(saveButtonText);\n\n      const event = new CustomEvent(\"rails_admin.dom_ready\", { detail: form });\n      document.dispatchEvent(event);\n\n      form.bind(\"ajax:complete\", function (event) {\n        var data = event.detail[0];\n        if (data.status == 200) {\n          var json = $.parseJSON(data.responseText);\n          var option =\n            '<option value=\"' +\n            json.id +\n            '\" selected>' +\n            json.label +\n            \"</option>\";\n          var select = widget.element.find(\"select\").filter(\":hidden\");\n\n          if (widget.element.find(\".filtering-select\").length) {\n            // select input\n            var input = widget.element\n              .find(\".filtering-select\")\n              .children(\".ra-filtering-select-input\");\n            input.val(json.label);\n            if (!select.find(\"option[value=\" + json.id + \"]\").length) {\n              // not a replace\n              select.html(option).val(json.id);\n              widget.element.find(\".update\").removeClass(\"disabled\");\n            }\n          } else {\n            // multi-select input\n            var multiselect = widget.element.find(\".ra-multiselect\");\n            if (multiselect.find(\"option[value=\" + json.id + \"]\").length) {\n              // replace\n              select.find(\"option[value=\" + json.id + \"]\").text(json.label);\n              multiselect\n                .find(\"option[value= \" + json.id + \"]\")\n                .text(json.label);\n            } else {\n              // add\n              select.append(option);\n              multiselect\n                .find(\"select.ra-multiselect-selection\")\n                .append(option);\n            }\n          }\n          widget._trigger(\"success\");\n          dialog.each(function (index, element) {\n            bootstrap.Modal.getInstance(element).hide();\n          });\n        } else {\n          dialog.find(\".modal-body\").html(data.responseText);\n          widget._bindFormEvents();\n        }\n      });\n    },\n\n    _getModal: function () {\n      var widget = this;\n      if (!widget.dialog) {\n        widget.dialog = $(\n          '<div id=\"modal\" class=\"modal fade\">\\\n            <div class=\"modal-dialog modal-lg\">\\\n            <div class=\"modal-content\">\\\n            <div class=\"modal-header\">\\\n              <h3 class=\"modal-header-title\">...</h3>\\\n              <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\"></button>\\\n            </div>\\\n            <div class=\"modal-body\">\\\n              ...\\\n            </div>\\\n            <div class=\"modal-footer\">\\\n              <a href=\"#\" class=\"btn cancel-action\">...</a>\\\n              <a href=\"#\" class=\"btn btn-primary save-action\">...</a>\\\n            </div>\\\n            </div>\\\n            </div>\\\n          </div>'\n        ).on(\"hidden.bs.modal\", function () {\n          widget.dialog.remove(); // We don't want to reuse closed modals\n          widget.dialog = null;\n        });\n        new bootstrap.Modal(widget.dialog[0], {\n          keyboard: true,\n          backdrop: true,\n          focus: false,\n          show: true,\n        }).show();\n      }\n      return this.dialog;\n    },\n  });\n})(jQuery);\n"
  },
  {
    "path": "src/rails_admin/sidescroll.js",
    "content": "\"use strict\";\n\n{\n  document.addEventListener(\"rails_admin.dom_ready\", () => {\n    const scroller = document.getElementById(\"sidescroll\");\n    if (!scroller) {\n      return;\n    }\n\n    scroller.querySelectorAll(\"tr\").forEach((tr, index) => {\n      let firstPosition;\n      tr.querySelectorAll(\"th.sticky, td.sticky\").forEach((td, idx) => {\n        if (idx === 0) {\n          firstPosition = td.offsetLeft;\n        }\n        td.style.left = `${td.offsetLeft - firstPosition}px`;\n      });\n    });\n  });\n}\n"
  },
  {
    "path": "src/rails_admin/styles/base/README.txt",
    "content": "For RailsAdmin developers:\nWe should use sass variables & mixins as much as possible so that themers/users can override them cleanly\n"
  },
  {
    "path": "src/rails_admin/styles/base/mixins.scss",
    "content": "/* RailsAdmin SASS mixins */\n"
  },
  {
    "path": "src/rails_admin/styles/base/theming.scss",
    "content": "/*\n  RailsAdmin main CSS\n  Keep it clean, people\n*/\n\n$avatar-size: 30px;\n\nbody.rails_admin {\n  .thumbnail {\n    display: inline-block;\n  }\n\n  /* Top navigation */\n  padding-top: $nav-link-height + $navbar-padding-y * 2;\n\n  .navbar {\n    .edit_user_root_link {\n      position: relative;\n\n      img {\n        position: absolute;\n        top: calc((40px - $avatar-size) / 2);\n\n        & + span {\n          margin-left: ($avatar-size + 5px);\n        }\n      }\n    }\n  }\n\n  /* Sidebar navigation */\n  .sidebar.btn-toggle-nav {\n    padding: 0;\n\n    .btn-toggle {\n      margin-top: calc(#{$grid-gutter-width} / 2);\n      padding: 3px calc(#{$grid-gutter-width} / 2);\n      font-weight: bold;\n      color: $gray-600;\n    }\n\n    .btn-toggle[aria-expanded=\"true\"] {\n      color: $gray-700;\n    }\n\n    .btn-toggle-nav > li > a {\n      padding: calc(#{$navbar-padding-y} / 2) calc(#{$grid-gutter-width} / 2);\n\n      &.active {\n        background-color: map-get($theme-colors, primary);\n        color: color-contrast(map-get($theme-colors, primary));\n      }\n\n      &:hover {\n        background-color: map-get($theme-colors, primary);\n        color: color-contrast(map-get($theme-colors, primary));\n      }\n\n      &.nav-level-1 {\n        padding-left: $grid-gutter-width;\n      }\n\n      &.nav-level-2 {\n        padding-left: ($grid-gutter-width * 1.5);\n      }\n\n      &.nav-level-3 {\n        padding-left: ($grid-gutter-width * 2);\n      }\n    }\n  }\n\n  /* Main form */\n  form.main {\n    /* hide hidden fields controls by default */\n    .control-group .hidden_type {\n      display: none;\n    }\n\n    /* nested forms */\n    .tab-content {\n      .tab-pane {\n        border-left: 5px solid map-get($theme-colors, primary);\n        position: relative;\n\n        fieldset {\n          padding-top: 30px;\n        }\n\n        .form-group {\n          margin-right: 0;\n          margin-left: -5px; /* Balance border-left */\n        }\n\n        & > .remove_nested_fields,\n        & > .remove_nested_one_fields {\n          display: block;\n          opacity: 0;\n          position: absolute;\n          top: 0px;\n          left: 5px;\n          transition: opacity 0.15s ease;\n        }\n        &:hover > .remove_nested_fields,\n        &:hover > .remove_nested_one_fields,\n        & > .remove_nested_one_fields.active {\n          opacity: 1;\n        }\n      }\n    }\n\n    /* double nesting, guys. Easy. */\n    .tab-content .tab-content .tab-pane {\n      border-color: lighten(map-get($theme-colors, info), 20%);\n      margin-left: 10px;\n\n      .form-group {\n        margin-left: -15px; /* Balance border-left */\n      }\n    }\n\n    /* triple nesting!*/\n    .tab-content .tab-content .tab-content .tab-pane {\n      border-color: lighten(map-get($theme-colors, warning), 30%);\n      margin-left: 20px;\n\n      .form-group {\n        margin-left: -25px; /* Balance border-left */\n      }\n    }\n\n    /* totally awesome! nesting on 4 levels! */\n    .tab-content .tab-content .tab-content .tab-content .tab-pane {\n      border-color: lighten(map-get($theme-colors, success), 40%);\n      margin-left: 30px;\n\n      .form-group {\n        margin-left: -35px; /* Balance border-left */\n      }\n    }\n  }\n\n  /* Action tabs */\n  .nav.nav-tabs {\n    li.nav-item.icon + li.nav-item.dropdown {\n      margin-left: auto;\n    }\n    /* To silence Popper's warning: 'CSS \"margin\" styles cannot be used...' */\n    .dropdown-menu {\n      margin: 0;\n    }\n  }\n\n  /* Table cells behaviour */\n  .table {\n    height: 100%;\n\n    // Cells\n    > thead,\n    > tbody,\n    > tfoot {\n      > tr {\n        > th {\n          border-bottom: 0px;\n        }\n      }\n    }\n    .thumbnail {\n      float: left;\n      & + * {\n        clear: left;\n      }\n    }\n    /* backport of Bootstrap 1.4 table headers */\n    .header {\n      cursor: pointer;\n      padding-right: 18px;\n      &:after {\n        content: \"\";\n        float: right;\n        margin-top: 7px;\n        margin-left: 8px;\n        margin-right: -16px;\n        border-width: 0 4px 4px;\n        border-style: solid;\n        border-color: $dark transparent;\n        visibility: hidden;\n      }\n    }\n    .headerSortUp,\n    .headerSortDown {\n      background-color: rgba($info, 0.25);\n      text-shadow: 0 1px 1px rgba($light, 0.75);\n    }\n    .header:hover {\n      &:after {\n        visibility: visible;\n      }\n    }\n    .headerSortDown,\n    .headerSortDown:hover {\n      &:after {\n        visibility: visible;\n        opacity: 60;\n      }\n    }\n    .headerSortUp {\n      &:after {\n        border-bottom: none;\n        border-left: 4px solid transparent;\n        border-right: 4px solid transparent;\n        border-top: 4px solid $dark;\n        visibility: visible;\n        @include box-shadow(none);\n        opacity: 60;\n      }\n    }\n\n    th {\n      white-space: nowrap;\n    }\n\n    /* text-overflow when cell content > 150px */\n    td {\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      max-width: 150px;\n    }\n\n    th,\n    td {\n      padding: 5px 10px;\n    }\n\n    .sticky {\n      position: sticky;\n    }\n\n    th.last,\n    td.last {\n      position: sticky;\n      right: 0px;\n    }\n\n    /* icons */\n    td.links {\n      max-width: none;\n      .list-inline {\n        margin-bottom: 0;\n        li {\n          display: inline-block;\n          padding: 0 3px;\n          .nav-link {\n            padding: 0 0.1em;\n          }\n        }\n      }\n    }\n\n    /* Shrink to content width */\n    .shrink {\n      width: 1px;\n      white-space: nowrap;\n    }\n\n    /* History */\n    th.created_at {\n      width: 160px;\n    }\n    th.username {\n      width: 140px;\n    }\n    th.item {\n      width: 60px;\n    }\n  }\n\n  /* Dashboard */\n  .table {\n    .progress {\n      height: 100%;\n    }\n  }\n\n  /* Index */\n  #filters_box {\n    .form-control {\n      display: inline-block;\n      vertical-align: middle;\n      width: auto;\n    }\n  }\n  #sidescroll {\n    margin-bottom: 20px;\n    overflow-x: auto;\n    .table {\n      margin-bottom: 0;\n    }\n\n    // Remove transparency on sticky cells.\n    $table-bg-default: if(\n      $table-bg == transparent,\n      if($body-bg == transparent, #fff, $body-bg),\n      $table-bg\n    ) !default;\n    .table-striped > tbody > tr > td,\n    .table-striped > thead > tr > th {\n      background-color: $table-bg-default;\n    }\n    $table-bg-header-sort: #e2eff6 !default;\n    .table .sticky,\n    .table .last {\n      &.headerSortUp,\n      &.headerSortDown {\n        background-color: $table-bg-header-sort;\n      }\n    }\n  }\n  .pagination .page-item {\n    white-space: nowrap;\n  }\n}\n\n@media screen and (min-width: map-get($grid-breakpoints, \"sm\")) {\n  body.rails_admin {\n    .sidebar.btn-toggle-nav {\n      position: fixed;\n      top: $nav-link-height + $navbar-padding-y * 2;\n      bottom: 0;\n      overflow-y: auto;\n    }\n  }\n}\n\n@media screen and (max-width: map-get($grid-breakpoints, \"sm\")) {\n  body.rails_admin {\n    .container {\n      padding: 0;\n    }\n  }\n}\n"
  },
  {
    "path": "src/rails_admin/styles/base/variables.scss",
    "content": "/* RailsAdmin SASS variables */\n\n$font-size-base: 0.85rem !default;\n"
  },
  {
    "path": "src/rails_admin/styles/base.scss",
    "content": "@charset \"UTF-8\";\n\n/***  Variables & mixins ***/\n\n@import \"base/variables\";\n@import \"base/mixins\";\n\n/***  Libraries  ***/\n\n@import \"flatpickr/dist/flatpickr\";\n\n/*** Font-awesome ***/\n\n$fa-font-path: \"~@fortawesome/fontawesome-free/webfonts\" !default;\n@import \"@fortawesome/fontawesome-free/scss/solid\";\n@import \"@fortawesome/fontawesome-free/scss/fontawesome\";\n\n/***  Bootstrap  ***/\n\n@import \"bootstrap/scss/bootstrap\";\n\n/***  RailsAdmin  ***/\n\n@import \"base/theming\";\n@import \"filtering-select\";\n@import \"filtering-multiselect\";\n@import \"widgets\";\n"
  },
  {
    "path": "src/rails_admin/styles/filtering-multiselect.scss",
    "content": ".ra-multiselect {\n  .ra-multiselect-header {\n    margin-bottom: 5px;\n    clear: right;\n    .help {\n      float: left;\n      font-size: 10px;\n    }\n    .ui-icon {\n      position: relative;\n      top: 10px;\n      left: 3px;\n    }\n  }\n\n  .ra-multiselect-search {\n    width: 180px;\n  }\n\n  .ra-multiselect-column {\n    float: left;\n    .wrapper {\n      overflow-x: auto;\n      select {\n        height: auto;\n        min-height: 120px;\n        margin-bottom: 5px;\n        min-width: 200px;\n      }\n    }\n  }\n\n  .ra-multiselect-center {\n    width: 30px;\n    padding-top: 15px;\n    text-align: center;\n    .fas {\n      margin: 5px auto;\n    }\n  }\n\n  span.fas,\n  a.fas {\n    color: $gray-400;\n    font-size: 16px;\n    margin-right: 4px;\n    text-decoration: none;\n\n    &:hover {\n      color: $gray-700;\n    }\n  }\n}\n"
  },
  {
    "path": "src/rails_admin/styles/filtering-select.scss",
    "content": ".ui-widget {\n  font-family: Arial, sans-serif;\n  font-size: 1.1em;\n}\n.ui-widget .ui-widget {\n  font-size: 1em;\n}\n.ui-widget input,\n.ui-widget select,\n.ui-widget textarea,\n.ui-widget button {\n  font-family: Arial, sans-serif;\n  font-size: 1em;\n}\n.ui-widget-content {\n  border: 1px solid #b6b6b6;\n  background: #ffffff;\n  color: #4f4f4f;\n}\n.ui-widget-content a {\n  color: #4f4f4f;\n}\n\n.ui-menu {\n  list-style: none;\n  padding: 2px;\n  margin: 0;\n  display: block;\n  float: left;\n}\n.ui-menu .ui-menu {\n  margin-top: -3px;\n}\n.ui-menu .ui-menu-item {\n  margin: 0;\n  padding: 0;\n  zoom: 1;\n  float: left;\n  clear: left;\n  width: 100%;\n}\n.ui-menu .ui-menu-item a {\n  text-decoration: none;\n  display: block;\n  padding: 0.2em 0.4em;\n  line-height: 1.5;\n  zoom: 1;\n}\n.ui-menu .ui-menu-item a.ui-state-hover,\n.ui-menu .ui-menu-item a.ui-state-active {\n  font-weight: normal;\n  margin: -1px;\n  background: #5f83b9;\n  color: #ffffff;\n  text-shadow: 0px 1px 1px #234386;\n  border-color: #466086;\n  border-radius: 0;\n}\n\n.ui-autocomplete {\n  position: absolute;\n  cursor: default;\n  z-index: 1056 !important;\n  border-radius: 0;\n  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);\n}\n\n.ui-helper-hidden-accessible {\n  display: none;\n}\n"
  },
  {
    "path": "src/rails_admin/styles/widgets.scss",
    "content": "iframe.wysihtml5-sandbox {\n  height: 250px !important;\n  width: 99.7% !important;\n}\n\niframe.wysihtml5-sandbox,\n.wysihtml5-editor {\n  border: 1px solid #ccc !important;\n}\n\n.controls img.preview {\n  max-height: 200px;\n  max-width: 300px;\n}\n\n.controls.ui-sortable .sortables {\n  cursor: move;\n}\n\n.form-group.hidden_type {\n  display: none;\n}\n\n.links .list-inline .disabled span {\n  color: $gray-600;\n}\n"
  },
  {
    "path": "src/rails_admin/ui.js",
    "content": "import jQuery from \"jquery\";\nimport \"jquery-ui/ui/effect.js\";\nimport I18n from \"./i18n\";\n\n(function ($) {\n  $(document).on(\"click\", \"#list input.toggle\", function () {\n    $(\"#list [name='bulk_ids[]']\").prop(\"checked\", $(this).is(\":checked\"));\n  });\n\n  $(document)\n    .on(\"turbo:click\", function () {\n      $(\"#loading\").show();\n    })\n    .on(\"turbo:before-render\", function (event) {\n      document\n        .querySelectorAll('.sidebar .btn-toggle[aria-expanded=\"false\"]')\n        .forEach((element) => {\n          const newButton = event.detail.newBody.querySelector(\n            `.sidebar [data-bs-target=\"${element.dataset.bsTarget}\"]`\n          );\n          const newMenu = event.detail.newBody.querySelector(\n            element.dataset.bsTarget\n          );\n          if (newButton) {\n            newButton.parentNode.replaceChild(\n              element.cloneNode(true),\n              newButton\n            );\n          }\n          if (newMenu) {\n            newMenu.classList.remove(\"show\");\n          }\n        });\n\n      $(\"#loading\").hide();\n    });\n\n  $(document).on(\"click\", \"[data-bs-target]\", function () {\n    if (!$(this).hasClass(\"disabled\")) {\n      if ($(this).has(\"i.fa-chevron-down\").length) {\n        $(this)\n          .removeClass(\"active\")\n          .children(\"i\")\n          .toggleClass(\"fa-chevron-down fa-chevron-right\");\n        $($(this).data(\"target\")).filter(\":visible\").hide(\"slow\");\n      } else {\n        if ($(this).has(\"i.fa-chevron-right\").length) {\n          $(this)\n            .addClass(\"active\")\n            .children(\"i\")\n            .toggleClass(\"fa-chevron-down fa-chevron-right\");\n          $($(this).data(\"target\")).filter(\":hidden\").show(\"slow\");\n        }\n      }\n    }\n  });\n\n  $(document).on(\"click\", \"form legend\", function () {\n    if ($(this).has(\"i.fa-chevron-down\").length) {\n      $(this).siblings(\".control-group:visible\").hide(\"slow\");\n      $(this).children(\"i\").toggleClass(\"fa-chevron-down fa-chevron-right\");\n    } else {\n      if ($(this).has(\"i.fa-chevron-right\").length) {\n        $(this).siblings(\".control-group:hidden\").show(\"slow\");\n        $(this).children(\"i\").toggleClass(\"fa-chevron-down fa-chevron-right\");\n      }\n    }\n  });\n\n  $(document).on(\n    \"click\",\n    \"form .tab-content .tab-pane a.remove_nested_one_fields\",\n    function () {\n      $(this)\n        .children('input[type=\"hidden\"]')\n        .val($(this).hasClass(\"active\"))\n        .siblings(\"i\")\n        .toggleClass(\"fa-check fa-trash\");\n    }\n  );\n\n  function triggerDomReady() {\n    I18n.init($(\"html\").attr(\"lang\"), $(\"#admin-js\").data(\"i18nOptions\"));\n\n    const event = new CustomEvent(\"rails_admin.dom_ready\");\n    document.dispatchEvent(event);\n  }\n  $(document).ready(triggerDomReady);\n  document.addEventListener(\"turbo:render\", triggerDomReady);\n\n  document.addEventListener(\"rails_admin.dom_ready\", function (event) {\n    $(\".nav.nav-pills li.active\").removeClass(\"active\");\n    $(\n      '.nav.nav-pills li[data-model=\"' + $(\".page-header\").data(\"model\") + '\"]'\n    ).addClass(\"active\");\n    $(\".animate-width-to\").each(function () {\n      var length, width;\n      length = $(this).data(\"animate-length\");\n      width = $(this).data(\"animate-width-to\");\n      $(this).animate(\n        {\n          width: width,\n        },\n        length,\n        \"easeOutQuad\"\n      );\n    });\n    $(\"form.main legend\")\n      .has(\"i.fa-chevron-right\")\n      .each(function () {\n        $(this).siblings(\".control-group\").hide();\n      });\n    $('button[name][type=\"submit\"]').on(\"click\", function () {\n      var form = $(this).closest(\"form\");\n      form.append(\n        $(\"<input />\")\n          .attr(\"type\", \"hidden\")\n          .attr(\"name\", $(this).attr(\"name\"))\n          .attr(\"value\", $(this).attr(\"value\"))\n      );\n      if ($(this).is(\"[formnovalidate]\")) {\n        form.attr(\"novalidate\", true);\n      }\n    });\n    $.each($(\"#filters_box\").data(\"options\"), function () {\n      $.filters.append(this);\n    });\n    // Workaround for https://github.com/heartcombo/devise/issues/5458\n    $(\"a[data-method]\").on(\"click\", function (event) {\n      window.Turbo.session.drive = false;\n    });\n\n    // Trigger via jQuery for compatibility with existing user codes\n    $(document).trigger(\n      \"rails_admin.dom_ready\",\n      event.detail ? [event.detail] : null\n    );\n  });\n\n  $(document).on(\"click\", \".bulk-link\", function (event) {\n    event.preventDefault();\n    $(\"#bulk_action\").val($(this).data(\"action\"));\n    $(\"#bulk_form\").submit();\n  });\n\n  $(document).on(\"click\", \"#remove_filter\", function (event) {\n    event.preventDefault();\n    $(\"#filters_box\").html(\"\");\n    $(\"hr.filters_box\").hide();\n    $(this).siblings(\"input[type='search']\").val(\"\");\n    $(this).parents(\"form\").submit();\n  });\n\n  $(document).on(\"click\", \"th.header\", function (event) {\n    event.preventDefault();\n    window.Turbo.visit($(this).data(\"href\"));\n  });\n\n  $(document).on(\n    \"click\",\n    \"#fields_to_export label input#check_all\",\n    function () {\n      var elems;\n      elems = $(\"#fields_to_export label input\");\n      if ($(\"#fields_to_export label input#check_all\").is(\":checked\")) {\n        $(elems).prop(\"checked\", true);\n      } else {\n        $(elems).prop(\"checked\", false);\n      }\n    }\n  );\n\n  $(document).on(\"click\", \"#fields_to_export .reverse-selection\", function () {\n    $(this).closest(\".control-group\").find(\".controls\").find(\"input\").click();\n  });\n})(jQuery);\n"
  },
  {
    "path": "src/rails_admin/vendor/jquery_nested_form.js",
    "content": "import jQuery from 'jquery';\n\n(function($) {\n  window.NestedFormEvents = function() {\n    this.addFields = $.proxy(this.addFields, this);\n    this.removeFields = $.proxy(this.removeFields, this);\n  };\n\n  NestedFormEvents.prototype = {\n    addFields: function(e) {\n      // Setup\n      var link      = e.currentTarget;\n      var assoc     = $(link).data('association');                // Name of child\n      var blueprint = $('#' + $(link).data('blueprint-id'));\n      var content   = blueprint.data('blueprint');                // Fields template\n\n      // Make the context correct by replacing <parents> with the generated ID\n      // of each of the parent objects\n      var context = ($(link).closest('.fields').closestChild('input, textarea, select').eq(0).attr('name') || '').replace(/\\[[a-z_]+\\]$/, '');\n\n      // If the parent has no inputs we need to strip off the last pair\n      var current = content.match(new RegExp('\\\\[([a-z_]+)\\\\]\\\\[new_' + assoc + '\\\\]'));\n      if (current) {\n        context = context.replace(new RegExp('\\\\[' + current[1] + '\\\\]\\\\[(new_)?\\\\d+\\\\]$'), '');\n      }\n\n      // context will be something like this for a brand new form:\n      // project[tasks_attributes][1255929127459][assignments_attributes][1255929128105]\n      // or for an edit form:\n      // project[tasks_attributes][0][assignments_attributes][1]\n      if (context) {\n        var parentNames = context.match(/[a-z_]+_attributes(?=\\]\\[(new_)?\\d+\\])/g) || [];\n        var parentIds   = context.match(/[0-9]+/g) || [];\n\n        for(var i = 0; i < parentNames.length; i++) {\n          if(parentIds[i]) {\n            content = content.replace(\n              new RegExp('(_' + parentNames[i] + ')_.+?_', 'g'),\n              '$1_' + parentIds[i] + '_');\n\n            content = content.replace(\n              new RegExp('(\\\\[' + parentNames[i] + '\\\\])\\\\[.+?\\\\]', 'g'),\n              '$1[' + parentIds[i] + ']');\n          }\n        }\n      }\n\n      // Make a unique ID for the new child\n      var regexp  = new RegExp('new_' + assoc, 'g');\n      var new_id  = this.newId();\n      content     = $.trim(content.replace(regexp, new_id));\n\n      var field = this.insertFields(content, assoc, link);\n      // bubble up event upto document (through form)\n      field\n        .trigger({ type: 'nested:fieldAdded', field: field })\n        .trigger({ type: 'nested:fieldAdded:' + assoc, field: field });\n      return false;\n    },\n    newId: function() {\n      return new Date().getTime();\n    },\n    insertFields: function(content, assoc, link) {\n      var target = $(link).data('target');\n      if (target) {\n        return $(content).appendTo($(target));\n      } else {\n        return $(content).insertBefore(link);\n      }\n    },\n    removeFields: function(e) {\n      var $link = $(e.currentTarget),\n          assoc = $link.data('association'); // Name of child to be removed\n      \n      var hiddenField = $link.prev('input[type=hidden]');\n      hiddenField.val('1');\n      \n      var field = $link.closest('.fields');\n      field.hide();\n      \n      field\n        .trigger({ type: 'nested:fieldRemoved', field: field })\n        .trigger({ type: 'nested:fieldRemoved:' + assoc, field: field });\n      return false;\n    }\n  };\n\n  window.nestedFormEvents = new NestedFormEvents();\n  $(document)\n    .delegate('form a.add_nested_fields',    'click', nestedFormEvents.addFields)\n    .delegate('form a.remove_nested_fields', 'click', nestedFormEvents.removeFields);\n})(jQuery);\n\n// http://plugins.jquery.com/project/closestChild\n/*\n * Copyright 2011, Tobias Lindig\n *\n * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)\n * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.\n *\n */\n(function($) {\n        $.fn.closestChild = function(selector) {\n                // breadth first search for the first matched node\n                if (selector && selector != '') {\n                        var queue = [];\n                        queue.push(this);\n                        while(queue.length > 0) {\n                                var node = queue.shift();\n                                var children = node.children();\n                                for(var i = 0; i < children.length; ++i) {\n                                        var child = $(children[i]);\n                                        if (child.is(selector)) {\n                                                return child; //well, we found one\n                                        }\n                                        queue.push(child);\n                                }\n                        }\n                }\n                return $();//nothing found\n        };\n})(jQuery);\n"
  },
  {
    "path": "src/rails_admin/widgets.js",
    "content": "import jQuery from \"jquery\";\nimport \"jquery-ui/ui/widgets/sortable.js\";\nimport * as bootstrap from \"bootstrap\";\nimport flatpickr from \"flatpickr\";\nimport I18n from \"./i18n\";\n\n(function ($) {\n  document.addEventListener(\"rails_admin.dom_ready\", function (event) {\n    var $editors,\n      array,\n      config_options,\n      goBootstrapWysihtml5s,\n      goCkeditors,\n      goCodeMirrors,\n      goFroalaWysiwygs,\n      goSimpleMDEs,\n      options;\n    var content = event.detail || $(\"form\");\n    if (content.length) {\n      content.find(\"[data-datetimepicker]\").each(function () {\n        flatpickr(\n          this,\n          $.extend(\n            {\n              dateFormat: \"Y-m-dTH:i:S\",\n              altInput: true,\n              locale: I18n.locale,\n            },\n            $(this).data(\"options\")\n          )\n        );\n      });\n      content.find(\"[data-enumeration]\").each(function () {\n        if ($(this).is(\"[multiple]\")) {\n          $(this).filteringMultiselect($(this).data(\"options\"));\n        } else {\n          $(this).filteringSelect($(this).data(\"options\"));\n        }\n      });\n      content.find(\"[data-fileupload]\").each(function () {\n        var parent;\n        parent = $(this).closest(\".controls\");\n        parent.find(\".btn-remove-image\").on(\"click\", function () {\n          $(this).siblings(\"[type=checkbox]\").click();\n          parent.find(\".toggle\").toggle(\"slow\");\n          $(this).toggleClass(\"btn-danger btn-info\");\n          return false;\n        });\n      });\n      content.find(\"[data-fileupload]\").change(function () {\n        var ext, image_container, input, reader;\n        input = this;\n        image_container = $(\"#\" + input.id)\n          .parent()\n          .children(\".preview\");\n        if (!image_container.length) {\n          image_container = $(\"#\" + input.id)\n            .parent()\n            .prepend($(\"<img />\").addClass(\"preview\").addClass(\"img-thumbnail\"))\n            .find(\"img.preview\");\n          image_container.parent().find(\"img:not(.preview)\").hide();\n        }\n        ext = $(\"#\" + input.id)\n          .val()\n          .split(\".\")\n          .pop()\n          .toLowerCase();\n        if (\n          input.files &&\n          input.files[0] &&\n          $.inArray(ext, [\"gif\", \"png\", \"jpg\", \"jpeg\", \"bmp\"]) !== -1\n        ) {\n          reader = new FileReader();\n          reader.onload = function (e) {\n            image_container.attr(\"src\", e.target.result);\n          };\n          reader.readAsDataURL(input.files[0]);\n          image_container.show();\n        } else {\n          image_container.hide();\n        }\n      });\n      content.find(\"[data-multiple-fileupload]\").each(function () {\n        $(this)\n          .closest(\".controls\")\n          .find(\".btn-remove-image\")\n          .on(\"click\", function () {\n            $(this).siblings(\"[type=checkbox]\").click();\n            $(this).parent(\".toggle\").toggle(\"slow\");\n            $(this).toggleClass(\"btn-danger btn-info\");\n            return false;\n          })\n          .end()\n          .sortable({\n            items: \".sortables\",\n          });\n      });\n      content.find(\"[data-multiple-fileupload]\").change(function () {\n        var ext, file, i, image_container, input, len, ref, results;\n        input = this;\n        $(\"#\" + input.id)\n          .parent()\n          .children(\".preview\")\n          .remove();\n        ref = input.files;\n        results = [];\n        for (i = 0, len = ref.length; i < len; i++) {\n          file = ref[i];\n          ext = file.name.split(\".\").pop().toLowerCase();\n          if ($.inArray(ext, [\"gif\", \"png\", \"jpg\", \"jpeg\", \"bmp\"]) === -1) {\n            continue;\n          }\n          image_container = $(\"<img />\")\n            .addClass(\"preview\")\n            .addClass(\"img-thumbnail\");\n          results.push(\n            (function (image_container) {\n              var reader;\n              reader = new FileReader();\n              reader.onload = function (e) {\n                image_container.attr(\"src\", e.target.result);\n              };\n              reader.readAsDataURL(file);\n              return $(\"#\" + input.id)\n                .parent()\n                .append(\n                  $(\"<div></div>\").addClass(\"preview\").append(image_container)\n                );\n            })(image_container)\n          );\n        }\n        return results;\n      });\n      content.find(\"[data-filteringmultiselect]\").each(function () {\n        $(this).filteringMultiselect($(this).data(\"options\"));\n        if ($(this).parents(\"#modal\").length) {\n          $(this).parent().siblings(\".modal-actions\").remove();\n        } else {\n          $(this).parents(\".control-group\").first().remoteForm();\n        }\n      });\n      content.find(\"[data-filteringselect]\").each(function () {\n        $(this).filteringSelect($(this).data(\"options\"));\n        if ($(this).parents(\"#modal\").length) {\n          $(this).parent().siblings(\".modal-actions\").remove();\n        } else {\n          $(this).parents(\".control-group\").first().remoteForm();\n        }\n      });\n      content.find(\"[data-nestedmany]\").each(function () {\n        var field, nav, tab_content, toggler;\n        field = $(this).parents(\".control-group\").first();\n        nav = field.find(\"> .controls > .nav\");\n        tab_content = field.find(\"> .tab-content\");\n        toggler = field.find(\"> .controls > .btn-group > .toggler\");\n        tab_content\n          .children(\".fields:not(.tab-pane)\")\n          .addClass(\"tab-pane\")\n          .each(function () {\n            $(this).attr(\n              \"id\",\n              \"unique-id-\" +\n                new Date().getTime() +\n                Math.floor(Math.random() * 100000)\n            );\n            nav.append(\n              $(\"<li></li>\")\n                .append(\n                  $(\"<a></a>\")\n                    .addClass(\"nav-link\")\n                    .attr(\"data-bs-toggle\", \"tab\")\n                    .attr(\"href\", \"#\" + this.id)\n                    .text(\n                      $(this).children(\".object-infos\").data(\"object-label\")\n                    )\n                )\n                .addClass(\"nav-item\")\n            );\n          });\n        if (nav.find(\"> li.active\").length === 0) {\n          nav\n            .find(\"> li > a[data-bs-toggle='tab']:first\")\n            .each(function (index, element) {\n              bootstrap.Tab.getOrCreateInstance(element).show();\n            });\n        }\n        if (nav.children().length === 0) {\n          toggler\n            .addClass(\"disabled\")\n            .removeClass(\"active\")\n            .children(\"i\")\n            .addClass(\"fa-chevron-right\");\n        } else {\n          if (toggler.hasClass(\"active\")) {\n            $(toggler.data(\"bs-target\")).addClass(\"show\");\n            toggler.children(\"i\").addClass(\"fa-chevron-down\");\n          } else {\n            toggler.children(\"i\").addClass(\"fa-chevron-right\");\n          }\n        }\n      });\n      content.find(\"[data-nestedone]\").each(function () {\n        var field, first_tab, nav, tab_content, toggler;\n        field = $(this).parents(\".control-group\").first();\n        nav = field.find(\"> .controls > .nav\");\n        tab_content = field.find(\"> .tab-content\");\n        toggler = field.find(\"> .controls > .btn-group > .toggler\");\n        tab_content\n          .children(\".fields:not(.tab-pane)\")\n          .addClass(\"tab-pane active\")\n          .each(function () {\n            field\n              .find(\"> .controls .add_nested_fields\")\n              .removeClass(\"add_nested_fields\")\n              .text($(this).children(\".object-infos\").data(\"object-label\"));\n            nav.append(\n              $(\"<li></li>\").append(\n                $(\"<a></a>\")\n                  .attr(\"data-bs-toggle\", \"tab\")\n                  .attr(\"href\", \"#\" + $(this).id)\n                  .text($(this).children(\".object-infos\").data(\"object-label\"))\n              )\n            );\n          });\n        first_tab = nav.find(\"> li > a[data-bs-toggle='tab']:first\");\n        first_tab.each(function (index, element) {\n          bootstrap.Tab.getOrCreateInstance(element).show();\n        });\n        field\n          .find(\"> .controls > [data-target]:first\")\n          .html('<i class=\"fas\"></i> ' + first_tab.html());\n        nav.hide();\n        if (nav.children().length === 0) {\n          toggler\n            .addClass(\"disabled\")\n            .removeClass(\"active\")\n            .children(\"i\")\n            .addClass(\"fa-chevron-right\");\n        } else {\n          if (toggler.hasClass(\"active\")) {\n            $(toggler.data(\"bs-target\")).addClass(\"show\");\n            toggler.children(\"i\").addClass(\"fa-chevron-down\");\n          } else {\n            toggler.children(\"i\").addClass(\"fa-chevron-right\");\n          }\n        }\n      });\n      content.find(\"[data-polymorphic]\").each(function () {\n        var field, object_select, type_select, urls;\n        type_select = $(this);\n        field = type_select.parents(\".control-group\").first();\n        object_select = field.find(\"select\").last();\n        urls = type_select.data(\"urls\");\n        type_select.on(\"change\", function (e) {\n          var selected_data, selected_type;\n          selected_type = type_select.val().toLowerCase().replace(/::/g, \"-\");\n          selected_data = $(\"#\" + selected_type + \"-js-options\").data(\n            \"options\"\n          );\n          object_select.data(\"options\", selected_data);\n          object_select.filteringSelect(\"destroy\");\n          object_select.filteringSelect(selected_data);\n        });\n      });\n      goSimpleMDEs = function () {\n        return content\n          .find(\"[data-richtext=simplemde]\")\n          .not(\".simplemded\")\n          .each(function (index, domEle) {\n            var instance_config, options;\n            options = $(this).data(\"options\");\n            instance_config = options.instance_config;\n            new window.SimpleMDE(\n              $.extend(\n                true,\n                {\n                  element: document.getElementById(this.id),\n                  autosave: {\n                    uniqueId: this.id,\n                  },\n                },\n                instance_config\n              )\n            );\n            $(this).addClass(\"simplemded\");\n          });\n      };\n      $editors = content.find(\"[data-richtext=simplemde]\").not(\".simplemded\");\n      if ($editors.length) {\n        if (!window.SimpleMDE) {\n          options = $editors.first().data(\"options\");\n          $(\"head\").append(\n            '<link href=\"' +\n              options[\"css_location\"] +\n              '\" rel=\"stylesheet\" media=\"all\" type=\"text/css\">'\n          );\n          $.getScript(\n            options[\"js_location\"],\n            function (script, textStatus, jqXHR) {\n              return goSimpleMDEs();\n            }\n          );\n        } else {\n          goSimpleMDEs();\n        }\n      }\n      goCkeditors = function () {\n        return content\n          .find(\"[data-richtext=ckeditor]\")\n          .not(\".ckeditored\")\n          .each(function (index, domEle) {\n            var instance;\n            try {\n              if ((instance = window.CKEDITOR.instances[this.id])) {\n                instance.destroy(true);\n              }\n            } catch (error1) {}\n            window.CKEDITOR.replace(this, $(this).data(\"options\").options);\n            $(this).addClass(\"ckeditored\");\n          });\n      };\n      $editors = content.find(\"[data-richtext=ckeditor]\").not(\".ckeditored\");\n      if ($editors.length) {\n        if (!window.CKEDITOR) {\n          options = $editors.first().data(\"options\");\n          window.CKEDITOR_BASEPATH = options[\"base_location\"];\n          $.getScript(\n            options[\"jspath\"],\n            (function (_this) {\n              return function (script, textStatus, jqXHR) {\n                return goCkeditors();\n              };\n            })(this)\n          );\n        } else {\n          goCkeditors();\n        }\n      }\n      goCodeMirrors = (function (_this) {\n        return function (array) {\n          return array.each(function (index, domEle) {\n            var textarea;\n            options = $(this).data(\"options\");\n            textarea = this;\n            $.getScript(\n              options[\"locations\"][\"mode\"],\n              function (script, textStatus, jqXHR) {\n                options = $(domEle).data(\"options\");\n                $(\"head\").append(\n                  '<link href=\"' +\n                    options[\"locations\"][\"theme\"] +\n                    '\" rel=\"stylesheet\" media=\"all\" type=\"text/css\">'\n                );\n                CodeMirror.fromTextArea(textarea, options[\"options\"]);\n                return $(textarea).addClass(\"codemirrored\");\n              }\n            );\n          });\n        };\n      })(this);\n      array = content.find(\"[data-richtext=codemirror]\").not(\".codemirrored\");\n      if (array.length) {\n        this.array = array;\n        if (!window.CodeMirror) {\n          options = $(array[0]).data(\"options\");\n          $(\"head\").append(\n            '<link href=\"' +\n              options[\"csspath\"] +\n              '\" rel=\"stylesheet\" media=\"all\" type=\"text/css\">'\n          );\n          $.getScript(\n            options[\"jspath\"],\n            (function (_this) {\n              return function (script, textStatus, jqXHR) {\n                return goCodeMirrors(_this.array);\n              };\n            })(this)\n          );\n        } else {\n          goCodeMirrors(this.array);\n        }\n      }\n      goBootstrapWysihtml5s = (function (_this) {\n        return function (array, config_options) {\n          return array.each(function () {\n            $(this).addClass(\"bootstrap-wysihtml5ed\");\n            $(this).closest(\".controls\").addClass(\"well\");\n            $(this).wysihtml5(config_options);\n          });\n        };\n      })(this);\n      array = content\n        .find(\"[data-richtext=bootstrap-wysihtml5]\")\n        .not(\".bootstrap-wysihtml5ed\");\n      if (array.length) {\n        this.array = array;\n        options = $(array[0]).data(\"options\");\n        config_options = $.parseJSON(options[\"config_options\"]);\n        if (!window.wysihtml5) {\n          $(\"head\").append(\n            '<link href=\"' +\n              options[\"csspath\"] +\n              '\" rel=\"stylesheet\" media=\"all\" type=\"text/css\">'\n          );\n          $.getScript(\n            options[\"jspath\"],\n            (function (_this) {\n              return function (script, textStatus, jqXHR) {\n                return goBootstrapWysihtml5s(_this.array, config_options);\n              };\n            })(this)\n          );\n        } else {\n          goBootstrapWysihtml5s(this.array, config_options);\n        }\n      }\n      goFroalaWysiwygs = (function (_this) {\n        return function (array) {\n          return array.each(function () {\n            var uploadEnabled;\n            options = $(this).data(\"options\");\n            config_options = $.parseJSON(options[\"config_options\"]);\n            if (config_options) {\n              if (!config_options[\"inlineMode\"]) {\n                config_options[\"inlineMode\"] = false;\n              }\n            } else {\n              config_options = {\n                inlineMode: false,\n              };\n            }\n            uploadEnabled = config_options[\"imageUploadURL\"]\n              ? (config_options[\"imageUploadParams\"] = {\n                  authenticity_token: $(\"meta[name=csrf-token]\").attr(\n                    \"content\"\n                  ),\n                })\n              : void 0;\n            $(this).addClass(\"froala-wysiwyged\");\n            $(this).froalaEditor(config_options);\n            if (uploadEnabled) {\n              $(this)\n                .on(\"froalaEditor.image.error\", function (e, editor, error) {\n                  alert(\"error uploading image: \" + error.message);\n                })\n                .on(\"froalaEditor.image.removed\", function (e, editor, $img) {\n                  editor.options.imageDeleteParams = {\n                    src: $img.attr(\"src\"),\n                    authenticity_token: $(\"meta[name=csrf-token]\").attr(\n                      \"content\"\n                    ),\n                  };\n                  editor.deleteImage($img);\n                })\n                .on(\n                  \"editable.imageDeleteSuccess\",\n                  function (e, editor, data) {}\n                )\n                .on(\"editable.imageDeleteError\", function (e, editor, error) {\n                  alert(\"error deleting image: \" + error.message);\n                });\n            }\n          });\n        };\n      })(this);\n      array = content\n        .find(\"[data-richtext=froala-wysiwyg]\")\n        .not(\".froala-wysiwyged\");\n      if (array.length) {\n        options = $(array[0]).data(\"options\");\n        if (!$.isFunction($.fn.editable)) {\n          $(\"head\").append(\n            '<link href=\"' +\n              options[\"csspath\"] +\n              '\" rel=\"stylesheet\" media=\"all\" type=\"text/css\">'\n          );\n          $.getScript(\n            options[\"jspath\"],\n            (function (_this) {\n              return function (script, textStatus, jqXHR) {\n                return goFroalaWysiwygs(array);\n              };\n            })(this)\n          );\n        } else {\n          goFroalaWysiwygs(array);\n        }\n      }\n      return content.find(\"trix-editor\").each(function () {\n        if (!window.Trix) {\n          options = $(this).data(\"options\");\n          if (options.warn_dynamic_load) {\n            console.warn(\n              \"ActionText assets should be loaded statically. Follow instructions in https://github.com/railsadminteam/rails_admin/wiki/ActionText\"\n            );\n          }\n          $(\"head\").append(\n            '<link href=\"' +\n              options[\"csspath\"] +\n              '\" rel=\"stylesheet\" media=\"all\" type=\"text/css\">'\n          );\n          return $.getScript(options[\"jspath\"]);\n        }\n      });\n    }\n  });\n})(jQuery);\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/bootstrap.js",
    "content": "/*!\n  * Bootstrap v5.1.3 (https://getbootstrap.com/)\n  * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n  */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core')) :\n  typeof define === 'function' && define.amd ? define(['@popperjs/core'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory(global.Popper));\n})(this, (function (Popper) { 'use strict';\n\n  function _interopNamespace(e) {\n    if (e && e.__esModule) return e;\n    const n = Object.create(null);\n    if (e) {\n      for (const k in e) {\n        if (k !== 'default') {\n          const d = Object.getOwnPropertyDescriptor(e, k);\n          Object.defineProperty(n, k, d.get ? d : {\n            enumerable: true,\n            get: () => e[k]\n          });\n        }\n      }\n    }\n    n.default = e;\n    return Object.freeze(n);\n  }\n\n  const Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): util/index.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const MAX_UID = 1000000;\n  const MILLISECONDS_MULTIPLIER = 1000;\n  const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)\n\n  const toType = obj => {\n    if (obj === null || obj === undefined) {\n      return `${obj}`;\n    }\n\n    return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase();\n  };\n  /**\n   * --------------------------------------------------------------------------\n   * Public Util Api\n   * --------------------------------------------------------------------------\n   */\n\n\n  const getUID = prefix => {\n    do {\n      prefix += Math.floor(Math.random() * MAX_UID);\n    } while (document.getElementById(prefix));\n\n    return prefix;\n  };\n\n  const getSelector = element => {\n    let selector = element.getAttribute('data-bs-target');\n\n    if (!selector || selector === '#') {\n      let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,\n      // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n      // `document.querySelector` will rightfully complain it is invalid.\n      // See https://github.com/twbs/bootstrap/issues/32273\n\n      if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {\n        return null;\n      } // Just in case some CMS puts out a full URL with the anchor appended\n\n\n      if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {\n        hrefAttr = `#${hrefAttr.split('#')[1]}`;\n      }\n\n      selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;\n    }\n\n    return selector;\n  };\n\n  const getSelectorFromElement = element => {\n    const selector = getSelector(element);\n\n    if (selector) {\n      return document.querySelector(selector) ? selector : null;\n    }\n\n    return null;\n  };\n\n  const getElementFromSelector = element => {\n    const selector = getSelector(element);\n    return selector ? document.querySelector(selector) : null;\n  };\n\n  const getTransitionDurationFromElement = element => {\n    if (!element) {\n      return 0;\n    } // Get transition-duration of the element\n\n\n    let {\n      transitionDuration,\n      transitionDelay\n    } = window.getComputedStyle(element);\n    const floatTransitionDuration = Number.parseFloat(transitionDuration);\n    const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found\n\n    if (!floatTransitionDuration && !floatTransitionDelay) {\n      return 0;\n    } // If multiple durations are defined, take the first\n\n\n    transitionDuration = transitionDuration.split(',')[0];\n    transitionDelay = transitionDelay.split(',')[0];\n    return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n  };\n\n  const triggerTransitionEnd = element => {\n    element.dispatchEvent(new Event(TRANSITION_END));\n  };\n\n  const isElement = obj => {\n    if (!obj || typeof obj !== 'object') {\n      return false;\n    }\n\n    if (typeof obj.jquery !== 'undefined') {\n      obj = obj[0];\n    }\n\n    return typeof obj.nodeType !== 'undefined';\n  };\n\n  const getElement = obj => {\n    if (isElement(obj)) {\n      // it's a jQuery object or a node element\n      return obj.jquery ? obj[0] : obj;\n    }\n\n    if (typeof obj === 'string' && obj.length > 0) {\n      return document.querySelector(obj);\n    }\n\n    return null;\n  };\n\n  const typeCheckConfig = (componentName, config, configTypes) => {\n    Object.keys(configTypes).forEach(property => {\n      const expectedTypes = configTypes[property];\n      const value = config[property];\n      const valueType = value && isElement(value) ? 'element' : toType(value);\n\n      if (!new RegExp(expectedTypes).test(valueType)) {\n        throw new TypeError(`${componentName.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n      }\n    });\n  };\n\n  const isVisible = element => {\n    if (!isElement(element) || element.getClientRects().length === 0) {\n      return false;\n    }\n\n    return getComputedStyle(element).getPropertyValue('visibility') === 'visible';\n  };\n\n  const isDisabled = element => {\n    if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n      return true;\n    }\n\n    if (element.classList.contains('disabled')) {\n      return true;\n    }\n\n    if (typeof element.disabled !== 'undefined') {\n      return element.disabled;\n    }\n\n    return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n  };\n\n  const findShadowRoot = element => {\n    if (!document.documentElement.attachShadow) {\n      return null;\n    } // Can find the shadow root otherwise it'll return the document\n\n\n    if (typeof element.getRootNode === 'function') {\n      const root = element.getRootNode();\n      return root instanceof ShadowRoot ? root : null;\n    }\n\n    if (element instanceof ShadowRoot) {\n      return element;\n    } // when we don't find a shadow root\n\n\n    if (!element.parentNode) {\n      return null;\n    }\n\n    return findShadowRoot(element.parentNode);\n  };\n\n  const noop = () => {};\n  /**\n   * Trick to restart an element's animation\n   *\n   * @param {HTMLElement} element\n   * @return void\n   *\n   * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n   */\n\n\n  const reflow = element => {\n    // eslint-disable-next-line no-unused-expressions\n    element.offsetHeight;\n  };\n\n  const getjQuery = () => {\n    const {\n      jQuery\n    } = window;\n\n    if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n      return jQuery;\n    }\n\n    return null;\n  };\n\n  const DOMContentLoadedCallbacks = [];\n\n  const onDOMContentLoaded = callback => {\n    if (document.readyState === 'loading') {\n      // add listener on the first call when the document is in loading state\n      if (!DOMContentLoadedCallbacks.length) {\n        document.addEventListener('DOMContentLoaded', () => {\n          DOMContentLoadedCallbacks.forEach(callback => callback());\n        });\n      }\n\n      DOMContentLoadedCallbacks.push(callback);\n    } else {\n      callback();\n    }\n  };\n\n  const isRTL = () => document.documentElement.dir === 'rtl';\n\n  const defineJQueryPlugin = plugin => {\n    onDOMContentLoaded(() => {\n      const $ = getjQuery();\n      /* istanbul ignore if */\n\n      if ($) {\n        const name = plugin.NAME;\n        const JQUERY_NO_CONFLICT = $.fn[name];\n        $.fn[name] = plugin.jQueryInterface;\n        $.fn[name].Constructor = plugin;\n\n        $.fn[name].noConflict = () => {\n          $.fn[name] = JQUERY_NO_CONFLICT;\n          return plugin.jQueryInterface;\n        };\n      }\n    });\n  };\n\n  const execute = callback => {\n    if (typeof callback === 'function') {\n      callback();\n    }\n  };\n\n  const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n    if (!waitForTransition) {\n      execute(callback);\n      return;\n    }\n\n    const durationPadding = 5;\n    const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n    let called = false;\n\n    const handler = ({\n      target\n    }) => {\n      if (target !== transitionElement) {\n        return;\n      }\n\n      called = true;\n      transitionElement.removeEventListener(TRANSITION_END, handler);\n      execute(callback);\n    };\n\n    transitionElement.addEventListener(TRANSITION_END, handler);\n    setTimeout(() => {\n      if (!called) {\n        triggerTransitionEnd(transitionElement);\n      }\n    }, emulatedDuration);\n  };\n  /**\n   * Return the previous/next element of a list.\n   *\n   * @param {array} list    The list of elements\n   * @param activeElement   The active element\n   * @param shouldGetNext   Choose to get next or previous element\n   * @param isCycleAllowed\n   * @return {Element|elem} The proper element\n   */\n\n\n  const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n    let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed\n\n    if (index === -1) {\n      return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];\n    }\n\n    const listLength = list.length;\n    index += shouldGetNext ? 1 : -1;\n\n    if (isCycleAllowed) {\n      index = (index + listLength) % listLength;\n    }\n\n    return list[Math.max(0, Math.min(index, listLength - 1))];\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): dom/event-handler.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\n  const stripNameRegex = /\\..*/;\n  const stripUidRegex = /::\\d+$/;\n  const eventRegistry = {}; // Events storage\n\n  let uidEvent = 1;\n  const customEvents = {\n    mouseenter: 'mouseover',\n    mouseleave: 'mouseout'\n  };\n  const customEventsRegex = /^(mouseenter|mouseleave)/i;\n  const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);\n  /**\n   * ------------------------------------------------------------------------\n   * Private methods\n   * ------------------------------------------------------------------------\n   */\n\n  function getUidEvent(element, uid) {\n    return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n  }\n\n  function getEvent(element) {\n    const uid = getUidEvent(element);\n    element.uidEvent = uid;\n    eventRegistry[uid] = eventRegistry[uid] || {};\n    return eventRegistry[uid];\n  }\n\n  function bootstrapHandler(element, fn) {\n    return function handler(event) {\n      event.delegateTarget = element;\n\n      if (handler.oneOff) {\n        EventHandler.off(element, event.type, fn);\n      }\n\n      return fn.apply(element, [event]);\n    };\n  }\n\n  function bootstrapDelegationHandler(element, selector, fn) {\n    return function handler(event) {\n      const domElements = element.querySelectorAll(selector);\n\n      for (let {\n        target\n      } = event; target && target !== this; target = target.parentNode) {\n        for (let i = domElements.length; i--;) {\n          if (domElements[i] === target) {\n            event.delegateTarget = target;\n\n            if (handler.oneOff) {\n              EventHandler.off(element, event.type, selector, fn);\n            }\n\n            return fn.apply(target, [event]);\n          }\n        }\n      } // To please ESLint\n\n\n      return null;\n    };\n  }\n\n  function findHandler(events, handler, delegationSelector = null) {\n    const uidEventList = Object.keys(events);\n\n    for (let i = 0, len = uidEventList.length; i < len; i++) {\n      const event = events[uidEventList[i]];\n\n      if (event.originalHandler === handler && event.delegationSelector === delegationSelector) {\n        return event;\n      }\n    }\n\n    return null;\n  }\n\n  function normalizeParams(originalTypeEvent, handler, delegationFn) {\n    const delegation = typeof handler === 'string';\n    const originalHandler = delegation ? delegationFn : handler;\n    let typeEvent = getTypeEvent(originalTypeEvent);\n    const isNative = nativeEvents.has(typeEvent);\n\n    if (!isNative) {\n      typeEvent = originalTypeEvent;\n    }\n\n    return [delegation, originalHandler, typeEvent];\n  }\n\n  function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {\n    if (typeof originalTypeEvent !== 'string' || !element) {\n      return;\n    }\n\n    if (!handler) {\n      handler = delegationFn;\n      delegationFn = null;\n    } // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n    // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n\n\n    if (customEventsRegex.test(originalTypeEvent)) {\n      const wrapFn = fn => {\n        return function (event) {\n          if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n            return fn.call(this, event);\n          }\n        };\n      };\n\n      if (delegationFn) {\n        delegationFn = wrapFn(delegationFn);\n      } else {\n        handler = wrapFn(handler);\n      }\n    }\n\n    const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);\n    const events = getEvent(element);\n    const handlers = events[typeEvent] || (events[typeEvent] = {});\n    const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null);\n\n    if (previousFn) {\n      previousFn.oneOff = previousFn.oneOff && oneOff;\n      return;\n    }\n\n    const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, ''));\n    const fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler);\n    fn.delegationSelector = delegation ? handler : null;\n    fn.originalHandler = originalHandler;\n    fn.oneOff = oneOff;\n    fn.uidEvent = uid;\n    handlers[uid] = fn;\n    element.addEventListener(typeEvent, fn, delegation);\n  }\n\n  function removeHandler(element, events, typeEvent, handler, delegationSelector) {\n    const fn = findHandler(events[typeEvent], handler, delegationSelector);\n\n    if (!fn) {\n      return;\n    }\n\n    element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n    delete events[typeEvent][fn.uidEvent];\n  }\n\n  function removeNamespacedHandlers(element, events, typeEvent, namespace) {\n    const storeElementEvent = events[typeEvent] || {};\n    Object.keys(storeElementEvent).forEach(handlerKey => {\n      if (handlerKey.includes(namespace)) {\n        const event = storeElementEvent[handlerKey];\n        removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);\n      }\n    });\n  }\n\n  function getTypeEvent(event) {\n    // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n    event = event.replace(stripNameRegex, '');\n    return customEvents[event] || event;\n  }\n\n  const EventHandler = {\n    on(element, event, handler, delegationFn) {\n      addHandler(element, event, handler, delegationFn, false);\n    },\n\n    one(element, event, handler, delegationFn) {\n      addHandler(element, event, handler, delegationFn, true);\n    },\n\n    off(element, originalTypeEvent, handler, delegationFn) {\n      if (typeof originalTypeEvent !== 'string' || !element) {\n        return;\n      }\n\n      const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);\n      const inNamespace = typeEvent !== originalTypeEvent;\n      const events = getEvent(element);\n      const isNamespace = originalTypeEvent.startsWith('.');\n\n      if (typeof originalHandler !== 'undefined') {\n        // Simplest case: handler is passed, remove that listener ONLY.\n        if (!events || !events[typeEvent]) {\n          return;\n        }\n\n        removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null);\n        return;\n      }\n\n      if (isNamespace) {\n        Object.keys(events).forEach(elementEvent => {\n          removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n        });\n      }\n\n      const storeElementEvent = events[typeEvent] || {};\n      Object.keys(storeElementEvent).forEach(keyHandlers => {\n        const handlerKey = keyHandlers.replace(stripUidRegex, '');\n\n        if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n          const event = storeElementEvent[keyHandlers];\n          removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);\n        }\n      });\n    },\n\n    trigger(element, event, args) {\n      if (typeof event !== 'string' || !element) {\n        return null;\n      }\n\n      const $ = getjQuery();\n      const typeEvent = getTypeEvent(event);\n      const inNamespace = event !== typeEvent;\n      const isNative = nativeEvents.has(typeEvent);\n      let jQueryEvent;\n      let bubbles = true;\n      let nativeDispatch = true;\n      let defaultPrevented = false;\n      let evt = null;\n\n      if (inNamespace && $) {\n        jQueryEvent = $.Event(event, args);\n        $(element).trigger(jQueryEvent);\n        bubbles = !jQueryEvent.isPropagationStopped();\n        nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n        defaultPrevented = jQueryEvent.isDefaultPrevented();\n      }\n\n      if (isNative) {\n        evt = document.createEvent('HTMLEvents');\n        evt.initEvent(typeEvent, bubbles, true);\n      } else {\n        evt = new CustomEvent(event, {\n          bubbles,\n          cancelable: true\n        });\n      } // merge custom information in our event\n\n\n      if (typeof args !== 'undefined') {\n        Object.keys(args).forEach(key => {\n          Object.defineProperty(evt, key, {\n            get() {\n              return args[key];\n            }\n\n          });\n        });\n      }\n\n      if (defaultPrevented) {\n        evt.preventDefault();\n      }\n\n      if (nativeDispatch) {\n        element.dispatchEvent(evt);\n      }\n\n      if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') {\n        jQueryEvent.preventDefault();\n      }\n\n      return evt;\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): dom/data.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n  const elementMap = new Map();\n  const Data = {\n    set(element, key, instance) {\n      if (!elementMap.has(element)) {\n        elementMap.set(element, new Map());\n      }\n\n      const instanceMap = elementMap.get(element); // make it clear we only want one instance per element\n      // can be removed later when multiple key/instances are fine to be used\n\n      if (!instanceMap.has(key) && instanceMap.size !== 0) {\n        // eslint-disable-next-line no-console\n        console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n        return;\n      }\n\n      instanceMap.set(key, instance);\n    },\n\n    get(element, key) {\n      if (elementMap.has(element)) {\n        return elementMap.get(element).get(key) || null;\n      }\n\n      return null;\n    },\n\n    remove(element, key) {\n      if (!elementMap.has(element)) {\n        return;\n      }\n\n      const instanceMap = elementMap.get(element);\n      instanceMap.delete(key); // free up element references if there are no instances left for an element\n\n      if (instanceMap.size === 0) {\n        elementMap.delete(element);\n      }\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): base-component.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const VERSION = '5.1.3';\n\n  class BaseComponent {\n    constructor(element) {\n      element = getElement(element);\n\n      if (!element) {\n        return;\n      }\n\n      this._element = element;\n      Data.set(this._element, this.constructor.DATA_KEY, this);\n    }\n\n    dispose() {\n      Data.remove(this._element, this.constructor.DATA_KEY);\n      EventHandler.off(this._element, this.constructor.EVENT_KEY);\n      Object.getOwnPropertyNames(this).forEach(propertyName => {\n        this[propertyName] = null;\n      });\n    }\n\n    _queueCallback(callback, element, isAnimated = true) {\n      executeAfterTransition(callback, element, isAnimated);\n    }\n    /** Static */\n\n\n    static getInstance(element) {\n      return Data.get(getElement(element), this.DATA_KEY);\n    }\n\n    static getOrCreateInstance(element, config = {}) {\n      return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n    }\n\n    static get VERSION() {\n      return VERSION;\n    }\n\n    static get NAME() {\n      throw new Error('You have to implement the static method \"NAME\", for each component!');\n    }\n\n    static get DATA_KEY() {\n      return `bs.${this.NAME}`;\n    }\n\n    static get EVENT_KEY() {\n      return `.${this.DATA_KEY}`;\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): util/component-functions.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n\n  const enableDismissTrigger = (component, method = 'hide') => {\n    const clickEvent = `click.dismiss${component.EVENT_KEY}`;\n    const name = component.NAME;\n    EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n      if (['A', 'AREA'].includes(this.tagName)) {\n        event.preventDefault();\n      }\n\n      if (isDisabled(this)) {\n        return;\n      }\n\n      const target = getElementFromSelector(this) || this.closest(`.${name}`);\n      const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n\n      instance[method]();\n    });\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): alert.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$d = 'alert';\n  const DATA_KEY$c = 'bs.alert';\n  const EVENT_KEY$c = `.${DATA_KEY$c}`;\n  const EVENT_CLOSE = `close${EVENT_KEY$c}`;\n  const EVENT_CLOSED = `closed${EVENT_KEY$c}`;\n  const CLASS_NAME_FADE$5 = 'fade';\n  const CLASS_NAME_SHOW$8 = 'show';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Alert extends BaseComponent {\n    // Getters\n    static get NAME() {\n      return NAME$d;\n    } // Public\n\n\n    close() {\n      const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);\n\n      if (closeEvent.defaultPrevented) {\n        return;\n      }\n\n      this._element.classList.remove(CLASS_NAME_SHOW$8);\n\n      const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);\n\n      this._queueCallback(() => this._destroyElement(), this._element, isAnimated);\n    } // Private\n\n\n    _destroyElement() {\n      this._element.remove();\n\n      EventHandler.trigger(this._element, EVENT_CLOSED);\n      this.dispose();\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Alert.getOrCreateInstance(this);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](this);\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  enableDismissTrigger(Alert, 'close');\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Alert to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Alert);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): button.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$c = 'button';\n  const DATA_KEY$b = 'bs.button';\n  const EVENT_KEY$b = `.${DATA_KEY$b}`;\n  const DATA_API_KEY$7 = '.data-api';\n  const CLASS_NAME_ACTIVE$3 = 'active';\n  const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle=\"button\"]';\n  const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$b}${DATA_API_KEY$7}`;\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Button extends BaseComponent {\n    // Getters\n    static get NAME() {\n      return NAME$c;\n    } // Public\n\n\n    toggle() {\n      // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n      this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Button.getOrCreateInstance(this);\n\n        if (config === 'toggle') {\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {\n    event.preventDefault();\n    const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);\n    const data = Button.getOrCreateInstance(button);\n    data.toggle();\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Button to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Button);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): dom/manipulator.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  function normalizeData(val) {\n    if (val === 'true') {\n      return true;\n    }\n\n    if (val === 'false') {\n      return false;\n    }\n\n    if (val === Number(val).toString()) {\n      return Number(val);\n    }\n\n    if (val === '' || val === 'null') {\n      return null;\n    }\n\n    return val;\n  }\n\n  function normalizeDataKey(key) {\n    return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n  }\n\n  const Manipulator = {\n    setDataAttribute(element, key, value) {\n      element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n    },\n\n    removeDataAttribute(element, key) {\n      element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n    },\n\n    getDataAttributes(element) {\n      if (!element) {\n        return {};\n      }\n\n      const attributes = {};\n      Object.keys(element.dataset).filter(key => key.startsWith('bs')).forEach(key => {\n        let pureKey = key.replace(/^bs/, '');\n        pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n        attributes[pureKey] = normalizeData(element.dataset[key]);\n      });\n      return attributes;\n    },\n\n    getDataAttribute(element, key) {\n      return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n    },\n\n    offset(element) {\n      const rect = element.getBoundingClientRect();\n      return {\n        top: rect.top + window.pageYOffset,\n        left: rect.left + window.pageXOffset\n      };\n    },\n\n    position(element) {\n      return {\n        top: element.offsetTop,\n        left: element.offsetLeft\n      };\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): dom/selector-engine.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const NODE_TEXT = 3;\n  const SelectorEngine = {\n    find(selector, element = document.documentElement) {\n      return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n    },\n\n    findOne(selector, element = document.documentElement) {\n      return Element.prototype.querySelector.call(element, selector);\n    },\n\n    children(element, selector) {\n      return [].concat(...element.children).filter(child => child.matches(selector));\n    },\n\n    parents(element, selector) {\n      const parents = [];\n      let ancestor = element.parentNode;\n\n      while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {\n        if (ancestor.matches(selector)) {\n          parents.push(ancestor);\n        }\n\n        ancestor = ancestor.parentNode;\n      }\n\n      return parents;\n    },\n\n    prev(element, selector) {\n      let previous = element.previousElementSibling;\n\n      while (previous) {\n        if (previous.matches(selector)) {\n          return [previous];\n        }\n\n        previous = previous.previousElementSibling;\n      }\n\n      return [];\n    },\n\n    next(element, selector) {\n      let next = element.nextElementSibling;\n\n      while (next) {\n        if (next.matches(selector)) {\n          return [next];\n        }\n\n        next = next.nextElementSibling;\n      }\n\n      return [];\n    },\n\n    focusableChildren(element) {\n      const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(', ');\n      return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): carousel.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$b = 'carousel';\n  const DATA_KEY$a = 'bs.carousel';\n  const EVENT_KEY$a = `.${DATA_KEY$a}`;\n  const DATA_API_KEY$6 = '.data-api';\n  const ARROW_LEFT_KEY = 'ArrowLeft';\n  const ARROW_RIGHT_KEY = 'ArrowRight';\n  const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\n  const SWIPE_THRESHOLD = 40;\n  const Default$a = {\n    interval: 5000,\n    keyboard: true,\n    slide: false,\n    pause: 'hover',\n    wrap: true,\n    touch: true\n  };\n  const DefaultType$a = {\n    interval: '(number|boolean)',\n    keyboard: 'boolean',\n    slide: '(boolean|string)',\n    pause: '(string|boolean)',\n    wrap: 'boolean',\n    touch: 'boolean'\n  };\n  const ORDER_NEXT = 'next';\n  const ORDER_PREV = 'prev';\n  const DIRECTION_LEFT = 'left';\n  const DIRECTION_RIGHT = 'right';\n  const KEY_TO_DIRECTION = {\n    [ARROW_LEFT_KEY]: DIRECTION_RIGHT,\n    [ARROW_RIGHT_KEY]: DIRECTION_LEFT\n  };\n  const EVENT_SLIDE = `slide${EVENT_KEY$a}`;\n  const EVENT_SLID = `slid${EVENT_KEY$a}`;\n  const EVENT_KEYDOWN = `keydown${EVENT_KEY$a}`;\n  const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY$a}`;\n  const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY$a}`;\n  const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$a}`;\n  const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$a}`;\n  const EVENT_TOUCHEND = `touchend${EVENT_KEY$a}`;\n  const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$a}`;\n  const EVENT_POINTERUP = `pointerup${EVENT_KEY$a}`;\n  const EVENT_DRAG_START = `dragstart${EVENT_KEY$a}`;\n  const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$a}${DATA_API_KEY$6}`;\n  const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;\n  const CLASS_NAME_CAROUSEL = 'carousel';\n  const CLASS_NAME_ACTIVE$2 = 'active';\n  const CLASS_NAME_SLIDE = 'slide';\n  const CLASS_NAME_END = 'carousel-item-end';\n  const CLASS_NAME_START = 'carousel-item-start';\n  const CLASS_NAME_NEXT = 'carousel-item-next';\n  const CLASS_NAME_PREV = 'carousel-item-prev';\n  const CLASS_NAME_POINTER_EVENT = 'pointer-event';\n  const SELECTOR_ACTIVE$1 = '.active';\n  const SELECTOR_ACTIVE_ITEM = '.active.carousel-item';\n  const SELECTOR_ITEM = '.carousel-item';\n  const SELECTOR_ITEM_IMG = '.carousel-item img';\n  const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';\n  const SELECTOR_INDICATORS = '.carousel-indicators';\n  const SELECTOR_INDICATOR = '[data-bs-target]';\n  const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';\n  const SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]';\n  const POINTER_TYPE_TOUCH = 'touch';\n  const POINTER_TYPE_PEN = 'pen';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Carousel extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._items = null;\n      this._interval = null;\n      this._activeElement = null;\n      this._isPaused = false;\n      this._isSliding = false;\n      this.touchTimeout = null;\n      this.touchStartX = 0;\n      this.touchDeltaX = 0;\n      this._config = this._getConfig(config);\n      this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);\n      this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n      this._pointerEvent = Boolean(window.PointerEvent);\n\n      this._addEventListeners();\n    } // Getters\n\n\n    static get Default() {\n      return Default$a;\n    }\n\n    static get NAME() {\n      return NAME$b;\n    } // Public\n\n\n    next() {\n      this._slide(ORDER_NEXT);\n    }\n\n    nextWhenVisible() {\n      // Don't call next when the page isn't visible\n      // or the carousel or its parent isn't visible\n      if (!document.hidden && isVisible(this._element)) {\n        this.next();\n      }\n    }\n\n    prev() {\n      this._slide(ORDER_PREV);\n    }\n\n    pause(event) {\n      if (!event) {\n        this._isPaused = true;\n      }\n\n      if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) {\n        triggerTransitionEnd(this._element);\n        this.cycle(true);\n      }\n\n      clearInterval(this._interval);\n      this._interval = null;\n    }\n\n    cycle(event) {\n      if (!event) {\n        this._isPaused = false;\n      }\n\n      if (this._interval) {\n        clearInterval(this._interval);\n        this._interval = null;\n      }\n\n      if (this._config && this._config.interval && !this._isPaused) {\n        this._updateInterval();\n\n        this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);\n      }\n    }\n\n    to(index) {\n      this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n      const activeIndex = this._getItemIndex(this._activeElement);\n\n      if (index > this._items.length - 1 || index < 0) {\n        return;\n      }\n\n      if (this._isSliding) {\n        EventHandler.one(this._element, EVENT_SLID, () => this.to(index));\n        return;\n      }\n\n      if (activeIndex === index) {\n        this.pause();\n        this.cycle();\n        return;\n      }\n\n      const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;\n\n      this._slide(order, this._items[index]);\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$a,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$b, config, DefaultType$a);\n      return config;\n    }\n\n    _handleSwipe() {\n      const absDeltax = Math.abs(this.touchDeltaX);\n\n      if (absDeltax <= SWIPE_THRESHOLD) {\n        return;\n      }\n\n      const direction = absDeltax / this.touchDeltaX;\n      this.touchDeltaX = 0;\n\n      if (!direction) {\n        return;\n      }\n\n      this._slide(direction > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT);\n    }\n\n    _addEventListeners() {\n      if (this._config.keyboard) {\n        EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));\n      }\n\n      if (this._config.pause === 'hover') {\n        EventHandler.on(this._element, EVENT_MOUSEENTER, event => this.pause(event));\n        EventHandler.on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event));\n      }\n\n      if (this._config.touch && this._touchSupported) {\n        this._addTouchEventListeners();\n      }\n    }\n\n    _addTouchEventListeners() {\n      const hasPointerPenTouch = event => {\n        return this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);\n      };\n\n      const start = event => {\n        if (hasPointerPenTouch(event)) {\n          this.touchStartX = event.clientX;\n        } else if (!this._pointerEvent) {\n          this.touchStartX = event.touches[0].clientX;\n        }\n      };\n\n      const move = event => {\n        // ensure swiping with one touch and not pinching\n        this.touchDeltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this.touchStartX;\n      };\n\n      const end = event => {\n        if (hasPointerPenTouch(event)) {\n          this.touchDeltaX = event.clientX - this.touchStartX;\n        }\n\n        this._handleSwipe();\n\n        if (this._config.pause === 'hover') {\n          // If it's a touch-enabled device, mouseenter/leave are fired as\n          // part of the mouse compatibility events on first tap - the carousel\n          // would stop cycling until user tapped out of it;\n          // here, we listen for touchend, explicitly pause the carousel\n          // (as if it's the second time we tap on it, mouseenter compat event\n          // is NOT fired) and after a timeout (to allow for mouse compatibility\n          // events to fire) we explicitly restart cycling\n          this.pause();\n\n          if (this.touchTimeout) {\n            clearTimeout(this.touchTimeout);\n          }\n\n          this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval);\n        }\n      };\n\n      SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach(itemImg => {\n        EventHandler.on(itemImg, EVENT_DRAG_START, event => event.preventDefault());\n      });\n\n      if (this._pointerEvent) {\n        EventHandler.on(this._element, EVENT_POINTERDOWN, event => start(event));\n        EventHandler.on(this._element, EVENT_POINTERUP, event => end(event));\n\n        this._element.classList.add(CLASS_NAME_POINTER_EVENT);\n      } else {\n        EventHandler.on(this._element, EVENT_TOUCHSTART, event => start(event));\n        EventHandler.on(this._element, EVENT_TOUCHMOVE, event => move(event));\n        EventHandler.on(this._element, EVENT_TOUCHEND, event => end(event));\n      }\n    }\n\n    _keydown(event) {\n      if (/input|textarea/i.test(event.target.tagName)) {\n        return;\n      }\n\n      const direction = KEY_TO_DIRECTION[event.key];\n\n      if (direction) {\n        event.preventDefault();\n\n        this._slide(direction);\n      }\n    }\n\n    _getItemIndex(element) {\n      this._items = element && element.parentNode ? SelectorEngine.find(SELECTOR_ITEM, element.parentNode) : [];\n      return this._items.indexOf(element);\n    }\n\n    _getItemByOrder(order, activeElement) {\n      const isNext = order === ORDER_NEXT;\n      return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap);\n    }\n\n    _triggerSlideEvent(relatedTarget, eventDirectionName) {\n      const targetIndex = this._getItemIndex(relatedTarget);\n\n      const fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element));\n\n      return EventHandler.trigger(this._element, EVENT_SLIDE, {\n        relatedTarget,\n        direction: eventDirectionName,\n        from: fromIndex,\n        to: targetIndex\n      });\n    }\n\n    _setActiveIndicatorElement(element) {\n      if (this._indicatorsElement) {\n        const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE$1, this._indicatorsElement);\n        activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);\n        activeIndicator.removeAttribute('aria-current');\n        const indicators = SelectorEngine.find(SELECTOR_INDICATOR, this._indicatorsElement);\n\n        for (let i = 0; i < indicators.length; i++) {\n          if (Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) {\n            indicators[i].classList.add(CLASS_NAME_ACTIVE$2);\n            indicators[i].setAttribute('aria-current', 'true');\n            break;\n          }\n        }\n      }\n    }\n\n    _updateInterval() {\n      const element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n      if (!element) {\n        return;\n      }\n\n      const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);\n\n      if (elementInterval) {\n        this._config.defaultInterval = this._config.defaultInterval || this._config.interval;\n        this._config.interval = elementInterval;\n      } else {\n        this._config.interval = this._config.defaultInterval || this._config.interval;\n      }\n    }\n\n    _slide(directionOrOrder, element) {\n      const order = this._directionToOrder(directionOrOrder);\n\n      const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n      const activeElementIndex = this._getItemIndex(activeElement);\n\n      const nextElement = element || this._getItemByOrder(order, activeElement);\n\n      const nextElementIndex = this._getItemIndex(nextElement);\n\n      const isCycling = Boolean(this._interval);\n      const isNext = order === ORDER_NEXT;\n      const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;\n      const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;\n\n      const eventDirectionName = this._orderToDirection(order);\n\n      if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE$2)) {\n        this._isSliding = false;\n        return;\n      }\n\n      if (this._isSliding) {\n        return;\n      }\n\n      const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);\n\n      if (slideEvent.defaultPrevented) {\n        return;\n      }\n\n      if (!activeElement || !nextElement) {\n        // Some weirdness is happening, so we bail\n        return;\n      }\n\n      this._isSliding = true;\n\n      if (isCycling) {\n        this.pause();\n      }\n\n      this._setActiveIndicatorElement(nextElement);\n\n      this._activeElement = nextElement;\n\n      const triggerSlidEvent = () => {\n        EventHandler.trigger(this._element, EVENT_SLID, {\n          relatedTarget: nextElement,\n          direction: eventDirectionName,\n          from: activeElementIndex,\n          to: nextElementIndex\n        });\n      };\n\n      if (this._element.classList.contains(CLASS_NAME_SLIDE)) {\n        nextElement.classList.add(orderClassName);\n        reflow(nextElement);\n        activeElement.classList.add(directionalClassName);\n        nextElement.classList.add(directionalClassName);\n\n        const completeCallBack = () => {\n          nextElement.classList.remove(directionalClassName, orderClassName);\n          nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n          activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);\n          this._isSliding = false;\n          setTimeout(triggerSlidEvent, 0);\n        };\n\n        this._queueCallback(completeCallBack, activeElement, true);\n      } else {\n        activeElement.classList.remove(CLASS_NAME_ACTIVE$2);\n        nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n        this._isSliding = false;\n        triggerSlidEvent();\n      }\n\n      if (isCycling) {\n        this.cycle();\n      }\n    }\n\n    _directionToOrder(direction) {\n      if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) {\n        return direction;\n      }\n\n      if (isRTL()) {\n        return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;\n      }\n\n      return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;\n    }\n\n    _orderToDirection(order) {\n      if (![ORDER_NEXT, ORDER_PREV].includes(order)) {\n        return order;\n      }\n\n      if (isRTL()) {\n        return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;\n      }\n\n      return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;\n    } // Static\n\n\n    static carouselInterface(element, config) {\n      const data = Carousel.getOrCreateInstance(element, config);\n      let {\n        _config\n      } = data;\n\n      if (typeof config === 'object') {\n        _config = { ..._config,\n          ...config\n        };\n      }\n\n      const action = typeof config === 'string' ? config : _config.slide;\n\n      if (typeof config === 'number') {\n        data.to(config);\n      } else if (typeof action === 'string') {\n        if (typeof data[action] === 'undefined') {\n          throw new TypeError(`No method named \"${action}\"`);\n        }\n\n        data[action]();\n      } else if (_config.interval && _config.ride) {\n        data.pause();\n        data.cycle();\n      }\n    }\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        Carousel.carouselInterface(this, config);\n      });\n    }\n\n    static dataApiClickHandler(event) {\n      const target = getElementFromSelector(this);\n\n      if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n        return;\n      }\n\n      const config = { ...Manipulator.getDataAttributes(target),\n        ...Manipulator.getDataAttributes(this)\n      };\n      const slideIndex = this.getAttribute('data-bs-slide-to');\n\n      if (slideIndex) {\n        config.interval = false;\n      }\n\n      Carousel.carouselInterface(target, config);\n\n      if (slideIndex) {\n        Carousel.getInstance(target).to(slideIndex);\n      }\n\n      event.preventDefault();\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler);\n  EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {\n    const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);\n\n    for (let i = 0, len = carousels.length; i < len; i++) {\n      Carousel.carouselInterface(carousels[i], Carousel.getInstance(carousels[i]));\n    }\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Carousel to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Carousel);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): collapse.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$a = 'collapse';\n  const DATA_KEY$9 = 'bs.collapse';\n  const EVENT_KEY$9 = `.${DATA_KEY$9}`;\n  const DATA_API_KEY$5 = '.data-api';\n  const Default$9 = {\n    toggle: true,\n    parent: null\n  };\n  const DefaultType$9 = {\n    toggle: 'boolean',\n    parent: '(null|element)'\n  };\n  const EVENT_SHOW$5 = `show${EVENT_KEY$9}`;\n  const EVENT_SHOWN$5 = `shown${EVENT_KEY$9}`;\n  const EVENT_HIDE$5 = `hide${EVENT_KEY$9}`;\n  const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$9}`;\n  const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$9}${DATA_API_KEY$5}`;\n  const CLASS_NAME_SHOW$7 = 'show';\n  const CLASS_NAME_COLLAPSE = 'collapse';\n  const CLASS_NAME_COLLAPSING = 'collapsing';\n  const CLASS_NAME_COLLAPSED = 'collapsed';\n  const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;\n  const CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\n  const WIDTH = 'width';\n  const HEIGHT = 'height';\n  const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';\n  const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle=\"collapse\"]';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Collapse extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._isTransitioning = false;\n      this._config = this._getConfig(config);\n      this._triggerArray = [];\n      const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);\n\n      for (let i = 0, len = toggleList.length; i < len; i++) {\n        const elem = toggleList[i];\n        const selector = getSelectorFromElement(elem);\n        const filterElement = SelectorEngine.find(selector).filter(foundElem => foundElem === this._element);\n\n        if (selector !== null && filterElement.length) {\n          this._selector = selector;\n\n          this._triggerArray.push(elem);\n        }\n      }\n\n      this._initializeChildren();\n\n      if (!this._config.parent) {\n        this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n      }\n\n      if (this._config.toggle) {\n        this.toggle();\n      }\n    } // Getters\n\n\n    static get Default() {\n      return Default$9;\n    }\n\n    static get NAME() {\n      return NAME$a;\n    } // Public\n\n\n    toggle() {\n      if (this._isShown()) {\n        this.hide();\n      } else {\n        this.show();\n      }\n    }\n\n    show() {\n      if (this._isTransitioning || this._isShown()) {\n        return;\n      }\n\n      let actives = [];\n      let activesData;\n\n      if (this._config.parent) {\n        const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);\n        actives = SelectorEngine.find(SELECTOR_ACTIVES, this._config.parent).filter(elem => !children.includes(elem)); // remove children if greater depth\n      }\n\n      const container = SelectorEngine.findOne(this._selector);\n\n      if (actives.length) {\n        const tempActiveData = actives.find(elem => container !== elem);\n        activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null;\n\n        if (activesData && activesData._isTransitioning) {\n          return;\n        }\n      }\n\n      const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$5);\n\n      if (startEvent.defaultPrevented) {\n        return;\n      }\n\n      actives.forEach(elemActive => {\n        if (container !== elemActive) {\n          Collapse.getOrCreateInstance(elemActive, {\n            toggle: false\n          }).hide();\n        }\n\n        if (!activesData) {\n          Data.set(elemActive, DATA_KEY$9, null);\n        }\n      });\n\n      const dimension = this._getDimension();\n\n      this._element.classList.remove(CLASS_NAME_COLLAPSE);\n\n      this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n      this._element.style[dimension] = 0;\n\n      this._addAriaAndCollapsedClass(this._triggerArray, true);\n\n      this._isTransitioning = true;\n\n      const complete = () => {\n        this._isTransitioning = false;\n\n        this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n        this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n        this._element.style[dimension] = '';\n        EventHandler.trigger(this._element, EVENT_SHOWN$5);\n      };\n\n      const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n      const scrollSize = `scroll${capitalizedDimension}`;\n\n      this._queueCallback(complete, this._element, true);\n\n      this._element.style[dimension] = `${this._element[scrollSize]}px`;\n    }\n\n    hide() {\n      if (this._isTransitioning || !this._isShown()) {\n        return;\n      }\n\n      const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$5);\n\n      if (startEvent.defaultPrevented) {\n        return;\n      }\n\n      const dimension = this._getDimension();\n\n      this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n      reflow(this._element);\n\n      this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n      this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n      const triggerArrayLength = this._triggerArray.length;\n\n      for (let i = 0; i < triggerArrayLength; i++) {\n        const trigger = this._triggerArray[i];\n        const elem = getElementFromSelector(trigger);\n\n        if (elem && !this._isShown(elem)) {\n          this._addAriaAndCollapsedClass([trigger], false);\n        }\n      }\n\n      this._isTransitioning = true;\n\n      const complete = () => {\n        this._isTransitioning = false;\n\n        this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n        this._element.classList.add(CLASS_NAME_COLLAPSE);\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN$5);\n      };\n\n      this._element.style[dimension] = '';\n\n      this._queueCallback(complete, this._element, true);\n    }\n\n    _isShown(element = this._element) {\n      return element.classList.contains(CLASS_NAME_SHOW$7);\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$9,\n        ...Manipulator.getDataAttributes(this._element),\n        ...config\n      };\n      config.toggle = Boolean(config.toggle); // Coerce string values\n\n      config.parent = getElement(config.parent);\n      typeCheckConfig(NAME$a, config, DefaultType$9);\n      return config;\n    }\n\n    _getDimension() {\n      return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n    }\n\n    _initializeChildren() {\n      if (!this._config.parent) {\n        return;\n      }\n\n      const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);\n      SelectorEngine.find(SELECTOR_DATA_TOGGLE$4, this._config.parent).filter(elem => !children.includes(elem)).forEach(element => {\n        const selected = getElementFromSelector(element);\n\n        if (selected) {\n          this._addAriaAndCollapsedClass([element], this._isShown(selected));\n        }\n      });\n    }\n\n    _addAriaAndCollapsedClass(triggerArray, isOpen) {\n      if (!triggerArray.length) {\n        return;\n      }\n\n      triggerArray.forEach(elem => {\n        if (isOpen) {\n          elem.classList.remove(CLASS_NAME_COLLAPSED);\n        } else {\n          elem.classList.add(CLASS_NAME_COLLAPSED);\n        }\n\n        elem.setAttribute('aria-expanded', isOpen);\n      });\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const _config = {};\n\n        if (typeof config === 'string' && /show|hide/.test(config)) {\n          _config.toggle = false;\n        }\n\n        const data = Collapse.getOrCreateInstance(this, _config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {\n    // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n    if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n      event.preventDefault();\n    }\n\n    const selector = getSelectorFromElement(this);\n    const selectorElements = SelectorEngine.find(selector);\n    selectorElements.forEach(element => {\n      Collapse.getOrCreateInstance(element, {\n        toggle: false\n      }).toggle();\n    });\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Collapse to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Collapse);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): dropdown.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$9 = 'dropdown';\n  const DATA_KEY$8 = 'bs.dropdown';\n  const EVENT_KEY$8 = `.${DATA_KEY$8}`;\n  const DATA_API_KEY$4 = '.data-api';\n  const ESCAPE_KEY$2 = 'Escape';\n  const SPACE_KEY = 'Space';\n  const TAB_KEY$1 = 'Tab';\n  const ARROW_UP_KEY = 'ArrowUp';\n  const ARROW_DOWN_KEY = 'ArrowDown';\n  const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button\n\n  const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY$2}`);\n  const EVENT_HIDE$4 = `hide${EVENT_KEY$8}`;\n  const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$8}`;\n  const EVENT_SHOW$4 = `show${EVENT_KEY$8}`;\n  const EVENT_SHOWN$4 = `shown${EVENT_KEY$8}`;\n  const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$8}${DATA_API_KEY$4}`;\n  const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$8}${DATA_API_KEY$4}`;\n  const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$8}${DATA_API_KEY$4}`;\n  const CLASS_NAME_SHOW$6 = 'show';\n  const CLASS_NAME_DROPUP = 'dropup';\n  const CLASS_NAME_DROPEND = 'dropend';\n  const CLASS_NAME_DROPSTART = 'dropstart';\n  const CLASS_NAME_NAVBAR = 'navbar';\n  const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle=\"dropdown\"]';\n  const SELECTOR_MENU = '.dropdown-menu';\n  const SELECTOR_NAVBAR_NAV = '.navbar-nav';\n  const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';\n  const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';\n  const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';\n  const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';\n  const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';\n  const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';\n  const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';\n  const Default$8 = {\n    offset: [0, 2],\n    boundary: 'clippingParents',\n    reference: 'toggle',\n    display: 'dynamic',\n    popperConfig: null,\n    autoClose: true\n  };\n  const DefaultType$8 = {\n    offset: '(array|string|function)',\n    boundary: '(string|element)',\n    reference: '(string|element|object)',\n    display: 'string',\n    popperConfig: '(null|object|function)',\n    autoClose: '(boolean|string)'\n  };\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Dropdown extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._popper = null;\n      this._config = this._getConfig(config);\n      this._menu = this._getMenuElement();\n      this._inNavbar = this._detectNavbar();\n    } // Getters\n\n\n    static get Default() {\n      return Default$8;\n    }\n\n    static get DefaultType() {\n      return DefaultType$8;\n    }\n\n    static get NAME() {\n      return NAME$9;\n    } // Public\n\n\n    toggle() {\n      return this._isShown() ? this.hide() : this.show();\n    }\n\n    show() {\n      if (isDisabled(this._element) || this._isShown(this._menu)) {\n        return;\n      }\n\n      const relatedTarget = {\n        relatedTarget: this._element\n      };\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, relatedTarget);\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      const parent = Dropdown.getParentFromElement(this._element); // Totally disable Popper for Dropdowns in Navbar\n\n      if (this._inNavbar) {\n        Manipulator.setDataAttribute(this._menu, 'popper', 'none');\n      } else {\n        this._createPopper(parent);\n      } // If this is a touch-enabled device we add extra\n      // empty mouseover listeners to the body's immediate children;\n      // only needed because of broken event delegation on iOS\n      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n\n      if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {\n        [].concat(...document.body.children).forEach(elem => EventHandler.on(elem, 'mouseover', noop));\n      }\n\n      this._element.focus();\n\n      this._element.setAttribute('aria-expanded', true);\n\n      this._menu.classList.add(CLASS_NAME_SHOW$6);\n\n      this._element.classList.add(CLASS_NAME_SHOW$6);\n\n      EventHandler.trigger(this._element, EVENT_SHOWN$4, relatedTarget);\n    }\n\n    hide() {\n      if (isDisabled(this._element) || !this._isShown(this._menu)) {\n        return;\n      }\n\n      const relatedTarget = {\n        relatedTarget: this._element\n      };\n\n      this._completeHide(relatedTarget);\n    }\n\n    dispose() {\n      if (this._popper) {\n        this._popper.destroy();\n      }\n\n      super.dispose();\n    }\n\n    update() {\n      this._inNavbar = this._detectNavbar();\n\n      if (this._popper) {\n        this._popper.update();\n      }\n    } // Private\n\n\n    _completeHide(relatedTarget) {\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4, relatedTarget);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      } // If this is a touch-enabled device we remove the extra\n      // empty mouseover listeners we added for iOS support\n\n\n      if ('ontouchstart' in document.documentElement) {\n        [].concat(...document.body.children).forEach(elem => EventHandler.off(elem, 'mouseover', noop));\n      }\n\n      if (this._popper) {\n        this._popper.destroy();\n      }\n\n      this._menu.classList.remove(CLASS_NAME_SHOW$6);\n\n      this._element.classList.remove(CLASS_NAME_SHOW$6);\n\n      this._element.setAttribute('aria-expanded', 'false');\n\n      Manipulator.removeDataAttribute(this._menu, 'popper');\n      EventHandler.trigger(this._element, EVENT_HIDDEN$4, relatedTarget);\n    }\n\n    _getConfig(config) {\n      config = { ...this.constructor.Default,\n        ...Manipulator.getDataAttributes(this._element),\n        ...config\n      };\n      typeCheckConfig(NAME$9, config, this.constructor.DefaultType);\n\n      if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {\n        // Popper virtual elements require a getBoundingClientRect method\n        throw new TypeError(`${NAME$9.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`);\n      }\n\n      return config;\n    }\n\n    _createPopper(parent) {\n      if (typeof Popper__namespace === 'undefined') {\n        throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)');\n      }\n\n      let referenceElement = this._element;\n\n      if (this._config.reference === 'parent') {\n        referenceElement = parent;\n      } else if (isElement(this._config.reference)) {\n        referenceElement = getElement(this._config.reference);\n      } else if (typeof this._config.reference === 'object') {\n        referenceElement = this._config.reference;\n      }\n\n      const popperConfig = this._getPopperConfig();\n\n      const isDisplayStatic = popperConfig.modifiers.find(modifier => modifier.name === 'applyStyles' && modifier.enabled === false);\n      this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);\n\n      if (isDisplayStatic) {\n        Manipulator.setDataAttribute(this._menu, 'popper', 'static');\n      }\n    }\n\n    _isShown(element = this._element) {\n      return element.classList.contains(CLASS_NAME_SHOW$6);\n    }\n\n    _getMenuElement() {\n      return SelectorEngine.next(this._element, SELECTOR_MENU)[0];\n    }\n\n    _getPlacement() {\n      const parentDropdown = this._element.parentNode;\n\n      if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n        return PLACEMENT_RIGHT;\n      }\n\n      if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n        return PLACEMENT_LEFT;\n      } // We need to trim the value because custom properties can also include spaces\n\n\n      const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';\n\n      if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n        return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;\n      }\n\n      return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;\n    }\n\n    _detectNavbar() {\n      return this._element.closest(`.${CLASS_NAME_NAVBAR}`) !== null;\n    }\n\n    _getOffset() {\n      const {\n        offset\n      } = this._config;\n\n      if (typeof offset === 'string') {\n        return offset.split(',').map(val => Number.parseInt(val, 10));\n      }\n\n      if (typeof offset === 'function') {\n        return popperData => offset(popperData, this._element);\n      }\n\n      return offset;\n    }\n\n    _getPopperConfig() {\n      const defaultBsPopperConfig = {\n        placement: this._getPlacement(),\n        modifiers: [{\n          name: 'preventOverflow',\n          options: {\n            boundary: this._config.boundary\n          }\n        }, {\n          name: 'offset',\n          options: {\n            offset: this._getOffset()\n          }\n        }]\n      }; // Disable Popper if we have a static display\n\n      if (this._config.display === 'static') {\n        defaultBsPopperConfig.modifiers = [{\n          name: 'applyStyles',\n          enabled: false\n        }];\n      }\n\n      return { ...defaultBsPopperConfig,\n        ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n      };\n    }\n\n    _selectMenuItem({\n      key,\n      target\n    }) {\n      const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible);\n\n      if (!items.length) {\n        return;\n      } // if target isn't included in items (e.g. when expanding the dropdown)\n      // allow cycling to get the last item in case key equals ARROW_UP_KEY\n\n\n      getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Dropdown.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      });\n    }\n\n    static clearMenus(event) {\n      if (event && (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1)) {\n        return;\n      }\n\n      const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE$3);\n\n      for (let i = 0, len = toggles.length; i < len; i++) {\n        const context = Dropdown.getInstance(toggles[i]);\n\n        if (!context || context._config.autoClose === false) {\n          continue;\n        }\n\n        if (!context._isShown()) {\n          continue;\n        }\n\n        const relatedTarget = {\n          relatedTarget: context._element\n        };\n\n        if (event) {\n          const composedPath = event.composedPath();\n          const isMenuTarget = composedPath.includes(context._menu);\n\n          if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {\n            continue;\n          } // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n\n\n          if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n            continue;\n          }\n\n          if (event.type === 'click') {\n            relatedTarget.clickEvent = event;\n          }\n        }\n\n        context._completeHide(relatedTarget);\n      }\n    }\n\n    static getParentFromElement(element) {\n      return getElementFromSelector(element) || element.parentNode;\n    }\n\n    static dataApiKeydownHandler(event) {\n      // If not input/textarea:\n      //  - And not a key in REGEXP_KEYDOWN => not a dropdown command\n      // If input/textarea:\n      //  - If space key => not a dropdown command\n      //  - If key is other than escape\n      //    - If key is not up or down => not a dropdown command\n      //    - If trigger inside the menu => not a dropdown command\n      if (/input|textarea/i.test(event.target.tagName) ? event.key === SPACE_KEY || event.key !== ESCAPE_KEY$2 && (event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY || event.target.closest(SELECTOR_MENU)) : !REGEXP_KEYDOWN.test(event.key)) {\n        return;\n      }\n\n      const isActive = this.classList.contains(CLASS_NAME_SHOW$6);\n\n      if (!isActive && event.key === ESCAPE_KEY$2) {\n        return;\n      }\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      if (isDisabled(this)) {\n        return;\n      }\n\n      const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0];\n      const instance = Dropdown.getOrCreateInstance(getToggleButton);\n\n      if (event.key === ESCAPE_KEY$2) {\n        instance.hide();\n        return;\n      }\n\n      if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {\n        if (!isActive) {\n          instance.show();\n        }\n\n        instance._selectMenuItem(event);\n\n        return;\n      }\n\n      if (!isActive || event.key === SPACE_KEY) {\n        Dropdown.clearMenus();\n      }\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);\n  EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);\n  EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);\n  EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);\n  EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {\n    event.preventDefault();\n    Dropdown.getOrCreateInstance(this).toggle();\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Dropdown to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Dropdown);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): util/scrollBar.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';\n  const SELECTOR_STICKY_CONTENT = '.sticky-top';\n\n  class ScrollBarHelper {\n    constructor() {\n      this._element = document.body;\n    }\n\n    getWidth() {\n      // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n      const documentWidth = document.documentElement.clientWidth;\n      return Math.abs(window.innerWidth - documentWidth);\n    }\n\n    hide() {\n      const width = this.getWidth();\n\n      this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width\n\n\n      this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n\n\n      this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);\n\n      this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);\n    }\n\n    _disableOverFlow() {\n      this._saveInitialAttribute(this._element, 'overflow');\n\n      this._element.style.overflow = 'hidden';\n    }\n\n    _setElementAttributes(selector, styleProp, callback) {\n      const scrollbarWidth = this.getWidth();\n\n      const manipulationCallBack = element => {\n        if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n          return;\n        }\n\n        this._saveInitialAttribute(element, styleProp);\n\n        const calculatedValue = window.getComputedStyle(element)[styleProp];\n        element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;\n      };\n\n      this._applyManipulationCallback(selector, manipulationCallBack);\n    }\n\n    reset() {\n      this._resetElementAttributes(this._element, 'overflow');\n\n      this._resetElementAttributes(this._element, 'paddingRight');\n\n      this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');\n\n      this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');\n    }\n\n    _saveInitialAttribute(element, styleProp) {\n      const actualValue = element.style[styleProp];\n\n      if (actualValue) {\n        Manipulator.setDataAttribute(element, styleProp, actualValue);\n      }\n    }\n\n    _resetElementAttributes(selector, styleProp) {\n      const manipulationCallBack = element => {\n        const value = Manipulator.getDataAttribute(element, styleProp);\n\n        if (typeof value === 'undefined') {\n          element.style.removeProperty(styleProp);\n        } else {\n          Manipulator.removeDataAttribute(element, styleProp);\n          element.style[styleProp] = value;\n        }\n      };\n\n      this._applyManipulationCallback(selector, manipulationCallBack);\n    }\n\n    _applyManipulationCallback(selector, callBack) {\n      if (isElement(selector)) {\n        callBack(selector);\n      } else {\n        SelectorEngine.find(selector, this._element).forEach(callBack);\n      }\n    }\n\n    isOverflowing() {\n      return this.getWidth() > 0;\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): util/backdrop.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const Default$7 = {\n    className: 'modal-backdrop',\n    isVisible: true,\n    // if false, we use the backdrop helper without adding any element to the dom\n    isAnimated: false,\n    rootElement: 'body',\n    // give the choice to place backdrop under different elements\n    clickCallback: null\n  };\n  const DefaultType$7 = {\n    className: 'string',\n    isVisible: 'boolean',\n    isAnimated: 'boolean',\n    rootElement: '(element|string)',\n    clickCallback: '(function|null)'\n  };\n  const NAME$8 = 'backdrop';\n  const CLASS_NAME_FADE$4 = 'fade';\n  const CLASS_NAME_SHOW$5 = 'show';\n  const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$8}`;\n\n  class Backdrop {\n    constructor(config) {\n      this._config = this._getConfig(config);\n      this._isAppended = false;\n      this._element = null;\n    }\n\n    show(callback) {\n      if (!this._config.isVisible) {\n        execute(callback);\n        return;\n      }\n\n      this._append();\n\n      if (this._config.isAnimated) {\n        reflow(this._getElement());\n      }\n\n      this._getElement().classList.add(CLASS_NAME_SHOW$5);\n\n      this._emulateAnimation(() => {\n        execute(callback);\n      });\n    }\n\n    hide(callback) {\n      if (!this._config.isVisible) {\n        execute(callback);\n        return;\n      }\n\n      this._getElement().classList.remove(CLASS_NAME_SHOW$5);\n\n      this._emulateAnimation(() => {\n        this.dispose();\n        execute(callback);\n      });\n    } // Private\n\n\n    _getElement() {\n      if (!this._element) {\n        const backdrop = document.createElement('div');\n        backdrop.className = this._config.className;\n\n        if (this._config.isAnimated) {\n          backdrop.classList.add(CLASS_NAME_FADE$4);\n        }\n\n        this._element = backdrop;\n      }\n\n      return this._element;\n    }\n\n    _getConfig(config) {\n      config = { ...Default$7,\n        ...(typeof config === 'object' ? config : {})\n      }; // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n\n      config.rootElement = getElement(config.rootElement);\n      typeCheckConfig(NAME$8, config, DefaultType$7);\n      return config;\n    }\n\n    _append() {\n      if (this._isAppended) {\n        return;\n      }\n\n      this._config.rootElement.append(this._getElement());\n\n      EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {\n        execute(this._config.clickCallback);\n      });\n      this._isAppended = true;\n    }\n\n    dispose() {\n      if (!this._isAppended) {\n        return;\n      }\n\n      EventHandler.off(this._element, EVENT_MOUSEDOWN);\n\n      this._element.remove();\n\n      this._isAppended = false;\n    }\n\n    _emulateAnimation(callback) {\n      executeAfterTransition(callback, this._getElement(), this._config.isAnimated);\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): util/focustrap.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const Default$6 = {\n    trapElement: null,\n    // The element to trap focus inside of\n    autofocus: true\n  };\n  const DefaultType$6 = {\n    trapElement: 'element',\n    autofocus: 'boolean'\n  };\n  const NAME$7 = 'focustrap';\n  const DATA_KEY$7 = 'bs.focustrap';\n  const EVENT_KEY$7 = `.${DATA_KEY$7}`;\n  const EVENT_FOCUSIN$1 = `focusin${EVENT_KEY$7}`;\n  const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$7}`;\n  const TAB_KEY = 'Tab';\n  const TAB_NAV_FORWARD = 'forward';\n  const TAB_NAV_BACKWARD = 'backward';\n\n  class FocusTrap {\n    constructor(config) {\n      this._config = this._getConfig(config);\n      this._isActive = false;\n      this._lastTabNavDirection = null;\n    }\n\n    activate() {\n      const {\n        trapElement,\n        autofocus\n      } = this._config;\n\n      if (this._isActive) {\n        return;\n      }\n\n      if (autofocus) {\n        trapElement.focus();\n      }\n\n      EventHandler.off(document, EVENT_KEY$7); // guard against infinite focus loop\n\n      EventHandler.on(document, EVENT_FOCUSIN$1, event => this._handleFocusin(event));\n      EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));\n      this._isActive = true;\n    }\n\n    deactivate() {\n      if (!this._isActive) {\n        return;\n      }\n\n      this._isActive = false;\n      EventHandler.off(document, EVENT_KEY$7);\n    } // Private\n\n\n    _handleFocusin(event) {\n      const {\n        target\n      } = event;\n      const {\n        trapElement\n      } = this._config;\n\n      if (target === document || target === trapElement || trapElement.contains(target)) {\n        return;\n      }\n\n      const elements = SelectorEngine.focusableChildren(trapElement);\n\n      if (elements.length === 0) {\n        trapElement.focus();\n      } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n        elements[elements.length - 1].focus();\n      } else {\n        elements[0].focus();\n      }\n    }\n\n    _handleKeydown(event) {\n      if (event.key !== TAB_KEY) {\n        return;\n      }\n\n      this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;\n    }\n\n    _getConfig(config) {\n      config = { ...Default$6,\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$7, config, DefaultType$6);\n      return config;\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): modal.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$6 = 'modal';\n  const DATA_KEY$6 = 'bs.modal';\n  const EVENT_KEY$6 = `.${DATA_KEY$6}`;\n  const DATA_API_KEY$3 = '.data-api';\n  const ESCAPE_KEY$1 = 'Escape';\n  const Default$5 = {\n    backdrop: true,\n    keyboard: true,\n    focus: true\n  };\n  const DefaultType$5 = {\n    backdrop: '(boolean|string)',\n    keyboard: 'boolean',\n    focus: 'boolean'\n  };\n  const EVENT_HIDE$3 = `hide${EVENT_KEY$6}`;\n  const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$6}`;\n  const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$6}`;\n  const EVENT_SHOW$3 = `show${EVENT_KEY$6}`;\n  const EVENT_SHOWN$3 = `shown${EVENT_KEY$6}`;\n  const EVENT_RESIZE = `resize${EVENT_KEY$6}`;\n  const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$6}`;\n  const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$6}`;\n  const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY$6}`;\n  const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$6}`;\n  const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;\n  const CLASS_NAME_OPEN = 'modal-open';\n  const CLASS_NAME_FADE$3 = 'fade';\n  const CLASS_NAME_SHOW$4 = 'show';\n  const CLASS_NAME_STATIC = 'modal-static';\n  const OPEN_SELECTOR$1 = '.modal.show';\n  const SELECTOR_DIALOG = '.modal-dialog';\n  const SELECTOR_MODAL_BODY = '.modal-body';\n  const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle=\"modal\"]';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Modal extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._config = this._getConfig(config);\n      this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);\n      this._backdrop = this._initializeBackDrop();\n      this._focustrap = this._initializeFocusTrap();\n      this._isShown = false;\n      this._ignoreBackdropClick = false;\n      this._isTransitioning = false;\n      this._scrollBar = new ScrollBarHelper();\n    } // Getters\n\n\n    static get Default() {\n      return Default$5;\n    }\n\n    static get NAME() {\n      return NAME$6;\n    } // Public\n\n\n    toggle(relatedTarget) {\n      return this._isShown ? this.hide() : this.show(relatedTarget);\n    }\n\n    show(relatedTarget) {\n      if (this._isShown || this._isTransitioning) {\n        return;\n      }\n\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {\n        relatedTarget\n      });\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      this._isShown = true;\n\n      if (this._isAnimated()) {\n        this._isTransitioning = true;\n      }\n\n      this._scrollBar.hide();\n\n      document.body.classList.add(CLASS_NAME_OPEN);\n\n      this._adjustDialog();\n\n      this._setEscapeEvent();\n\n      this._setResizeEvent();\n\n      EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {\n        EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {\n          if (event.target === this._element) {\n            this._ignoreBackdropClick = true;\n          }\n        });\n      });\n\n      this._showBackdrop(() => this._showElement(relatedTarget));\n    }\n\n    hide() {\n      if (!this._isShown || this._isTransitioning) {\n        return;\n      }\n\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      this._isShown = false;\n\n      const isAnimated = this._isAnimated();\n\n      if (isAnimated) {\n        this._isTransitioning = true;\n      }\n\n      this._setEscapeEvent();\n\n      this._setResizeEvent();\n\n      this._focustrap.deactivate();\n\n      this._element.classList.remove(CLASS_NAME_SHOW$4);\n\n      EventHandler.off(this._element, EVENT_CLICK_DISMISS);\n      EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS);\n\n      this._queueCallback(() => this._hideModal(), this._element, isAnimated);\n    }\n\n    dispose() {\n      [window, this._dialog].forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY$6));\n\n      this._backdrop.dispose();\n\n      this._focustrap.deactivate();\n\n      super.dispose();\n    }\n\n    handleUpdate() {\n      this._adjustDialog();\n    } // Private\n\n\n    _initializeBackDrop() {\n      return new Backdrop({\n        isVisible: Boolean(this._config.backdrop),\n        // 'static' option will be translated to true, and booleans will keep their value\n        isAnimated: this._isAnimated()\n      });\n    }\n\n    _initializeFocusTrap() {\n      return new FocusTrap({\n        trapElement: this._element\n      });\n    }\n\n    _getConfig(config) {\n      config = { ...Default$5,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$6, config, DefaultType$5);\n      return config;\n    }\n\n    _showElement(relatedTarget) {\n      const isAnimated = this._isAnimated();\n\n      const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);\n\n      if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n        // Don't move modal's DOM position\n        document.body.append(this._element);\n      }\n\n      this._element.style.display = 'block';\n\n      this._element.removeAttribute('aria-hidden');\n\n      this._element.setAttribute('aria-modal', true);\n\n      this._element.setAttribute('role', 'dialog');\n\n      this._element.scrollTop = 0;\n\n      if (modalBody) {\n        modalBody.scrollTop = 0;\n      }\n\n      if (isAnimated) {\n        reflow(this._element);\n      }\n\n      this._element.classList.add(CLASS_NAME_SHOW$4);\n\n      const transitionComplete = () => {\n        if (this._config.focus) {\n          this._focustrap.activate();\n        }\n\n        this._isTransitioning = false;\n        EventHandler.trigger(this._element, EVENT_SHOWN$3, {\n          relatedTarget\n        });\n      };\n\n      this._queueCallback(transitionComplete, this._dialog, isAnimated);\n    }\n\n    _setEscapeEvent() {\n      if (this._isShown) {\n        EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {\n          if (this._config.keyboard && event.key === ESCAPE_KEY$1) {\n            event.preventDefault();\n            this.hide();\n          } else if (!this._config.keyboard && event.key === ESCAPE_KEY$1) {\n            this._triggerBackdropTransition();\n          }\n        });\n      } else {\n        EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS$1);\n      }\n    }\n\n    _setResizeEvent() {\n      if (this._isShown) {\n        EventHandler.on(window, EVENT_RESIZE, () => this._adjustDialog());\n      } else {\n        EventHandler.off(window, EVENT_RESIZE);\n      }\n    }\n\n    _hideModal() {\n      this._element.style.display = 'none';\n\n      this._element.setAttribute('aria-hidden', true);\n\n      this._element.removeAttribute('aria-modal');\n\n      this._element.removeAttribute('role');\n\n      this._isTransitioning = false;\n\n      this._backdrop.hide(() => {\n        document.body.classList.remove(CLASS_NAME_OPEN);\n\n        this._resetAdjustments();\n\n        this._scrollBar.reset();\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN$3);\n      });\n    }\n\n    _showBackdrop(callback) {\n      EventHandler.on(this._element, EVENT_CLICK_DISMISS, event => {\n        if (this._ignoreBackdropClick) {\n          this._ignoreBackdropClick = false;\n          return;\n        }\n\n        if (event.target !== event.currentTarget) {\n          return;\n        }\n\n        if (this._config.backdrop === true) {\n          this.hide();\n        } else if (this._config.backdrop === 'static') {\n          this._triggerBackdropTransition();\n        }\n      });\n\n      this._backdrop.show(callback);\n    }\n\n    _isAnimated() {\n      return this._element.classList.contains(CLASS_NAME_FADE$3);\n    }\n\n    _triggerBackdropTransition() {\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      const {\n        classList,\n        scrollHeight,\n        style\n      } = this._element;\n      const isModalOverflowing = scrollHeight > document.documentElement.clientHeight; // return if the following background transition hasn't yet completed\n\n      if (!isModalOverflowing && style.overflowY === 'hidden' || classList.contains(CLASS_NAME_STATIC)) {\n        return;\n      }\n\n      if (!isModalOverflowing) {\n        style.overflowY = 'hidden';\n      }\n\n      classList.add(CLASS_NAME_STATIC);\n\n      this._queueCallback(() => {\n        classList.remove(CLASS_NAME_STATIC);\n\n        if (!isModalOverflowing) {\n          this._queueCallback(() => {\n            style.overflowY = '';\n          }, this._dialog);\n        }\n      }, this._dialog);\n\n      this._element.focus();\n    } // ----------------------------------------------------------------------\n    // the following methods are used to handle overflowing modals\n    // ----------------------------------------------------------------------\n\n\n    _adjustDialog() {\n      const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n\n      const scrollbarWidth = this._scrollBar.getWidth();\n\n      const isBodyOverflowing = scrollbarWidth > 0;\n\n      if (!isBodyOverflowing && isModalOverflowing && !isRTL() || isBodyOverflowing && !isModalOverflowing && isRTL()) {\n        this._element.style.paddingLeft = `${scrollbarWidth}px`;\n      }\n\n      if (isBodyOverflowing && !isModalOverflowing && !isRTL() || !isBodyOverflowing && isModalOverflowing && isRTL()) {\n        this._element.style.paddingRight = `${scrollbarWidth}px`;\n      }\n    }\n\n    _resetAdjustments() {\n      this._element.style.paddingLeft = '';\n      this._element.style.paddingRight = '';\n    } // Static\n\n\n    static jQueryInterface(config, relatedTarget) {\n      return this.each(function () {\n        const data = Modal.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](relatedTarget);\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {\n    const target = getElementFromSelector(this);\n\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    EventHandler.one(target, EVENT_SHOW$3, showEvent => {\n      if (showEvent.defaultPrevented) {\n        // only register focus restorer if modal will actually get shown\n        return;\n      }\n\n      EventHandler.one(target, EVENT_HIDDEN$3, () => {\n        if (isVisible(this)) {\n          this.focus();\n        }\n      });\n    }); // avoid conflict when clicking moddal toggler while another one is open\n\n    const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);\n\n    if (allReadyOpen) {\n      Modal.getInstance(allReadyOpen).hide();\n    }\n\n    const data = Modal.getOrCreateInstance(target);\n    data.toggle(this);\n  });\n  enableDismissTrigger(Modal);\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Modal to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Modal);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): offcanvas.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$5 = 'offcanvas';\n  const DATA_KEY$5 = 'bs.offcanvas';\n  const EVENT_KEY$5 = `.${DATA_KEY$5}`;\n  const DATA_API_KEY$2 = '.data-api';\n  const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$5}${DATA_API_KEY$2}`;\n  const ESCAPE_KEY = 'Escape';\n  const Default$4 = {\n    backdrop: true,\n    keyboard: true,\n    scroll: false\n  };\n  const DefaultType$4 = {\n    backdrop: 'boolean',\n    keyboard: 'boolean',\n    scroll: 'boolean'\n  };\n  const CLASS_NAME_SHOW$3 = 'show';\n  const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';\n  const OPEN_SELECTOR = '.offcanvas.show';\n  const EVENT_SHOW$2 = `show${EVENT_KEY$5}`;\n  const EVENT_SHOWN$2 = `shown${EVENT_KEY$5}`;\n  const EVENT_HIDE$2 = `hide${EVENT_KEY$5}`;\n  const EVENT_HIDDEN$2 = `hidden${EVENT_KEY$5}`;\n  const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$5}${DATA_API_KEY$2}`;\n  const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$5}`;\n  const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle=\"offcanvas\"]';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Offcanvas extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._config = this._getConfig(config);\n      this._isShown = false;\n      this._backdrop = this._initializeBackDrop();\n      this._focustrap = this._initializeFocusTrap();\n\n      this._addEventListeners();\n    } // Getters\n\n\n    static get NAME() {\n      return NAME$5;\n    }\n\n    static get Default() {\n      return Default$4;\n    } // Public\n\n\n    toggle(relatedTarget) {\n      return this._isShown ? this.hide() : this.show(relatedTarget);\n    }\n\n    show(relatedTarget) {\n      if (this._isShown) {\n        return;\n      }\n\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$2, {\n        relatedTarget\n      });\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      this._isShown = true;\n      this._element.style.visibility = 'visible';\n\n      this._backdrop.show();\n\n      if (!this._config.scroll) {\n        new ScrollBarHelper().hide();\n      }\n\n      this._element.removeAttribute('aria-hidden');\n\n      this._element.setAttribute('aria-modal', true);\n\n      this._element.setAttribute('role', 'dialog');\n\n      this._element.classList.add(CLASS_NAME_SHOW$3);\n\n      const completeCallBack = () => {\n        if (!this._config.scroll) {\n          this._focustrap.activate();\n        }\n\n        EventHandler.trigger(this._element, EVENT_SHOWN$2, {\n          relatedTarget\n        });\n      };\n\n      this._queueCallback(completeCallBack, this._element, true);\n    }\n\n    hide() {\n      if (!this._isShown) {\n        return;\n      }\n\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$2);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      this._focustrap.deactivate();\n\n      this._element.blur();\n\n      this._isShown = false;\n\n      this._element.classList.remove(CLASS_NAME_SHOW$3);\n\n      this._backdrop.hide();\n\n      const completeCallback = () => {\n        this._element.setAttribute('aria-hidden', true);\n\n        this._element.removeAttribute('aria-modal');\n\n        this._element.removeAttribute('role');\n\n        this._element.style.visibility = 'hidden';\n\n        if (!this._config.scroll) {\n          new ScrollBarHelper().reset();\n        }\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN$2);\n      };\n\n      this._queueCallback(completeCallback, this._element, true);\n    }\n\n    dispose() {\n      this._backdrop.dispose();\n\n      this._focustrap.deactivate();\n\n      super.dispose();\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$4,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$5, config, DefaultType$4);\n      return config;\n    }\n\n    _initializeBackDrop() {\n      return new Backdrop({\n        className: CLASS_NAME_BACKDROP,\n        isVisible: this._config.backdrop,\n        isAnimated: true,\n        rootElement: this._element.parentNode,\n        clickCallback: () => this.hide()\n      });\n    }\n\n    _initializeFocusTrap() {\n      return new FocusTrap({\n        trapElement: this._element\n      });\n    }\n\n    _addEventListeners() {\n      EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n        if (this._config.keyboard && event.key === ESCAPE_KEY) {\n          this.hide();\n        }\n      });\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Offcanvas.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](this);\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {\n    const target = getElementFromSelector(this);\n\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    if (isDisabled(this)) {\n      return;\n    }\n\n    EventHandler.one(target, EVENT_HIDDEN$2, () => {\n      // focus on trigger when it is closed\n      if (isVisible(this)) {\n        this.focus();\n      }\n    }); // avoid conflict when clicking a toggler of an offcanvas, while another is open\n\n    const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);\n\n    if (allReadyOpen && allReadyOpen !== target) {\n      Offcanvas.getInstance(allReadyOpen).hide();\n    }\n\n    const data = Offcanvas.getOrCreateInstance(target);\n    data.toggle(this);\n  });\n  EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => SelectorEngine.find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show()));\n  enableDismissTrigger(Offcanvas);\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   */\n\n  defineJQueryPlugin(Offcanvas);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): util/sanitizer.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);\n  const ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\n  /**\n   * A pattern that recognizes a commonly useful subset of URLs that are safe.\n   *\n   * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts\n   */\n\n  const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;\n  /**\n   * A pattern that matches safe data URLs. Only matches image, video and audio types.\n   *\n   * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts\n   */\n\n  const DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i;\n\n  const allowedAttribute = (attribute, allowedAttributeList) => {\n    const attributeName = attribute.nodeName.toLowerCase();\n\n    if (allowedAttributeList.includes(attributeName)) {\n      if (uriAttributes.has(attributeName)) {\n        return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue));\n      }\n\n      return true;\n    }\n\n    const regExp = allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp); // Check if a regular expression validates the attribute.\n\n    for (let i = 0, len = regExp.length; i < len; i++) {\n      if (regExp[i].test(attributeName)) {\n        return true;\n      }\n    }\n\n    return false;\n  };\n\n  const DefaultAllowlist = {\n    // Global attributes allowed on any supplied element below.\n    '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n    a: ['target', 'href', 'title', 'rel'],\n    area: [],\n    b: [],\n    br: [],\n    col: [],\n    code: [],\n    div: [],\n    em: [],\n    hr: [],\n    h1: [],\n    h2: [],\n    h3: [],\n    h4: [],\n    h5: [],\n    h6: [],\n    i: [],\n    img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n    li: [],\n    ol: [],\n    p: [],\n    pre: [],\n    s: [],\n    small: [],\n    span: [],\n    sub: [],\n    sup: [],\n    strong: [],\n    u: [],\n    ul: []\n  };\n  function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {\n    if (!unsafeHtml.length) {\n      return unsafeHtml;\n    }\n\n    if (sanitizeFn && typeof sanitizeFn === 'function') {\n      return sanitizeFn(unsafeHtml);\n    }\n\n    const domParser = new window.DOMParser();\n    const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n    const elements = [].concat(...createdDocument.body.querySelectorAll('*'));\n\n    for (let i = 0, len = elements.length; i < len; i++) {\n      const element = elements[i];\n      const elementName = element.nodeName.toLowerCase();\n\n      if (!Object.keys(allowList).includes(elementName)) {\n        element.remove();\n        continue;\n      }\n\n      const attributeList = [].concat(...element.attributes);\n      const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);\n      attributeList.forEach(attribute => {\n        if (!allowedAttribute(attribute, allowedAttributes)) {\n          element.removeAttribute(attribute.nodeName);\n        }\n      });\n    }\n\n    return createdDocument.body.innerHTML;\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): tooltip.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$4 = 'tooltip';\n  const DATA_KEY$4 = 'bs.tooltip';\n  const EVENT_KEY$4 = `.${DATA_KEY$4}`;\n  const CLASS_PREFIX$1 = 'bs-tooltip';\n  const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);\n  const DefaultType$3 = {\n    animation: 'boolean',\n    template: 'string',\n    title: '(string|element|function)',\n    trigger: 'string',\n    delay: '(number|object)',\n    html: 'boolean',\n    selector: '(string|boolean)',\n    placement: '(string|function)',\n    offset: '(array|string|function)',\n    container: '(string|element|boolean)',\n    fallbackPlacements: 'array',\n    boundary: '(string|element)',\n    customClass: '(string|function)',\n    sanitize: 'boolean',\n    sanitizeFn: '(null|function)',\n    allowList: 'object',\n    popperConfig: '(null|object|function)'\n  };\n  const AttachmentMap = {\n    AUTO: 'auto',\n    TOP: 'top',\n    RIGHT: isRTL() ? 'left' : 'right',\n    BOTTOM: 'bottom',\n    LEFT: isRTL() ? 'right' : 'left'\n  };\n  const Default$3 = {\n    animation: true,\n    template: '<div class=\"tooltip\" role=\"tooltip\">' + '<div class=\"tooltip-arrow\"></div>' + '<div class=\"tooltip-inner\"></div>' + '</div>',\n    trigger: 'hover focus',\n    title: '',\n    delay: 0,\n    html: false,\n    selector: false,\n    placement: 'top',\n    offset: [0, 0],\n    container: false,\n    fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n    boundary: 'clippingParents',\n    customClass: '',\n    sanitize: true,\n    sanitizeFn: null,\n    allowList: DefaultAllowlist,\n    popperConfig: null\n  };\n  const Event$2 = {\n    HIDE: `hide${EVENT_KEY$4}`,\n    HIDDEN: `hidden${EVENT_KEY$4}`,\n    SHOW: `show${EVENT_KEY$4}`,\n    SHOWN: `shown${EVENT_KEY$4}`,\n    INSERTED: `inserted${EVENT_KEY$4}`,\n    CLICK: `click${EVENT_KEY$4}`,\n    FOCUSIN: `focusin${EVENT_KEY$4}`,\n    FOCUSOUT: `focusout${EVENT_KEY$4}`,\n    MOUSEENTER: `mouseenter${EVENT_KEY$4}`,\n    MOUSELEAVE: `mouseleave${EVENT_KEY$4}`\n  };\n  const CLASS_NAME_FADE$2 = 'fade';\n  const CLASS_NAME_MODAL = 'modal';\n  const CLASS_NAME_SHOW$2 = 'show';\n  const HOVER_STATE_SHOW = 'show';\n  const HOVER_STATE_OUT = 'out';\n  const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';\n  const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;\n  const EVENT_MODAL_HIDE = 'hide.bs.modal';\n  const TRIGGER_HOVER = 'hover';\n  const TRIGGER_FOCUS = 'focus';\n  const TRIGGER_CLICK = 'click';\n  const TRIGGER_MANUAL = 'manual';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Tooltip extends BaseComponent {\n    constructor(element, config) {\n      if (typeof Popper__namespace === 'undefined') {\n        throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)');\n      }\n\n      super(element); // private\n\n      this._isEnabled = true;\n      this._timeout = 0;\n      this._hoverState = '';\n      this._activeTrigger = {};\n      this._popper = null; // Protected\n\n      this._config = this._getConfig(config);\n      this.tip = null;\n\n      this._setListeners();\n    } // Getters\n\n\n    static get Default() {\n      return Default$3;\n    }\n\n    static get NAME() {\n      return NAME$4;\n    }\n\n    static get Event() {\n      return Event$2;\n    }\n\n    static get DefaultType() {\n      return DefaultType$3;\n    } // Public\n\n\n    enable() {\n      this._isEnabled = true;\n    }\n\n    disable() {\n      this._isEnabled = false;\n    }\n\n    toggleEnabled() {\n      this._isEnabled = !this._isEnabled;\n    }\n\n    toggle(event) {\n      if (!this._isEnabled) {\n        return;\n      }\n\n      if (event) {\n        const context = this._initializeOnDelegatedTarget(event);\n\n        context._activeTrigger.click = !context._activeTrigger.click;\n\n        if (context._isWithActiveTrigger()) {\n          context._enter(null, context);\n        } else {\n          context._leave(null, context);\n        }\n      } else {\n        if (this.getTipElement().classList.contains(CLASS_NAME_SHOW$2)) {\n          this._leave(null, this);\n\n          return;\n        }\n\n        this._enter(null, this);\n      }\n    }\n\n    dispose() {\n      clearTimeout(this._timeout);\n      EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n\n      if (this.tip) {\n        this.tip.remove();\n      }\n\n      this._disposePopper();\n\n      super.dispose();\n    }\n\n    show() {\n      if (this._element.style.display === 'none') {\n        throw new Error('Please use show on visible elements');\n      }\n\n      if (!(this.isWithContent() && this._isEnabled)) {\n        return;\n      }\n\n      const showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW);\n      const shadowRoot = findShadowRoot(this._element);\n      const isInTheDom = shadowRoot === null ? this._element.ownerDocument.documentElement.contains(this._element) : shadowRoot.contains(this._element);\n\n      if (showEvent.defaultPrevented || !isInTheDom) {\n        return;\n      } // A trick to recreate a tooltip in case a new title is given by using the NOT documented `data-bs-original-title`\n      // This will be removed later in favor of a `setContent` method\n\n\n      if (this.constructor.NAME === 'tooltip' && this.tip && this.getTitle() !== this.tip.querySelector(SELECTOR_TOOLTIP_INNER).innerHTML) {\n        this._disposePopper();\n\n        this.tip.remove();\n        this.tip = null;\n      }\n\n      const tip = this.getTipElement();\n      const tipId = getUID(this.constructor.NAME);\n      tip.setAttribute('id', tipId);\n\n      this._element.setAttribute('aria-describedby', tipId);\n\n      if (this._config.animation) {\n        tip.classList.add(CLASS_NAME_FADE$2);\n      }\n\n      const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement;\n\n      const attachment = this._getAttachment(placement);\n\n      this._addAttachmentClass(attachment);\n\n      const {\n        container\n      } = this._config;\n      Data.set(tip, this.constructor.DATA_KEY, this);\n\n      if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n        container.append(tip);\n        EventHandler.trigger(this._element, this.constructor.Event.INSERTED);\n      }\n\n      if (this._popper) {\n        this._popper.update();\n      } else {\n        this._popper = Popper__namespace.createPopper(this._element, tip, this._getPopperConfig(attachment));\n      }\n\n      tip.classList.add(CLASS_NAME_SHOW$2);\n\n      const customClass = this._resolvePossibleFunction(this._config.customClass);\n\n      if (customClass) {\n        tip.classList.add(...customClass.split(' '));\n      } // If this is a touch-enabled device we add extra\n      // empty mouseover listeners to the body's immediate children;\n      // only needed because of broken event delegation on iOS\n      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n\n      if ('ontouchstart' in document.documentElement) {\n        [].concat(...document.body.children).forEach(element => {\n          EventHandler.on(element, 'mouseover', noop);\n        });\n      }\n\n      const complete = () => {\n        const prevHoverState = this._hoverState;\n        this._hoverState = null;\n        EventHandler.trigger(this._element, this.constructor.Event.SHOWN);\n\n        if (prevHoverState === HOVER_STATE_OUT) {\n          this._leave(null, this);\n        }\n      };\n\n      const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$2);\n\n      this._queueCallback(complete, this.tip, isAnimated);\n    }\n\n    hide() {\n      if (!this._popper) {\n        return;\n      }\n\n      const tip = this.getTipElement();\n\n      const complete = () => {\n        if (this._isWithActiveTrigger()) {\n          return;\n        }\n\n        if (this._hoverState !== HOVER_STATE_SHOW) {\n          tip.remove();\n        }\n\n        this._cleanTipClass();\n\n        this._element.removeAttribute('aria-describedby');\n\n        EventHandler.trigger(this._element, this.constructor.Event.HIDDEN);\n\n        this._disposePopper();\n      };\n\n      const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      tip.classList.remove(CLASS_NAME_SHOW$2); // If this is a touch-enabled device we remove the extra\n      // empty mouseover listeners we added for iOS support\n\n      if ('ontouchstart' in document.documentElement) {\n        [].concat(...document.body.children).forEach(element => EventHandler.off(element, 'mouseover', noop));\n      }\n\n      this._activeTrigger[TRIGGER_CLICK] = false;\n      this._activeTrigger[TRIGGER_FOCUS] = false;\n      this._activeTrigger[TRIGGER_HOVER] = false;\n      const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$2);\n\n      this._queueCallback(complete, this.tip, isAnimated);\n\n      this._hoverState = '';\n    }\n\n    update() {\n      if (this._popper !== null) {\n        this._popper.update();\n      }\n    } // Protected\n\n\n    isWithContent() {\n      return Boolean(this.getTitle());\n    }\n\n    getTipElement() {\n      if (this.tip) {\n        return this.tip;\n      }\n\n      const element = document.createElement('div');\n      element.innerHTML = this._config.template;\n      const tip = element.children[0];\n      this.setContent(tip);\n      tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);\n      this.tip = tip;\n      return this.tip;\n    }\n\n    setContent(tip) {\n      this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER);\n    }\n\n    _sanitizeAndSetContent(template, content, selector) {\n      const templateElement = SelectorEngine.findOne(selector, template);\n\n      if (!content && templateElement) {\n        templateElement.remove();\n        return;\n      } // we use append for html objects to maintain js events\n\n\n      this.setElementContent(templateElement, content);\n    }\n\n    setElementContent(element, content) {\n      if (element === null) {\n        return;\n      }\n\n      if (isElement(content)) {\n        content = getElement(content); // content is a DOM node or a jQuery\n\n        if (this._config.html) {\n          if (content.parentNode !== element) {\n            element.innerHTML = '';\n            element.append(content);\n          }\n        } else {\n          element.textContent = content.textContent;\n        }\n\n        return;\n      }\n\n      if (this._config.html) {\n        if (this._config.sanitize) {\n          content = sanitizeHtml(content, this._config.allowList, this._config.sanitizeFn);\n        }\n\n        element.innerHTML = content;\n      } else {\n        element.textContent = content;\n      }\n    }\n\n    getTitle() {\n      const title = this._element.getAttribute('data-bs-original-title') || this._config.title;\n\n      return this._resolvePossibleFunction(title);\n    }\n\n    updateAttachment(attachment) {\n      if (attachment === 'right') {\n        return 'end';\n      }\n\n      if (attachment === 'left') {\n        return 'start';\n      }\n\n      return attachment;\n    } // Private\n\n\n    _initializeOnDelegatedTarget(event, context) {\n      return context || this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());\n    }\n\n    _getOffset() {\n      const {\n        offset\n      } = this._config;\n\n      if (typeof offset === 'string') {\n        return offset.split(',').map(val => Number.parseInt(val, 10));\n      }\n\n      if (typeof offset === 'function') {\n        return popperData => offset(popperData, this._element);\n      }\n\n      return offset;\n    }\n\n    _resolvePossibleFunction(content) {\n      return typeof content === 'function' ? content.call(this._element) : content;\n    }\n\n    _getPopperConfig(attachment) {\n      const defaultBsPopperConfig = {\n        placement: attachment,\n        modifiers: [{\n          name: 'flip',\n          options: {\n            fallbackPlacements: this._config.fallbackPlacements\n          }\n        }, {\n          name: 'offset',\n          options: {\n            offset: this._getOffset()\n          }\n        }, {\n          name: 'preventOverflow',\n          options: {\n            boundary: this._config.boundary\n          }\n        }, {\n          name: 'arrow',\n          options: {\n            element: `.${this.constructor.NAME}-arrow`\n          }\n        }, {\n          name: 'onChange',\n          enabled: true,\n          phase: 'afterWrite',\n          fn: data => this._handlePopperPlacementChange(data)\n        }],\n        onFirstUpdate: data => {\n          if (data.options.placement !== data.placement) {\n            this._handlePopperPlacementChange(data);\n          }\n        }\n      };\n      return { ...defaultBsPopperConfig,\n        ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n      };\n    }\n\n    _addAttachmentClass(attachment) {\n      this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`);\n    }\n\n    _getAttachment(placement) {\n      return AttachmentMap[placement.toUpperCase()];\n    }\n\n    _setListeners() {\n      const triggers = this._config.trigger.split(' ');\n\n      triggers.forEach(trigger => {\n        if (trigger === 'click') {\n          EventHandler.on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event));\n        } else if (trigger !== TRIGGER_MANUAL) {\n          const eventIn = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSEENTER : this.constructor.Event.FOCUSIN;\n          const eventOut = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSELEAVE : this.constructor.Event.FOCUSOUT;\n          EventHandler.on(this._element, eventIn, this._config.selector, event => this._enter(event));\n          EventHandler.on(this._element, eventOut, this._config.selector, event => this._leave(event));\n        }\n      });\n\n      this._hideModalHandler = () => {\n        if (this._element) {\n          this.hide();\n        }\n      };\n\n      EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n\n      if (this._config.selector) {\n        this._config = { ...this._config,\n          trigger: 'manual',\n          selector: ''\n        };\n      } else {\n        this._fixTitle();\n      }\n    }\n\n    _fixTitle() {\n      const title = this._element.getAttribute('title');\n\n      const originalTitleType = typeof this._element.getAttribute('data-bs-original-title');\n\n      if (title || originalTitleType !== 'string') {\n        this._element.setAttribute('data-bs-original-title', title || '');\n\n        if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) {\n          this._element.setAttribute('aria-label', title);\n        }\n\n        this._element.setAttribute('title', '');\n      }\n    }\n\n    _enter(event, context) {\n      context = this._initializeOnDelegatedTarget(event, context);\n\n      if (event) {\n        context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;\n      }\n\n      if (context.getTipElement().classList.contains(CLASS_NAME_SHOW$2) || context._hoverState === HOVER_STATE_SHOW) {\n        context._hoverState = HOVER_STATE_SHOW;\n        return;\n      }\n\n      clearTimeout(context._timeout);\n      context._hoverState = HOVER_STATE_SHOW;\n\n      if (!context._config.delay || !context._config.delay.show) {\n        context.show();\n        return;\n      }\n\n      context._timeout = setTimeout(() => {\n        if (context._hoverState === HOVER_STATE_SHOW) {\n          context.show();\n        }\n      }, context._config.delay.show);\n    }\n\n    _leave(event, context) {\n      context = this._initializeOnDelegatedTarget(event, context);\n\n      if (event) {\n        context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);\n      }\n\n      if (context._isWithActiveTrigger()) {\n        return;\n      }\n\n      clearTimeout(context._timeout);\n      context._hoverState = HOVER_STATE_OUT;\n\n      if (!context._config.delay || !context._config.delay.hide) {\n        context.hide();\n        return;\n      }\n\n      context._timeout = setTimeout(() => {\n        if (context._hoverState === HOVER_STATE_OUT) {\n          context.hide();\n        }\n      }, context._config.delay.hide);\n    }\n\n    _isWithActiveTrigger() {\n      for (const trigger in this._activeTrigger) {\n        if (this._activeTrigger[trigger]) {\n          return true;\n        }\n      }\n\n      return false;\n    }\n\n    _getConfig(config) {\n      const dataAttributes = Manipulator.getDataAttributes(this._element);\n      Object.keys(dataAttributes).forEach(dataAttr => {\n        if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {\n          delete dataAttributes[dataAttr];\n        }\n      });\n      config = { ...this.constructor.Default,\n        ...dataAttributes,\n        ...(typeof config === 'object' && config ? config : {})\n      };\n      config.container = config.container === false ? document.body : getElement(config.container);\n\n      if (typeof config.delay === 'number') {\n        config.delay = {\n          show: config.delay,\n          hide: config.delay\n        };\n      }\n\n      if (typeof config.title === 'number') {\n        config.title = config.title.toString();\n      }\n\n      if (typeof config.content === 'number') {\n        config.content = config.content.toString();\n      }\n\n      typeCheckConfig(NAME$4, config, this.constructor.DefaultType);\n\n      if (config.sanitize) {\n        config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn);\n      }\n\n      return config;\n    }\n\n    _getDelegateConfig() {\n      const config = {};\n\n      for (const key in this._config) {\n        if (this.constructor.Default[key] !== this._config[key]) {\n          config[key] = this._config[key];\n        }\n      } // In the future can be replaced with:\n      // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n      // `Object.fromEntries(keysWithDifferentValues)`\n\n\n      return config;\n    }\n\n    _cleanTipClass() {\n      const tip = this.getTipElement();\n      const basicClassPrefixRegex = new RegExp(`(^|\\\\s)${this._getBasicClassPrefix()}\\\\S+`, 'g');\n      const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex);\n\n      if (tabClass !== null && tabClass.length > 0) {\n        tabClass.map(token => token.trim()).forEach(tClass => tip.classList.remove(tClass));\n      }\n    }\n\n    _getBasicClassPrefix() {\n      return CLASS_PREFIX$1;\n    }\n\n    _handlePopperPlacementChange(popperData) {\n      const {\n        state\n      } = popperData;\n\n      if (!state) {\n        return;\n      }\n\n      this.tip = state.elements.popper;\n\n      this._cleanTipClass();\n\n      this._addAttachmentClass(this._getAttachment(state.placement));\n    }\n\n    _disposePopper() {\n      if (this._popper) {\n        this._popper.destroy();\n\n        this._popper = null;\n      }\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Tooltip.getOrCreateInstance(this, config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Tooltip to jQuery only if jQuery is present\n   */\n\n\n  defineJQueryPlugin(Tooltip);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): popover.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$3 = 'popover';\n  const DATA_KEY$3 = 'bs.popover';\n  const EVENT_KEY$3 = `.${DATA_KEY$3}`;\n  const CLASS_PREFIX = 'bs-popover';\n  const Default$2 = { ...Tooltip.Default,\n    placement: 'right',\n    offset: [0, 8],\n    trigger: 'click',\n    content: '',\n    template: '<div class=\"popover\" role=\"tooltip\">' + '<div class=\"popover-arrow\"></div>' + '<h3 class=\"popover-header\"></h3>' + '<div class=\"popover-body\"></div>' + '</div>'\n  };\n  const DefaultType$2 = { ...Tooltip.DefaultType,\n    content: '(string|element|function)'\n  };\n  const Event$1 = {\n    HIDE: `hide${EVENT_KEY$3}`,\n    HIDDEN: `hidden${EVENT_KEY$3}`,\n    SHOW: `show${EVENT_KEY$3}`,\n    SHOWN: `shown${EVENT_KEY$3}`,\n    INSERTED: `inserted${EVENT_KEY$3}`,\n    CLICK: `click${EVENT_KEY$3}`,\n    FOCUSIN: `focusin${EVENT_KEY$3}`,\n    FOCUSOUT: `focusout${EVENT_KEY$3}`,\n    MOUSEENTER: `mouseenter${EVENT_KEY$3}`,\n    MOUSELEAVE: `mouseleave${EVENT_KEY$3}`\n  };\n  const SELECTOR_TITLE = '.popover-header';\n  const SELECTOR_CONTENT = '.popover-body';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Popover extends Tooltip {\n    // Getters\n    static get Default() {\n      return Default$2;\n    }\n\n    static get NAME() {\n      return NAME$3;\n    }\n\n    static get Event() {\n      return Event$1;\n    }\n\n    static get DefaultType() {\n      return DefaultType$2;\n    } // Overrides\n\n\n    isWithContent() {\n      return this.getTitle() || this._getContent();\n    }\n\n    setContent(tip) {\n      this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TITLE);\n\n      this._sanitizeAndSetContent(tip, this._getContent(), SELECTOR_CONTENT);\n    } // Private\n\n\n    _getContent() {\n      return this._resolvePossibleFunction(this._config.content);\n    }\n\n    _getBasicClassPrefix() {\n      return CLASS_PREFIX;\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Popover.getOrCreateInstance(this, config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Popover to jQuery only if jQuery is present\n   */\n\n\n  defineJQueryPlugin(Popover);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): scrollspy.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$2 = 'scrollspy';\n  const DATA_KEY$2 = 'bs.scrollspy';\n  const EVENT_KEY$2 = `.${DATA_KEY$2}`;\n  const DATA_API_KEY$1 = '.data-api';\n  const Default$1 = {\n    offset: 10,\n    method: 'auto',\n    target: ''\n  };\n  const DefaultType$1 = {\n    offset: 'number',\n    method: 'string',\n    target: '(string|element)'\n  };\n  const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;\n  const EVENT_SCROLL = `scroll${EVENT_KEY$2}`;\n  const EVENT_LOAD_DATA_API = `load${EVENT_KEY$2}${DATA_API_KEY$1}`;\n  const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';\n  const CLASS_NAME_ACTIVE$1 = 'active';\n  const SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]';\n  const SELECTOR_NAV_LIST_GROUP$1 = '.nav, .list-group';\n  const SELECTOR_NAV_LINKS = '.nav-link';\n  const SELECTOR_NAV_ITEMS = '.nav-item';\n  const SELECTOR_LIST_ITEMS = '.list-group-item';\n  const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;\n  const SELECTOR_DROPDOWN$1 = '.dropdown';\n  const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';\n  const METHOD_OFFSET = 'offset';\n  const METHOD_POSITION = 'position';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class ScrollSpy extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;\n      this._config = this._getConfig(config);\n      this._offsets = [];\n      this._targets = [];\n      this._activeTarget = null;\n      this._scrollHeight = 0;\n      EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process());\n      this.refresh();\n\n      this._process();\n    } // Getters\n\n\n    static get Default() {\n      return Default$1;\n    }\n\n    static get NAME() {\n      return NAME$2;\n    } // Public\n\n\n    refresh() {\n      const autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;\n      const offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;\n      const offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;\n      this._offsets = [];\n      this._targets = [];\n      this._scrollHeight = this._getScrollHeight();\n      const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target);\n      targets.map(element => {\n        const targetSelector = getSelectorFromElement(element);\n        const target = targetSelector ? SelectorEngine.findOne(targetSelector) : null;\n\n        if (target) {\n          const targetBCR = target.getBoundingClientRect();\n\n          if (targetBCR.width || targetBCR.height) {\n            return [Manipulator[offsetMethod](target).top + offsetBase, targetSelector];\n          }\n        }\n\n        return null;\n      }).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => {\n        this._offsets.push(item[0]);\n\n        this._targets.push(item[1]);\n      });\n    }\n\n    dispose() {\n      EventHandler.off(this._scrollElement, EVENT_KEY$2);\n      super.dispose();\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$1,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' && config ? config : {})\n      };\n      config.target = getElement(config.target) || document.documentElement;\n      typeCheckConfig(NAME$2, config, DefaultType$1);\n      return config;\n    }\n\n    _getScrollTop() {\n      return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;\n    }\n\n    _getScrollHeight() {\n      return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);\n    }\n\n    _getOffsetHeight() {\n      return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;\n    }\n\n    _process() {\n      const scrollTop = this._getScrollTop() + this._config.offset;\n\n      const scrollHeight = this._getScrollHeight();\n\n      const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();\n\n      if (this._scrollHeight !== scrollHeight) {\n        this.refresh();\n      }\n\n      if (scrollTop >= maxScroll) {\n        const target = this._targets[this._targets.length - 1];\n\n        if (this._activeTarget !== target) {\n          this._activate(target);\n        }\n\n        return;\n      }\n\n      if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n        this._activeTarget = null;\n\n        this._clear();\n\n        return;\n      }\n\n      for (let i = this._offsets.length; i--;) {\n        const isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);\n\n        if (isActiveTarget) {\n          this._activate(this._targets[i]);\n        }\n      }\n    }\n\n    _activate(target) {\n      this._activeTarget = target;\n\n      this._clear();\n\n      const queries = SELECTOR_LINK_ITEMS.split(',').map(selector => `${selector}[data-bs-target=\"${target}\"],${selector}[href=\"${target}\"]`);\n      const link = SelectorEngine.findOne(queries.join(','), this._config.target);\n      link.classList.add(CLASS_NAME_ACTIVE$1);\n\n      if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n        SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, link.closest(SELECTOR_DROPDOWN$1)).classList.add(CLASS_NAME_ACTIVE$1);\n      } else {\n        SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP$1).forEach(listGroup => {\n          // Set triggered links parents as active\n          // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n          SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1)); // Handle special case when .nav-link is inside .nav-item\n\n          SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS).forEach(navItem => {\n            SelectorEngine.children(navItem, SELECTOR_NAV_LINKS).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1));\n          });\n        });\n      }\n\n      EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, {\n        relatedTarget: target\n      });\n    }\n\n    _clear() {\n      SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target).filter(node => node.classList.contains(CLASS_NAME_ACTIVE$1)).forEach(node => node.classList.remove(CLASS_NAME_ACTIVE$1));\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = ScrollSpy.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n    SelectorEngine.find(SELECTOR_DATA_SPY).forEach(spy => new ScrollSpy(spy));\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .ScrollSpy to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(ScrollSpy);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): tab.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$1 = 'tab';\n  const DATA_KEY$1 = 'bs.tab';\n  const EVENT_KEY$1 = `.${DATA_KEY$1}`;\n  const DATA_API_KEY = '.data-api';\n  const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`;\n  const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`;\n  const EVENT_SHOW$1 = `show${EVENT_KEY$1}`;\n  const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`;\n  const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}${DATA_API_KEY}`;\n  const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';\n  const CLASS_NAME_ACTIVE = 'active';\n  const CLASS_NAME_FADE$1 = 'fade';\n  const CLASS_NAME_SHOW$1 = 'show';\n  const SELECTOR_DROPDOWN = '.dropdown';\n  const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';\n  const SELECTOR_ACTIVE = '.active';\n  const SELECTOR_ACTIVE_UL = ':scope > li > .active';\n  const SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"tab\"], [data-bs-toggle=\"pill\"], [data-bs-toggle=\"list\"]';\n  const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';\n  const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Tab extends BaseComponent {\n    // Getters\n    static get NAME() {\n      return NAME$1;\n    } // Public\n\n\n    show() {\n      if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n        return;\n      }\n\n      let previous;\n      const target = getElementFromSelector(this._element);\n\n      const listElement = this._element.closest(SELECTOR_NAV_LIST_GROUP);\n\n      if (listElement) {\n        const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE;\n        previous = SelectorEngine.find(itemSelector, listElement);\n        previous = previous[previous.length - 1];\n      }\n\n      const hideEvent = previous ? EventHandler.trigger(previous, EVENT_HIDE$1, {\n        relatedTarget: this._element\n      }) : null;\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$1, {\n        relatedTarget: previous\n      });\n\n      if (showEvent.defaultPrevented || hideEvent !== null && hideEvent.defaultPrevented) {\n        return;\n      }\n\n      this._activate(this._element, listElement);\n\n      const complete = () => {\n        EventHandler.trigger(previous, EVENT_HIDDEN$1, {\n          relatedTarget: this._element\n        });\n        EventHandler.trigger(this._element, EVENT_SHOWN$1, {\n          relatedTarget: previous\n        });\n      };\n\n      if (target) {\n        this._activate(target, target.parentNode, complete);\n      } else {\n        complete();\n      }\n    } // Private\n\n\n    _activate(element, container, callback) {\n      const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? SelectorEngine.find(SELECTOR_ACTIVE_UL, container) : SelectorEngine.children(container, SELECTOR_ACTIVE);\n      const active = activeElements[0];\n      const isTransitioning = callback && active && active.classList.contains(CLASS_NAME_FADE$1);\n\n      const complete = () => this._transitionComplete(element, active, callback);\n\n      if (active && isTransitioning) {\n        active.classList.remove(CLASS_NAME_SHOW$1);\n\n        this._queueCallback(complete, element, true);\n      } else {\n        complete();\n      }\n    }\n\n    _transitionComplete(element, active, callback) {\n      if (active) {\n        active.classList.remove(CLASS_NAME_ACTIVE);\n        const dropdownChild = SelectorEngine.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode);\n\n        if (dropdownChild) {\n          dropdownChild.classList.remove(CLASS_NAME_ACTIVE);\n        }\n\n        if (active.getAttribute('role') === 'tab') {\n          active.setAttribute('aria-selected', false);\n        }\n      }\n\n      element.classList.add(CLASS_NAME_ACTIVE);\n\n      if (element.getAttribute('role') === 'tab') {\n        element.setAttribute('aria-selected', true);\n      }\n\n      reflow(element);\n\n      if (element.classList.contains(CLASS_NAME_FADE$1)) {\n        element.classList.add(CLASS_NAME_SHOW$1);\n      }\n\n      let parent = element.parentNode;\n\n      if (parent && parent.nodeName === 'LI') {\n        parent = parent.parentNode;\n      }\n\n      if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {\n        const dropdownElement = element.closest(SELECTOR_DROPDOWN);\n\n        if (dropdownElement) {\n          SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement).forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE));\n        }\n\n        element.setAttribute('aria-expanded', true);\n      }\n\n      if (callback) {\n        callback();\n      }\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Tab.getOrCreateInstance(this);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    if (isDisabled(this)) {\n      return;\n    }\n\n    const data = Tab.getOrCreateInstance(this);\n    data.show();\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Tab to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Tab);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): toast.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME = 'toast';\n  const DATA_KEY = 'bs.toast';\n  const EVENT_KEY = `.${DATA_KEY}`;\n  const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;\n  const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;\n  const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;\n  const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`;\n  const EVENT_HIDE = `hide${EVENT_KEY}`;\n  const EVENT_HIDDEN = `hidden${EVENT_KEY}`;\n  const EVENT_SHOW = `show${EVENT_KEY}`;\n  const EVENT_SHOWN = `shown${EVENT_KEY}`;\n  const CLASS_NAME_FADE = 'fade';\n  const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility\n\n  const CLASS_NAME_SHOW = 'show';\n  const CLASS_NAME_SHOWING = 'showing';\n  const DefaultType = {\n    animation: 'boolean',\n    autohide: 'boolean',\n    delay: 'number'\n  };\n  const Default = {\n    animation: true,\n    autohide: true,\n    delay: 5000\n  };\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Toast extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._config = this._getConfig(config);\n      this._timeout = null;\n      this._hasMouseInteraction = false;\n      this._hasKeyboardInteraction = false;\n\n      this._setListeners();\n    } // Getters\n\n\n    static get DefaultType() {\n      return DefaultType;\n    }\n\n    static get Default() {\n      return Default;\n    }\n\n    static get NAME() {\n      return NAME;\n    } // Public\n\n\n    show() {\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      this._clearTimeout();\n\n      if (this._config.animation) {\n        this._element.classList.add(CLASS_NAME_FADE);\n      }\n\n      const complete = () => {\n        this._element.classList.remove(CLASS_NAME_SHOWING);\n\n        EventHandler.trigger(this._element, EVENT_SHOWN);\n\n        this._maybeScheduleHide();\n      };\n\n      this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated\n\n\n      reflow(this._element);\n\n      this._element.classList.add(CLASS_NAME_SHOW);\n\n      this._element.classList.add(CLASS_NAME_SHOWING);\n\n      this._queueCallback(complete, this._element, this._config.animation);\n    }\n\n    hide() {\n      if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n        return;\n      }\n\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      const complete = () => {\n        this._element.classList.add(CLASS_NAME_HIDE); // @deprecated\n\n\n        this._element.classList.remove(CLASS_NAME_SHOWING);\n\n        this._element.classList.remove(CLASS_NAME_SHOW);\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN);\n      };\n\n      this._element.classList.add(CLASS_NAME_SHOWING);\n\n      this._queueCallback(complete, this._element, this._config.animation);\n    }\n\n    dispose() {\n      this._clearTimeout();\n\n      if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n        this._element.classList.remove(CLASS_NAME_SHOW);\n      }\n\n      super.dispose();\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' && config ? config : {})\n      };\n      typeCheckConfig(NAME, config, this.constructor.DefaultType);\n      return config;\n    }\n\n    _maybeScheduleHide() {\n      if (!this._config.autohide) {\n        return;\n      }\n\n      if (this._hasMouseInteraction || this._hasKeyboardInteraction) {\n        return;\n      }\n\n      this._timeout = setTimeout(() => {\n        this.hide();\n      }, this._config.delay);\n    }\n\n    _onInteraction(event, isInteracting) {\n      switch (event.type) {\n        case 'mouseover':\n        case 'mouseout':\n          this._hasMouseInteraction = isInteracting;\n          break;\n\n        case 'focusin':\n        case 'focusout':\n          this._hasKeyboardInteraction = isInteracting;\n          break;\n      }\n\n      if (isInteracting) {\n        this._clearTimeout();\n\n        return;\n      }\n\n      const nextElement = event.relatedTarget;\n\n      if (this._element === nextElement || this._element.contains(nextElement)) {\n        return;\n      }\n\n      this._maybeScheduleHide();\n    }\n\n    _setListeners() {\n      EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));\n      EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));\n      EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));\n      EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));\n    }\n\n    _clearTimeout() {\n      clearTimeout(this._timeout);\n      this._timeout = null;\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Toast.getOrCreateInstance(this, config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config](this);\n        }\n      });\n    }\n\n  }\n\n  enableDismissTrigger(Toast);\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Toast to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Toast);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.3): index.umd.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const index_umd = {\n    Alert,\n    Button,\n    Carousel,\n    Collapse,\n    Dropdown,\n    Modal,\n    Offcanvas,\n    Popover,\n    ScrollSpy,\n    Tab,\n    Toast,\n    Tooltip\n  };\n\n  return index_umd;\n\n}));\n//# sourceMappingURL=bootstrap.js.map\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/flatpickr-with-locales.js",
    "content": "/* flatpickr v4.6.11, @license MIT */\n(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.flatpickr = factory());\n}(this, (function () { 'use strict';\n\n    /*! *****************************************************************************\r\n    Copyright (c) Microsoft Corporation.\r\n\r\n    Permission to use, copy, modify, and/or distribute this software for any\r\n    purpose with or without fee is hereby granted.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\n    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\n    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\n    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\n    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\n    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\n    PERFORMANCE OF THIS SOFTWARE.\r\n    ***************************************************************************** */\r\n\r\n    var __assign = function() {\r\n        __assign = Object.assign || function __assign(t) {\r\n            for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n                s = arguments[i];\r\n                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n            }\r\n            return t;\r\n        };\r\n        return __assign.apply(this, arguments);\r\n    };\r\n\r\n    function __spreadArrays() {\r\n        for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n        for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n                r[k] = a[j];\r\n        return r;\r\n    }\n\n    var HOOKS = [\n        \"onChange\",\n        \"onClose\",\n        \"onDayCreate\",\n        \"onDestroy\",\n        \"onKeyDown\",\n        \"onMonthChange\",\n        \"onOpen\",\n        \"onParseConfig\",\n        \"onReady\",\n        \"onValueUpdate\",\n        \"onYearChange\",\n        \"onPreCalendarPosition\",\n    ];\n    var defaults = {\n        _disable: [],\n        allowInput: false,\n        allowInvalidPreload: false,\n        altFormat: \"F j, Y\",\n        altInput: false,\n        altInputClass: \"form-control input\",\n        animate: typeof window === \"object\" &&\n            window.navigator.userAgent.indexOf(\"MSIE\") === -1,\n        ariaDateFormat: \"F j, Y\",\n        autoFillDefaultTime: true,\n        clickOpens: true,\n        closeOnSelect: true,\n        conjunction: \", \",\n        dateFormat: \"Y-m-d\",\n        defaultHour: 12,\n        defaultMinute: 0,\n        defaultSeconds: 0,\n        disable: [],\n        disableMobile: false,\n        enableSeconds: false,\n        enableTime: false,\n        errorHandler: function (err) {\n            return typeof console !== \"undefined\" && console.warn(err);\n        },\n        getWeek: function (givenDate) {\n            var date = new Date(givenDate.getTime());\n            date.setHours(0, 0, 0, 0);\n            // Thursday in current week decides the year.\n            date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7));\n            // January 4 is always in week 1.\n            var week1 = new Date(date.getFullYear(), 0, 4);\n            // Adjust to Thursday in week 1 and count number of weeks from date to week1.\n            return (1 +\n                Math.round(((date.getTime() - week1.getTime()) / 86400000 -\n                    3 +\n                    ((week1.getDay() + 6) % 7)) /\n                    7));\n        },\n        hourIncrement: 1,\n        ignoredFocusElements: [],\n        inline: false,\n        locale: \"default\",\n        minuteIncrement: 5,\n        mode: \"single\",\n        monthSelectorType: \"dropdown\",\n        nextArrow: \"<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>\",\n        noCalendar: false,\n        now: new Date(),\n        onChange: [],\n        onClose: [],\n        onDayCreate: [],\n        onDestroy: [],\n        onKeyDown: [],\n        onMonthChange: [],\n        onOpen: [],\n        onParseConfig: [],\n        onReady: [],\n        onValueUpdate: [],\n        onYearChange: [],\n        onPreCalendarPosition: [],\n        plugins: [],\n        position: \"auto\",\n        positionElement: undefined,\n        prevArrow: \"<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>\",\n        shorthandCurrentMonth: false,\n        showMonths: 1,\n        static: false,\n        time_24hr: false,\n        weekNumbers: false,\n        wrap: false,\n    };\n\n    var english = {\n        weekdays: {\n            shorthand: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n            longhand: [\n                \"Sunday\",\n                \"Monday\",\n                \"Tuesday\",\n                \"Wednesday\",\n                \"Thursday\",\n                \"Friday\",\n                \"Saturday\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"May\",\n                \"Jun\",\n                \"Jul\",\n                \"Aug\",\n                \"Sep\",\n                \"Oct\",\n                \"Nov\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"January\",\n                \"February\",\n                \"March\",\n                \"April\",\n                \"May\",\n                \"June\",\n                \"July\",\n                \"August\",\n                \"September\",\n                \"October\",\n                \"November\",\n                \"December\",\n            ],\n        },\n        daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],\n        firstDayOfWeek: 0,\n        ordinal: function (nth) {\n            var s = nth % 100;\n            if (s > 3 && s < 21)\n                return \"th\";\n            switch (s % 10) {\n                case 1:\n                    return \"st\";\n                case 2:\n                    return \"nd\";\n                case 3:\n                    return \"rd\";\n                default:\n                    return \"th\";\n            }\n        },\n        rangeSeparator: \" to \",\n        weekAbbreviation: \"Wk\",\n        scrollTitle: \"Scroll to increment\",\n        toggleTitle: \"Click to toggle\",\n        amPM: [\"AM\", \"PM\"],\n        yearAriaLabel: \"Year\",\n        monthAriaLabel: \"Month\",\n        hourAriaLabel: \"Hour\",\n        minuteAriaLabel: \"Minute\",\n        time_24hr: false,\n    };\n\n    var pad = function (number, length) {\n        if (length === void 0) { length = 2; }\n        return (\"000\" + number).slice(length * -1);\n    };\n    var int = function (bool) { return (bool === true ? 1 : 0); };\n    /* istanbul ignore next */\n    function debounce(fn, wait) {\n        var t;\n        return function () {\n            var _this = this;\n            var args = arguments;\n            clearTimeout(t);\n            t = setTimeout(function () { return fn.apply(_this, args); }, wait);\n        };\n    }\n    var arrayify = function (obj) {\n        return obj instanceof Array ? obj : [obj];\n    };\n\n    function toggleClass(elem, className, bool) {\n        if (bool === true)\n            return elem.classList.add(className);\n        elem.classList.remove(className);\n    }\n    function createElement(tag, className, content) {\n        var e = window.document.createElement(tag);\n        className = className || \"\";\n        content = content || \"\";\n        e.className = className;\n        if (content !== undefined)\n            e.textContent = content;\n        return e;\n    }\n    function clearNode(node) {\n        while (node.firstChild)\n            node.removeChild(node.firstChild);\n    }\n    function findParent(node, condition) {\n        if (condition(node))\n            return node;\n        else if (node.parentNode)\n            return findParent(node.parentNode, condition);\n        return undefined; // nothing found\n    }\n    function createNumberInput(inputClassName, opts) {\n        var wrapper = createElement(\"div\", \"numInputWrapper\"), numInput = createElement(\"input\", \"numInput \" + inputClassName), arrowUp = createElement(\"span\", \"arrowUp\"), arrowDown = createElement(\"span\", \"arrowDown\");\n        if (navigator.userAgent.indexOf(\"MSIE 9.0\") === -1) {\n            numInput.type = \"number\";\n        }\n        else {\n            numInput.type = \"text\";\n            numInput.pattern = \"\\\\d*\";\n        }\n        if (opts !== undefined)\n            for (var key in opts)\n                numInput.setAttribute(key, opts[key]);\n        wrapper.appendChild(numInput);\n        wrapper.appendChild(arrowUp);\n        wrapper.appendChild(arrowDown);\n        return wrapper;\n    }\n    function getEventTarget(event) {\n        try {\n            if (typeof event.composedPath === \"function\") {\n                var path = event.composedPath();\n                return path[0];\n            }\n            return event.target;\n        }\n        catch (error) {\n            return event.target;\n        }\n    }\n\n    var doNothing = function () { return undefined; };\n    var monthToStr = function (monthNumber, shorthand, locale) { return locale.months[shorthand ? \"shorthand\" : \"longhand\"][monthNumber]; };\n    var revFormat = {\n        D: doNothing,\n        F: function (dateObj, monthName, locale) {\n            dateObj.setMonth(locale.months.longhand.indexOf(monthName));\n        },\n        G: function (dateObj, hour) {\n            dateObj.setHours((dateObj.getHours() >= 12 ? 12 : 0) + parseFloat(hour));\n        },\n        H: function (dateObj, hour) {\n            dateObj.setHours(parseFloat(hour));\n        },\n        J: function (dateObj, day) {\n            dateObj.setDate(parseFloat(day));\n        },\n        K: function (dateObj, amPM, locale) {\n            dateObj.setHours((dateObj.getHours() % 12) +\n                12 * int(new RegExp(locale.amPM[1], \"i\").test(amPM)));\n        },\n        M: function (dateObj, shortMonth, locale) {\n            dateObj.setMonth(locale.months.shorthand.indexOf(shortMonth));\n        },\n        S: function (dateObj, seconds) {\n            dateObj.setSeconds(parseFloat(seconds));\n        },\n        U: function (_, unixSeconds) { return new Date(parseFloat(unixSeconds) * 1000); },\n        W: function (dateObj, weekNum, locale) {\n            var weekNumber = parseInt(weekNum);\n            var date = new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0);\n            date.setDate(date.getDate() - date.getDay() + locale.firstDayOfWeek);\n            return date;\n        },\n        Y: function (dateObj, year) {\n            dateObj.setFullYear(parseFloat(year));\n        },\n        Z: function (_, ISODate) { return new Date(ISODate); },\n        d: function (dateObj, day) {\n            dateObj.setDate(parseFloat(day));\n        },\n        h: function (dateObj, hour) {\n            dateObj.setHours((dateObj.getHours() >= 12 ? 12 : 0) + parseFloat(hour));\n        },\n        i: function (dateObj, minutes) {\n            dateObj.setMinutes(parseFloat(minutes));\n        },\n        j: function (dateObj, day) {\n            dateObj.setDate(parseFloat(day));\n        },\n        l: doNothing,\n        m: function (dateObj, month) {\n            dateObj.setMonth(parseFloat(month) - 1);\n        },\n        n: function (dateObj, month) {\n            dateObj.setMonth(parseFloat(month) - 1);\n        },\n        s: function (dateObj, seconds) {\n            dateObj.setSeconds(parseFloat(seconds));\n        },\n        u: function (_, unixMillSeconds) {\n            return new Date(parseFloat(unixMillSeconds));\n        },\n        w: doNothing,\n        y: function (dateObj, year) {\n            dateObj.setFullYear(2000 + parseFloat(year));\n        },\n    };\n    var tokenRegex = {\n        D: \"\",\n        F: \"\",\n        G: \"(\\\\d\\\\d|\\\\d)\",\n        H: \"(\\\\d\\\\d|\\\\d)\",\n        J: \"(\\\\d\\\\d|\\\\d)\\\\w+\",\n        K: \"\",\n        M: \"\",\n        S: \"(\\\\d\\\\d|\\\\d)\",\n        U: \"(.+)\",\n        W: \"(\\\\d\\\\d|\\\\d)\",\n        Y: \"(\\\\d{4})\",\n        Z: \"(.+)\",\n        d: \"(\\\\d\\\\d|\\\\d)\",\n        h: \"(\\\\d\\\\d|\\\\d)\",\n        i: \"(\\\\d\\\\d|\\\\d)\",\n        j: \"(\\\\d\\\\d|\\\\d)\",\n        l: \"\",\n        m: \"(\\\\d\\\\d|\\\\d)\",\n        n: \"(\\\\d\\\\d|\\\\d)\",\n        s: \"(\\\\d\\\\d|\\\\d)\",\n        u: \"(.+)\",\n        w: \"(\\\\d\\\\d|\\\\d)\",\n        y: \"(\\\\d{2})\",\n    };\n    var formats = {\n        // get the date in UTC\n        Z: function (date) { return date.toISOString(); },\n        // weekday name, short, e.g. Thu\n        D: function (date, locale, options) {\n            return locale.weekdays.shorthand[formats.w(date, locale, options)];\n        },\n        // full month name e.g. January\n        F: function (date, locale, options) {\n            return monthToStr(formats.n(date, locale, options) - 1, false, locale);\n        },\n        // padded hour 1-12\n        G: function (date, locale, options) {\n            return pad(formats.h(date, locale, options));\n        },\n        // hours with leading zero e.g. 03\n        H: function (date) { return pad(date.getHours()); },\n        // day (1-30) with ordinal suffix e.g. 1st, 2nd\n        J: function (date, locale) {\n            return locale.ordinal !== undefined\n                ? date.getDate() + locale.ordinal(date.getDate())\n                : date.getDate();\n        },\n        // AM/PM\n        K: function (date, locale) { return locale.amPM[int(date.getHours() > 11)]; },\n        // shorthand month e.g. Jan, Sep, Oct, etc\n        M: function (date, locale) {\n            return monthToStr(date.getMonth(), true, locale);\n        },\n        // seconds 00-59\n        S: function (date) { return pad(date.getSeconds()); },\n        // unix timestamp\n        U: function (date) { return date.getTime() / 1000; },\n        W: function (date, _, options) {\n            return options.getWeek(date);\n        },\n        // full year e.g. 2016, padded (0001-9999)\n        Y: function (date) { return pad(date.getFullYear(), 4); },\n        // day in month, padded (01-30)\n        d: function (date) { return pad(date.getDate()); },\n        // hour from 1-12 (am/pm)\n        h: function (date) { return (date.getHours() % 12 ? date.getHours() % 12 : 12); },\n        // minutes, padded with leading zero e.g. 09\n        i: function (date) { return pad(date.getMinutes()); },\n        // day in month (1-30)\n        j: function (date) { return date.getDate(); },\n        // weekday name, full, e.g. Thursday\n        l: function (date, locale) {\n            return locale.weekdays.longhand[date.getDay()];\n        },\n        // padded month number (01-12)\n        m: function (date) { return pad(date.getMonth() + 1); },\n        // the month number (1-12)\n        n: function (date) { return date.getMonth() + 1; },\n        // seconds 0-59\n        s: function (date) { return date.getSeconds(); },\n        // Unix Milliseconds\n        u: function (date) { return date.getTime(); },\n        // number of the day of the week\n        w: function (date) { return date.getDay(); },\n        // last two digits of year e.g. 16 for 2016\n        y: function (date) { return String(date.getFullYear()).substring(2); },\n    };\n\n    var createDateFormatter = function (_a) {\n        var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c, _d = _a.isMobile, isMobile = _d === void 0 ? false : _d;\n        return function (dateObj, frmt, overrideLocale) {\n            var locale = overrideLocale || l10n;\n            if (config.formatDate !== undefined && !isMobile) {\n                return config.formatDate(dateObj, frmt, locale);\n            }\n            return frmt\n                .split(\"\")\n                .map(function (c, i, arr) {\n                return formats[c] && arr[i - 1] !== \"\\\\\"\n                    ? formats[c](dateObj, locale, config)\n                    : c !== \"\\\\\"\n                        ? c\n                        : \"\";\n            })\n                .join(\"\");\n        };\n    };\n    var createDateParser = function (_a) {\n        var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c;\n        return function (date, givenFormat, timeless, customLocale) {\n            if (date !== 0 && !date)\n                return undefined;\n            var locale = customLocale || l10n;\n            var parsedDate;\n            var dateOrig = date;\n            if (date instanceof Date)\n                parsedDate = new Date(date.getTime());\n            else if (typeof date !== \"string\" &&\n                date.toFixed !== undefined // timestamp\n            )\n                // create a copy\n                parsedDate = new Date(date);\n            else if (typeof date === \"string\") {\n                // date string\n                var format = givenFormat || (config || defaults).dateFormat;\n                var datestr = String(date).trim();\n                if (datestr === \"today\") {\n                    parsedDate = new Date();\n                    timeless = true;\n                }\n                else if (config && config.parseDate) {\n                    parsedDate = config.parseDate(date, format);\n                }\n                else if (/Z$/.test(datestr) ||\n                    /GMT$/.test(datestr) // datestrings w/ timezone\n                ) {\n                    parsedDate = new Date(date);\n                }\n                else {\n                    var matched = void 0, ops = [];\n                    for (var i = 0, matchIndex = 0, regexStr = \"\"; i < format.length; i++) {\n                        var token_1 = format[i];\n                        var isBackSlash = token_1 === \"\\\\\";\n                        var escaped = format[i - 1] === \"\\\\\" || isBackSlash;\n                        if (tokenRegex[token_1] && !escaped) {\n                            regexStr += tokenRegex[token_1];\n                            var match = new RegExp(regexStr).exec(date);\n                            if (match && (matched = true)) {\n                                ops[token_1 !== \"Y\" ? \"push\" : \"unshift\"]({\n                                    fn: revFormat[token_1],\n                                    val: match[++matchIndex],\n                                });\n                            }\n                        }\n                        else if (!isBackSlash)\n                            regexStr += \".\"; // don't really care\n                    }\n                    parsedDate =\n                        !config || !config.noCalendar\n                            ? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0)\n                            : new Date(new Date().setHours(0, 0, 0, 0));\n                    ops.forEach(function (_a) {\n                        var fn = _a.fn, val = _a.val;\n                        return (parsedDate = fn(parsedDate, val, locale) || parsedDate);\n                    });\n                    parsedDate = matched ? parsedDate : undefined;\n                }\n            }\n            /* istanbul ignore next */\n            if (!(parsedDate instanceof Date && !isNaN(parsedDate.getTime()))) {\n                config.errorHandler(new Error(\"Invalid date provided: \" + dateOrig));\n                return undefined;\n            }\n            if (timeless === true)\n                parsedDate.setHours(0, 0, 0, 0);\n            return parsedDate;\n        };\n    };\n    /**\n     * Compute the difference in dates, measured in ms\n     */\n    function compareDates(date1, date2, timeless) {\n        if (timeless === void 0) { timeless = true; }\n        if (timeless !== false) {\n            return (new Date(date1.getTime()).setHours(0, 0, 0, 0) -\n                new Date(date2.getTime()).setHours(0, 0, 0, 0));\n        }\n        return date1.getTime() - date2.getTime();\n    }\n    var isBetween = function (ts, ts1, ts2) {\n        return ts > Math.min(ts1, ts2) && ts < Math.max(ts1, ts2);\n    };\n    var calculateSecondsSinceMidnight = function (hours, minutes, seconds) {\n        return hours * 3600 + minutes * 60 + seconds;\n    };\n    var parseSeconds = function (secondsSinceMidnight) {\n        var hours = Math.floor(secondsSinceMidnight / 3600), minutes = (secondsSinceMidnight - hours * 3600) / 60;\n        return [hours, minutes, secondsSinceMidnight - hours * 3600 - minutes * 60];\n    };\n    var duration = {\n        DAY: 86400000,\n    };\n    function getDefaultHours(config) {\n        var hours = config.defaultHour;\n        var minutes = config.defaultMinute;\n        var seconds = config.defaultSeconds;\n        if (config.minDate !== undefined) {\n            var minHour = config.minDate.getHours();\n            var minMinutes = config.minDate.getMinutes();\n            var minSeconds = config.minDate.getSeconds();\n            if (hours < minHour) {\n                hours = minHour;\n            }\n            if (hours === minHour && minutes < minMinutes) {\n                minutes = minMinutes;\n            }\n            if (hours === minHour && minutes === minMinutes && seconds < minSeconds)\n                seconds = config.minDate.getSeconds();\n        }\n        if (config.maxDate !== undefined) {\n            var maxHr = config.maxDate.getHours();\n            var maxMinutes = config.maxDate.getMinutes();\n            hours = Math.min(hours, maxHr);\n            if (hours === maxHr)\n                minutes = Math.min(maxMinutes, minutes);\n            if (hours === maxHr && minutes === maxMinutes)\n                seconds = config.maxDate.getSeconds();\n        }\n        return { hours: hours, minutes: minutes, seconds: seconds };\n    }\n\n    if (typeof Object.assign !== \"function\") {\n        Object.assign = function (target) {\n            var args = [];\n            for (var _i = 1; _i < arguments.length; _i++) {\n                args[_i - 1] = arguments[_i];\n            }\n            if (!target) {\n                throw TypeError(\"Cannot convert undefined or null to object\");\n            }\n            var _loop_1 = function (source) {\n                if (source) {\n                    Object.keys(source).forEach(function (key) { return (target[key] = source[key]); });\n                }\n            };\n            for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {\n                var source = args_1[_a];\n                _loop_1(source);\n            }\n            return target;\n        };\n    }\n\n    var DEBOUNCED_CHANGE_MS = 300;\n    function FlatpickrInstance(element, instanceConfig) {\n        var self = {\n            config: __assign(__assign({}, defaults), flatpickr.defaultConfig),\n            l10n: english,\n        };\n        self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });\n        self._handlers = [];\n        self.pluginElements = [];\n        self.loadedPlugins = [];\n        self._bind = bind;\n        self._setHoursFromDate = setHoursFromDate;\n        self._positionCalendar = positionCalendar;\n        self.changeMonth = changeMonth;\n        self.changeYear = changeYear;\n        self.clear = clear;\n        self.close = close;\n        self.onMouseOver = onMouseOver;\n        self._createElement = createElement;\n        self.createDay = createDay;\n        self.destroy = destroy;\n        self.isEnabled = isEnabled;\n        self.jumpToDate = jumpToDate;\n        self.updateValue = updateValue;\n        self.open = open;\n        self.redraw = redraw;\n        self.set = set;\n        self.setDate = setDate;\n        self.toggle = toggle;\n        function setupHelperFunctions() {\n            self.utils = {\n                getDaysInMonth: function (month, yr) {\n                    if (month === void 0) { month = self.currentMonth; }\n                    if (yr === void 0) { yr = self.currentYear; }\n                    if (month === 1 && ((yr % 4 === 0 && yr % 100 !== 0) || yr % 400 === 0))\n                        return 29;\n                    return self.l10n.daysInMonth[month];\n                },\n            };\n        }\n        function init() {\n            self.element = self.input = element;\n            self.isOpen = false;\n            parseConfig();\n            setupLocale();\n            setupInputs();\n            setupDates();\n            setupHelperFunctions();\n            if (!self.isMobile)\n                build();\n            bindEvents();\n            if (self.selectedDates.length || self.config.noCalendar) {\n                if (self.config.enableTime) {\n                    setHoursFromDate(self.config.noCalendar ? self.latestSelectedDateObj : undefined);\n                }\n                updateValue(false);\n            }\n            setCalendarWidth();\n            var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n            /* TODO: investigate this further\n        \n              Currently, there is weird positioning behavior in safari causing pages\n              to scroll up. https://github.com/chmln/flatpickr/issues/563\n        \n              However, most browsers are not Safari and positioning is expensive when used\n              in scale. https://github.com/chmln/flatpickr/issues/1096\n            */\n            if (!self.isMobile && isSafari) {\n                positionCalendar();\n            }\n            triggerEvent(\"onReady\");\n        }\n        function getClosestActiveElement() {\n            var _a;\n            return ((_a = self.calendarContainer) === null || _a === void 0 ? void 0 : _a.getRootNode()).activeElement || document.activeElement;\n        }\n        function bindToInstance(fn) {\n            return fn.bind(self);\n        }\n        function setCalendarWidth() {\n            var config = self.config;\n            if (config.weekNumbers === false && config.showMonths === 1) {\n                return;\n            }\n            else if (config.noCalendar !== true) {\n                window.requestAnimationFrame(function () {\n                    if (self.calendarContainer !== undefined) {\n                        self.calendarContainer.style.visibility = \"hidden\";\n                        self.calendarContainer.style.display = \"block\";\n                    }\n                    if (self.daysContainer !== undefined) {\n                        var daysWidth = (self.days.offsetWidth + 1) * config.showMonths;\n                        self.daysContainer.style.width = daysWidth + \"px\";\n                        self.calendarContainer.style.width =\n                            daysWidth +\n                                (self.weekWrapper !== undefined\n                                    ? self.weekWrapper.offsetWidth\n                                    : 0) +\n                                \"px\";\n                        self.calendarContainer.style.removeProperty(\"visibility\");\n                        self.calendarContainer.style.removeProperty(\"display\");\n                    }\n                });\n            }\n        }\n        /**\n         * The handler for all events targeting the time inputs\n         */\n        function updateTime(e) {\n            if (self.selectedDates.length === 0) {\n                var defaultDate = self.config.minDate === undefined ||\n                    compareDates(new Date(), self.config.minDate) >= 0\n                    ? new Date()\n                    : new Date(self.config.minDate.getTime());\n                var defaults = getDefaultHours(self.config);\n                defaultDate.setHours(defaults.hours, defaults.minutes, defaults.seconds, defaultDate.getMilliseconds());\n                self.selectedDates = [defaultDate];\n                self.latestSelectedDateObj = defaultDate;\n            }\n            if (e !== undefined && e.type !== \"blur\") {\n                timeWrapper(e);\n            }\n            var prevValue = self._input.value;\n            setHoursFromInputs();\n            updateValue();\n            if (self._input.value !== prevValue) {\n                self._debouncedChange();\n            }\n        }\n        function ampm2military(hour, amPM) {\n            return (hour % 12) + 12 * int(amPM === self.l10n.amPM[1]);\n        }\n        function military2ampm(hour) {\n            switch (hour % 24) {\n                case 0:\n                case 12:\n                    return 12;\n                default:\n                    return hour % 12;\n            }\n        }\n        /**\n         * Syncs the selected date object time with user's time input\n         */\n        function setHoursFromInputs() {\n            if (self.hourElement === undefined || self.minuteElement === undefined)\n                return;\n            var hours = (parseInt(self.hourElement.value.slice(-2), 10) || 0) % 24, minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60, seconds = self.secondElement !== undefined\n                ? (parseInt(self.secondElement.value, 10) || 0) % 60\n                : 0;\n            if (self.amPM !== undefined) {\n                hours = ampm2military(hours, self.amPM.textContent);\n            }\n            var limitMinHours = self.config.minTime !== undefined ||\n                (self.config.minDate &&\n                    self.minDateHasTime &&\n                    self.latestSelectedDateObj &&\n                    compareDates(self.latestSelectedDateObj, self.config.minDate, true) ===\n                        0);\n            var limitMaxHours = self.config.maxTime !== undefined ||\n                (self.config.maxDate &&\n                    self.maxDateHasTime &&\n                    self.latestSelectedDateObj &&\n                    compareDates(self.latestSelectedDateObj, self.config.maxDate, true) ===\n                        0);\n            if (self.config.maxTime !== undefined &&\n                self.config.minTime !== undefined &&\n                self.config.minTime > self.config.maxTime) {\n                var minBound = calculateSecondsSinceMidnight(self.config.minTime.getHours(), self.config.minTime.getMinutes(), self.config.minTime.getSeconds());\n                var maxBound = calculateSecondsSinceMidnight(self.config.maxTime.getHours(), self.config.maxTime.getMinutes(), self.config.maxTime.getSeconds());\n                var currentTime = calculateSecondsSinceMidnight(hours, minutes, seconds);\n                if (currentTime > maxBound && currentTime < minBound) {\n                    var result = parseSeconds(minBound);\n                    hours = result[0];\n                    minutes = result[1];\n                    seconds = result[2];\n                }\n            }\n            else {\n                if (limitMaxHours) {\n                    var maxTime = self.config.maxTime !== undefined\n                        ? self.config.maxTime\n                        : self.config.maxDate;\n                    hours = Math.min(hours, maxTime.getHours());\n                    if (hours === maxTime.getHours())\n                        minutes = Math.min(minutes, maxTime.getMinutes());\n                    if (minutes === maxTime.getMinutes())\n                        seconds = Math.min(seconds, maxTime.getSeconds());\n                }\n                if (limitMinHours) {\n                    var minTime = self.config.minTime !== undefined\n                        ? self.config.minTime\n                        : self.config.minDate;\n                    hours = Math.max(hours, minTime.getHours());\n                    if (hours === minTime.getHours() && minutes < minTime.getMinutes())\n                        minutes = minTime.getMinutes();\n                    if (minutes === minTime.getMinutes())\n                        seconds = Math.max(seconds, minTime.getSeconds());\n                }\n            }\n            setHours(hours, minutes, seconds);\n        }\n        /**\n         * Syncs time input values with a date\n         */\n        function setHoursFromDate(dateObj) {\n            var date = dateObj || self.latestSelectedDateObj;\n            if (date && date instanceof Date) {\n                setHours(date.getHours(), date.getMinutes(), date.getSeconds());\n            }\n        }\n        /**\n         * Sets the hours, minutes, and optionally seconds\n         * of the latest selected date object and the\n         * corresponding time inputs\n         * @param {Number} hours the hour. whether its military\n         *                 or am-pm gets inferred from config\n         * @param {Number} minutes the minutes\n         * @param {Number} seconds the seconds (optional)\n         */\n        function setHours(hours, minutes, seconds) {\n            if (self.latestSelectedDateObj !== undefined) {\n                self.latestSelectedDateObj.setHours(hours % 24, minutes, seconds || 0, 0);\n            }\n            if (!self.hourElement || !self.minuteElement || self.isMobile)\n                return;\n            self.hourElement.value = pad(!self.config.time_24hr\n                ? ((12 + hours) % 12) + 12 * int(hours % 12 === 0)\n                : hours);\n            self.minuteElement.value = pad(minutes);\n            if (self.amPM !== undefined)\n                self.amPM.textContent = self.l10n.amPM[int(hours >= 12)];\n            if (self.secondElement !== undefined)\n                self.secondElement.value = pad(seconds);\n        }\n        /**\n         * Handles the year input and incrementing events\n         * @param {Event} event the keyup or increment event\n         */\n        function onYearInput(event) {\n            var eventTarget = getEventTarget(event);\n            var year = parseInt(eventTarget.value) + (event.delta || 0);\n            if (year / 1000 > 1 ||\n                (event.key === \"Enter\" && !/[^\\d]/.test(year.toString()))) {\n                changeYear(year);\n            }\n        }\n        /**\n         * Essentially addEventListener + tracking\n         * @param {Element} element the element to addEventListener to\n         * @param {String} event the event name\n         * @param {Function} handler the event handler\n         */\n        function bind(element, event, handler, options) {\n            if (event instanceof Array)\n                return event.forEach(function (ev) { return bind(element, ev, handler, options); });\n            if (element instanceof Array)\n                return element.forEach(function (el) { return bind(el, event, handler, options); });\n            element.addEventListener(event, handler, options);\n            self._handlers.push({\n                remove: function () { return element.removeEventListener(event, handler, options); },\n            });\n        }\n        function triggerChange() {\n            triggerEvent(\"onChange\");\n        }\n        /**\n         * Adds all the necessary event listeners\n         */\n        function bindEvents() {\n            if (self.config.wrap) {\n                [\"open\", \"close\", \"toggle\", \"clear\"].forEach(function (evt) {\n                    Array.prototype.forEach.call(self.element.querySelectorAll(\"[data-\" + evt + \"]\"), function (el) {\n                        return bind(el, \"click\", self[evt]);\n                    });\n                });\n            }\n            if (self.isMobile) {\n                setupMobile();\n                return;\n            }\n            var debouncedResize = debounce(onResize, 50);\n            self._debouncedChange = debounce(triggerChange, DEBOUNCED_CHANGE_MS);\n            if (self.daysContainer && !/iPhone|iPad|iPod/i.test(navigator.userAgent))\n                bind(self.daysContainer, \"mouseover\", function (e) {\n                    if (self.config.mode === \"range\")\n                        onMouseOver(getEventTarget(e));\n                });\n            bind(self._input, \"keydown\", onKeyDown);\n            if (self.calendarContainer !== undefined) {\n                bind(self.calendarContainer, \"keydown\", onKeyDown);\n            }\n            if (!self.config.inline && !self.config.static)\n                bind(window, \"resize\", debouncedResize);\n            if (window.ontouchstart !== undefined)\n                bind(window.document, \"touchstart\", documentClick);\n            else\n                bind(window.document, \"mousedown\", documentClick);\n            bind(window.document, \"focus\", documentClick, { capture: true });\n            if (self.config.clickOpens === true) {\n                bind(self._input, \"focus\", self.open);\n                bind(self._input, \"click\", self.open);\n            }\n            if (self.daysContainer !== undefined) {\n                bind(self.monthNav, \"click\", onMonthNavClick);\n                bind(self.monthNav, [\"keyup\", \"increment\"], onYearInput);\n                bind(self.daysContainer, \"click\", selectDate);\n            }\n            if (self.timeContainer !== undefined &&\n                self.minuteElement !== undefined &&\n                self.hourElement !== undefined) {\n                var selText = function (e) {\n                    return getEventTarget(e).select();\n                };\n                bind(self.timeContainer, [\"increment\"], updateTime);\n                bind(self.timeContainer, \"blur\", updateTime, { capture: true });\n                bind(self.timeContainer, \"click\", timeIncrement);\n                bind([self.hourElement, self.minuteElement], [\"focus\", \"click\"], selText);\n                if (self.secondElement !== undefined)\n                    bind(self.secondElement, \"focus\", function () { return self.secondElement && self.secondElement.select(); });\n                if (self.amPM !== undefined) {\n                    bind(self.amPM, \"click\", function (e) {\n                        updateTime(e);\n                    });\n                }\n            }\n            if (self.config.allowInput) {\n                bind(self._input, \"blur\", onBlur);\n            }\n        }\n        /**\n         * Set the calendar view to a particular date.\n         * @param {Date} jumpDate the date to set the view to\n         * @param {boolean} triggerChange if change events should be triggered\n         */\n        function jumpToDate(jumpDate, triggerChange) {\n            var jumpTo = jumpDate !== undefined\n                ? self.parseDate(jumpDate)\n                : self.latestSelectedDateObj ||\n                    (self.config.minDate && self.config.minDate > self.now\n                        ? self.config.minDate\n                        : self.config.maxDate && self.config.maxDate < self.now\n                            ? self.config.maxDate\n                            : self.now);\n            var oldYear = self.currentYear;\n            var oldMonth = self.currentMonth;\n            try {\n                if (jumpTo !== undefined) {\n                    self.currentYear = jumpTo.getFullYear();\n                    self.currentMonth = jumpTo.getMonth();\n                }\n            }\n            catch (e) {\n                /* istanbul ignore next */\n                e.message = \"Invalid date supplied: \" + jumpTo;\n                self.config.errorHandler(e);\n            }\n            if (triggerChange && self.currentYear !== oldYear) {\n                triggerEvent(\"onYearChange\");\n                buildMonthSwitch();\n            }\n            if (triggerChange &&\n                (self.currentYear !== oldYear || self.currentMonth !== oldMonth)) {\n                triggerEvent(\"onMonthChange\");\n            }\n            self.redraw();\n        }\n        /**\n         * The up/down arrow handler for time inputs\n         * @param {Event} e the click event\n         */\n        function timeIncrement(e) {\n            var eventTarget = getEventTarget(e);\n            if (~eventTarget.className.indexOf(\"arrow\"))\n                incrementNumInput(e, eventTarget.classList.contains(\"arrowUp\") ? 1 : -1);\n        }\n        /**\n         * Increments/decrements the value of input associ-\n         * ated with the up/down arrow by dispatching an\n         * \"increment\" event on the input.\n         *\n         * @param {Event} e the click event\n         * @param {Number} delta the diff (usually 1 or -1)\n         * @param {Element} inputElem the input element\n         */\n        function incrementNumInput(e, delta, inputElem) {\n            var target = e && getEventTarget(e);\n            var input = inputElem ||\n                (target && target.parentNode && target.parentNode.firstChild);\n            var event = createEvent(\"increment\");\n            event.delta = delta;\n            input && input.dispatchEvent(event);\n        }\n        function build() {\n            var fragment = window.document.createDocumentFragment();\n            self.calendarContainer = createElement(\"div\", \"flatpickr-calendar\");\n            self.calendarContainer.tabIndex = -1;\n            if (!self.config.noCalendar) {\n                fragment.appendChild(buildMonthNav());\n                self.innerContainer = createElement(\"div\", \"flatpickr-innerContainer\");\n                if (self.config.weekNumbers) {\n                    var _a = buildWeeks(), weekWrapper = _a.weekWrapper, weekNumbers = _a.weekNumbers;\n                    self.innerContainer.appendChild(weekWrapper);\n                    self.weekNumbers = weekNumbers;\n                    self.weekWrapper = weekWrapper;\n                }\n                self.rContainer = createElement(\"div\", \"flatpickr-rContainer\");\n                self.rContainer.appendChild(buildWeekdays());\n                if (!self.daysContainer) {\n                    self.daysContainer = createElement(\"div\", \"flatpickr-days\");\n                    self.daysContainer.tabIndex = -1;\n                }\n                buildDays();\n                self.rContainer.appendChild(self.daysContainer);\n                self.innerContainer.appendChild(self.rContainer);\n                fragment.appendChild(self.innerContainer);\n            }\n            if (self.config.enableTime) {\n                fragment.appendChild(buildTime());\n            }\n            toggleClass(self.calendarContainer, \"rangeMode\", self.config.mode === \"range\");\n            toggleClass(self.calendarContainer, \"animate\", self.config.animate === true);\n            toggleClass(self.calendarContainer, \"multiMonth\", self.config.showMonths > 1);\n            self.calendarContainer.appendChild(fragment);\n            var customAppend = self.config.appendTo !== undefined &&\n                self.config.appendTo.nodeType !== undefined;\n            if (self.config.inline || self.config.static) {\n                self.calendarContainer.classList.add(self.config.inline ? \"inline\" : \"static\");\n                if (self.config.inline) {\n                    if (!customAppend && self.element.parentNode)\n                        self.element.parentNode.insertBefore(self.calendarContainer, self._input.nextSibling);\n                    else if (self.config.appendTo !== undefined)\n                        self.config.appendTo.appendChild(self.calendarContainer);\n                }\n                if (self.config.static) {\n                    var wrapper = createElement(\"div\", \"flatpickr-wrapper\");\n                    if (self.element.parentNode)\n                        self.element.parentNode.insertBefore(wrapper, self.element);\n                    wrapper.appendChild(self.element);\n                    if (self.altInput)\n                        wrapper.appendChild(self.altInput);\n                    wrapper.appendChild(self.calendarContainer);\n                }\n            }\n            if (!self.config.static && !self.config.inline)\n                (self.config.appendTo !== undefined\n                    ? self.config.appendTo\n                    : window.document.body).appendChild(self.calendarContainer);\n        }\n        function createDay(className, date, dayNumber, i) {\n            var dateIsEnabled = isEnabled(date, true), dayElement = createElement(\"span\", className, date.getDate().toString());\n            dayElement.dateObj = date;\n            dayElement.$i = i;\n            dayElement.setAttribute(\"aria-label\", self.formatDate(date, self.config.ariaDateFormat));\n            if (className.indexOf(\"hidden\") === -1 &&\n                compareDates(date, self.now) === 0) {\n                self.todayDateElem = dayElement;\n                dayElement.classList.add(\"today\");\n                dayElement.setAttribute(\"aria-current\", \"date\");\n            }\n            if (dateIsEnabled) {\n                dayElement.tabIndex = -1;\n                if (isDateSelected(date)) {\n                    dayElement.classList.add(\"selected\");\n                    self.selectedDateElem = dayElement;\n                    if (self.config.mode === \"range\") {\n                        toggleClass(dayElement, \"startRange\", self.selectedDates[0] &&\n                            compareDates(date, self.selectedDates[0], true) === 0);\n                        toggleClass(dayElement, \"endRange\", self.selectedDates[1] &&\n                            compareDates(date, self.selectedDates[1], true) === 0);\n                        if (className === \"nextMonthDay\")\n                            dayElement.classList.add(\"inRange\");\n                    }\n                }\n            }\n            else {\n                dayElement.classList.add(\"flatpickr-disabled\");\n            }\n            if (self.config.mode === \"range\") {\n                if (isDateInRange(date) && !isDateSelected(date))\n                    dayElement.classList.add(\"inRange\");\n            }\n            if (self.weekNumbers &&\n                self.config.showMonths === 1 &&\n                className !== \"prevMonthDay\" &&\n                dayNumber % 7 === 1) {\n                self.weekNumbers.insertAdjacentHTML(\"beforeend\", \"<span class='flatpickr-day'>\" + self.config.getWeek(date) + \"</span>\");\n            }\n            triggerEvent(\"onDayCreate\", dayElement);\n            return dayElement;\n        }\n        function focusOnDayElem(targetNode) {\n            targetNode.focus();\n            if (self.config.mode === \"range\")\n                onMouseOver(targetNode);\n        }\n        function getFirstAvailableDay(delta) {\n            var startMonth = delta > 0 ? 0 : self.config.showMonths - 1;\n            var endMonth = delta > 0 ? self.config.showMonths : -1;\n            for (var m = startMonth; m != endMonth; m += delta) {\n                var month = self.daysContainer.children[m];\n                var startIndex = delta > 0 ? 0 : month.children.length - 1;\n                var endIndex = delta > 0 ? month.children.length : -1;\n                for (var i = startIndex; i != endIndex; i += delta) {\n                    var c = month.children[i];\n                    if (c.className.indexOf(\"hidden\") === -1 && isEnabled(c.dateObj))\n                        return c;\n                }\n            }\n            return undefined;\n        }\n        function getNextAvailableDay(current, delta) {\n            var givenMonth = current.className.indexOf(\"Month\") === -1\n                ? current.dateObj.getMonth()\n                : self.currentMonth;\n            var endMonth = delta > 0 ? self.config.showMonths : -1;\n            var loopDelta = delta > 0 ? 1 : -1;\n            for (var m = givenMonth - self.currentMonth; m != endMonth; m += loopDelta) {\n                var month = self.daysContainer.children[m];\n                var startIndex = givenMonth - self.currentMonth === m\n                    ? current.$i + delta\n                    : delta < 0\n                        ? month.children.length - 1\n                        : 0;\n                var numMonthDays = month.children.length;\n                for (var i = startIndex; i >= 0 && i < numMonthDays && i != (delta > 0 ? numMonthDays : -1); i += loopDelta) {\n                    var c = month.children[i];\n                    if (c.className.indexOf(\"hidden\") === -1 &&\n                        isEnabled(c.dateObj) &&\n                        Math.abs(current.$i - i) >= Math.abs(delta))\n                        return focusOnDayElem(c);\n                }\n            }\n            self.changeMonth(loopDelta);\n            focusOnDay(getFirstAvailableDay(loopDelta), 0);\n            return undefined;\n        }\n        function focusOnDay(current, offset) {\n            var activeElement = getClosestActiveElement();\n            var dayFocused = isInView(activeElement || document.body);\n            var startElem = current !== undefined\n                ? current\n                : dayFocused\n                    ? activeElement\n                    : self.selectedDateElem !== undefined && isInView(self.selectedDateElem)\n                        ? self.selectedDateElem\n                        : self.todayDateElem !== undefined && isInView(self.todayDateElem)\n                            ? self.todayDateElem\n                            : getFirstAvailableDay(offset > 0 ? 1 : -1);\n            if (startElem === undefined) {\n                self._input.focus();\n            }\n            else if (!dayFocused) {\n                focusOnDayElem(startElem);\n            }\n            else {\n                getNextAvailableDay(startElem, offset);\n            }\n        }\n        function buildMonthDays(year, month) {\n            var firstOfMonth = (new Date(year, month, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7;\n            var prevMonthDays = self.utils.getDaysInMonth((month - 1 + 12) % 12, year);\n            var daysInMonth = self.utils.getDaysInMonth(month, year), days = window.document.createDocumentFragment(), isMultiMonth = self.config.showMonths > 1, prevMonthDayClass = isMultiMonth ? \"prevMonthDay hidden\" : \"prevMonthDay\", nextMonthDayClass = isMultiMonth ? \"nextMonthDay hidden\" : \"nextMonthDay\";\n            var dayNumber = prevMonthDays + 1 - firstOfMonth, dayIndex = 0;\n            // prepend days from the ending of previous month\n            for (; dayNumber <= prevMonthDays; dayNumber++, dayIndex++) {\n                days.appendChild(createDay(\"flatpickr-day \" + prevMonthDayClass, new Date(year, month - 1, dayNumber), dayNumber, dayIndex));\n            }\n            // Start at 1 since there is no 0th day\n            for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) {\n                days.appendChild(createDay(\"flatpickr-day\", new Date(year, month, dayNumber), dayNumber, dayIndex));\n            }\n            // append days from the next month\n            for (var dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth &&\n                (self.config.showMonths === 1 || dayIndex % 7 !== 0); dayNum++, dayIndex++) {\n                days.appendChild(createDay(\"flatpickr-day \" + nextMonthDayClass, new Date(year, month + 1, dayNum % daysInMonth), dayNum, dayIndex));\n            }\n            //updateNavigationCurrentMonth();\n            var dayContainer = createElement(\"div\", \"dayContainer\");\n            dayContainer.appendChild(days);\n            return dayContainer;\n        }\n        function buildDays() {\n            if (self.daysContainer === undefined) {\n                return;\n            }\n            clearNode(self.daysContainer);\n            // TODO: week numbers for each month\n            if (self.weekNumbers)\n                clearNode(self.weekNumbers);\n            var frag = document.createDocumentFragment();\n            for (var i = 0; i < self.config.showMonths; i++) {\n                var d = new Date(self.currentYear, self.currentMonth, 1);\n                d.setMonth(self.currentMonth + i);\n                frag.appendChild(buildMonthDays(d.getFullYear(), d.getMonth()));\n            }\n            self.daysContainer.appendChild(frag);\n            self.days = self.daysContainer.firstChild;\n            if (self.config.mode === \"range\" && self.selectedDates.length === 1) {\n                onMouseOver();\n            }\n        }\n        function buildMonthSwitch() {\n            if (self.config.showMonths > 1 ||\n                self.config.monthSelectorType !== \"dropdown\")\n                return;\n            var shouldBuildMonth = function (month) {\n                if (self.config.minDate !== undefined &&\n                    self.currentYear === self.config.minDate.getFullYear() &&\n                    month < self.config.minDate.getMonth()) {\n                    return false;\n                }\n                return !(self.config.maxDate !== undefined &&\n                    self.currentYear === self.config.maxDate.getFullYear() &&\n                    month > self.config.maxDate.getMonth());\n            };\n            self.monthsDropdownContainer.tabIndex = -1;\n            self.monthsDropdownContainer.innerHTML = \"\";\n            for (var i = 0; i < 12; i++) {\n                if (!shouldBuildMonth(i))\n                    continue;\n                var month = createElement(\"option\", \"flatpickr-monthDropdown-month\");\n                month.value = new Date(self.currentYear, i).getMonth().toString();\n                month.textContent = monthToStr(i, self.config.shorthandCurrentMonth, self.l10n);\n                month.tabIndex = -1;\n                if (self.currentMonth === i) {\n                    month.selected = true;\n                }\n                self.monthsDropdownContainer.appendChild(month);\n            }\n        }\n        function buildMonth() {\n            var container = createElement(\"div\", \"flatpickr-month\");\n            var monthNavFragment = window.document.createDocumentFragment();\n            var monthElement;\n            if (self.config.showMonths > 1 ||\n                self.config.monthSelectorType === \"static\") {\n                monthElement = createElement(\"span\", \"cur-month\");\n            }\n            else {\n                self.monthsDropdownContainer = createElement(\"select\", \"flatpickr-monthDropdown-months\");\n                self.monthsDropdownContainer.setAttribute(\"aria-label\", self.l10n.monthAriaLabel);\n                bind(self.monthsDropdownContainer, \"change\", function (e) {\n                    var target = getEventTarget(e);\n                    var selectedMonth = parseInt(target.value, 10);\n                    self.changeMonth(selectedMonth - self.currentMonth);\n                    triggerEvent(\"onMonthChange\");\n                });\n                buildMonthSwitch();\n                monthElement = self.monthsDropdownContainer;\n            }\n            var yearInput = createNumberInput(\"cur-year\", { tabindex: \"-1\" });\n            var yearElement = yearInput.getElementsByTagName(\"input\")[0];\n            yearElement.setAttribute(\"aria-label\", self.l10n.yearAriaLabel);\n            if (self.config.minDate) {\n                yearElement.setAttribute(\"min\", self.config.minDate.getFullYear().toString());\n            }\n            if (self.config.maxDate) {\n                yearElement.setAttribute(\"max\", self.config.maxDate.getFullYear().toString());\n                yearElement.disabled =\n                    !!self.config.minDate &&\n                        self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();\n            }\n            var currentMonth = createElement(\"div\", \"flatpickr-current-month\");\n            currentMonth.appendChild(monthElement);\n            currentMonth.appendChild(yearInput);\n            monthNavFragment.appendChild(currentMonth);\n            container.appendChild(monthNavFragment);\n            return {\n                container: container,\n                yearElement: yearElement,\n                monthElement: monthElement,\n            };\n        }\n        function buildMonths() {\n            clearNode(self.monthNav);\n            self.monthNav.appendChild(self.prevMonthNav);\n            if (self.config.showMonths) {\n                self.yearElements = [];\n                self.monthElements = [];\n            }\n            for (var m = self.config.showMonths; m--;) {\n                var month = buildMonth();\n                self.yearElements.push(month.yearElement);\n                self.monthElements.push(month.monthElement);\n                self.monthNav.appendChild(month.container);\n            }\n            self.monthNav.appendChild(self.nextMonthNav);\n        }\n        function buildMonthNav() {\n            self.monthNav = createElement(\"div\", \"flatpickr-months\");\n            self.yearElements = [];\n            self.monthElements = [];\n            self.prevMonthNav = createElement(\"span\", \"flatpickr-prev-month\");\n            self.prevMonthNav.innerHTML = self.config.prevArrow;\n            self.nextMonthNav = createElement(\"span\", \"flatpickr-next-month\");\n            self.nextMonthNav.innerHTML = self.config.nextArrow;\n            buildMonths();\n            Object.defineProperty(self, \"_hidePrevMonthArrow\", {\n                get: function () { return self.__hidePrevMonthArrow; },\n                set: function (bool) {\n                    if (self.__hidePrevMonthArrow !== bool) {\n                        toggleClass(self.prevMonthNav, \"flatpickr-disabled\", bool);\n                        self.__hidePrevMonthArrow = bool;\n                    }\n                },\n            });\n            Object.defineProperty(self, \"_hideNextMonthArrow\", {\n                get: function () { return self.__hideNextMonthArrow; },\n                set: function (bool) {\n                    if (self.__hideNextMonthArrow !== bool) {\n                        toggleClass(self.nextMonthNav, \"flatpickr-disabled\", bool);\n                        self.__hideNextMonthArrow = bool;\n                    }\n                },\n            });\n            self.currentYearElement = self.yearElements[0];\n            updateNavigationCurrentMonth();\n            return self.monthNav;\n        }\n        function buildTime() {\n            self.calendarContainer.classList.add(\"hasTime\");\n            if (self.config.noCalendar)\n                self.calendarContainer.classList.add(\"noCalendar\");\n            var defaults = getDefaultHours(self.config);\n            self.timeContainer = createElement(\"div\", \"flatpickr-time\");\n            self.timeContainer.tabIndex = -1;\n            var separator = createElement(\"span\", \"flatpickr-time-separator\", \":\");\n            var hourInput = createNumberInput(\"flatpickr-hour\", {\n                \"aria-label\": self.l10n.hourAriaLabel,\n            });\n            self.hourElement = hourInput.getElementsByTagName(\"input\")[0];\n            var minuteInput = createNumberInput(\"flatpickr-minute\", {\n                \"aria-label\": self.l10n.minuteAriaLabel,\n            });\n            self.minuteElement = minuteInput.getElementsByTagName(\"input\")[0];\n            self.hourElement.tabIndex = self.minuteElement.tabIndex = -1;\n            self.hourElement.value = pad(self.latestSelectedDateObj\n                ? self.latestSelectedDateObj.getHours()\n                : self.config.time_24hr\n                    ? defaults.hours\n                    : military2ampm(defaults.hours));\n            self.minuteElement.value = pad(self.latestSelectedDateObj\n                ? self.latestSelectedDateObj.getMinutes()\n                : defaults.minutes);\n            self.hourElement.setAttribute(\"step\", self.config.hourIncrement.toString());\n            self.minuteElement.setAttribute(\"step\", self.config.minuteIncrement.toString());\n            self.hourElement.setAttribute(\"min\", self.config.time_24hr ? \"0\" : \"1\");\n            self.hourElement.setAttribute(\"max\", self.config.time_24hr ? \"23\" : \"12\");\n            self.hourElement.setAttribute(\"maxlength\", \"2\");\n            self.minuteElement.setAttribute(\"min\", \"0\");\n            self.minuteElement.setAttribute(\"max\", \"59\");\n            self.minuteElement.setAttribute(\"maxlength\", \"2\");\n            self.timeContainer.appendChild(hourInput);\n            self.timeContainer.appendChild(separator);\n            self.timeContainer.appendChild(minuteInput);\n            if (self.config.time_24hr)\n                self.timeContainer.classList.add(\"time24hr\");\n            if (self.config.enableSeconds) {\n                self.timeContainer.classList.add(\"hasSeconds\");\n                var secondInput = createNumberInput(\"flatpickr-second\");\n                self.secondElement = secondInput.getElementsByTagName(\"input\")[0];\n                self.secondElement.value = pad(self.latestSelectedDateObj\n                    ? self.latestSelectedDateObj.getSeconds()\n                    : defaults.seconds);\n                self.secondElement.setAttribute(\"step\", self.minuteElement.getAttribute(\"step\"));\n                self.secondElement.setAttribute(\"min\", \"0\");\n                self.secondElement.setAttribute(\"max\", \"59\");\n                self.secondElement.setAttribute(\"maxlength\", \"2\");\n                self.timeContainer.appendChild(createElement(\"span\", \"flatpickr-time-separator\", \":\"));\n                self.timeContainer.appendChild(secondInput);\n            }\n            if (!self.config.time_24hr) {\n                // add self.amPM if appropriate\n                self.amPM = createElement(\"span\", \"flatpickr-am-pm\", self.l10n.amPM[int((self.latestSelectedDateObj\n                    ? self.hourElement.value\n                    : self.config.defaultHour) > 11)]);\n                self.amPM.title = self.l10n.toggleTitle;\n                self.amPM.tabIndex = -1;\n                self.timeContainer.appendChild(self.amPM);\n            }\n            return self.timeContainer;\n        }\n        function buildWeekdays() {\n            if (!self.weekdayContainer)\n                self.weekdayContainer = createElement(\"div\", \"flatpickr-weekdays\");\n            else\n                clearNode(self.weekdayContainer);\n            for (var i = self.config.showMonths; i--;) {\n                var container = createElement(\"div\", \"flatpickr-weekdaycontainer\");\n                self.weekdayContainer.appendChild(container);\n            }\n            updateWeekdays();\n            return self.weekdayContainer;\n        }\n        function updateWeekdays() {\n            if (!self.weekdayContainer) {\n                return;\n            }\n            var firstDayOfWeek = self.l10n.firstDayOfWeek;\n            var weekdays = __spreadArrays(self.l10n.weekdays.shorthand);\n            if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {\n                weekdays = __spreadArrays(weekdays.splice(firstDayOfWeek, weekdays.length), weekdays.splice(0, firstDayOfWeek));\n            }\n            for (var i = self.config.showMonths; i--;) {\n                self.weekdayContainer.children[i].innerHTML = \"\\n      <span class='flatpickr-weekday'>\\n        \" + weekdays.join(\"</span><span class='flatpickr-weekday'>\") + \"\\n      </span>\\n      \";\n            }\n        }\n        /* istanbul ignore next */\n        function buildWeeks() {\n            self.calendarContainer.classList.add(\"hasWeeks\");\n            var weekWrapper = createElement(\"div\", \"flatpickr-weekwrapper\");\n            weekWrapper.appendChild(createElement(\"span\", \"flatpickr-weekday\", self.l10n.weekAbbreviation));\n            var weekNumbers = createElement(\"div\", \"flatpickr-weeks\");\n            weekWrapper.appendChild(weekNumbers);\n            return {\n                weekWrapper: weekWrapper,\n                weekNumbers: weekNumbers,\n            };\n        }\n        function changeMonth(value, isOffset) {\n            if (isOffset === void 0) { isOffset = true; }\n            var delta = isOffset ? value : value - self.currentMonth;\n            if ((delta < 0 && self._hidePrevMonthArrow === true) ||\n                (delta > 0 && self._hideNextMonthArrow === true))\n                return;\n            self.currentMonth += delta;\n            if (self.currentMonth < 0 || self.currentMonth > 11) {\n                self.currentYear += self.currentMonth > 11 ? 1 : -1;\n                self.currentMonth = (self.currentMonth + 12) % 12;\n                triggerEvent(\"onYearChange\");\n                buildMonthSwitch();\n            }\n            buildDays();\n            triggerEvent(\"onMonthChange\");\n            updateNavigationCurrentMonth();\n        }\n        function clear(triggerChangeEvent, toInitial) {\n            if (triggerChangeEvent === void 0) { triggerChangeEvent = true; }\n            if (toInitial === void 0) { toInitial = true; }\n            self.input.value = \"\";\n            if (self.altInput !== undefined)\n                self.altInput.value = \"\";\n            if (self.mobileInput !== undefined)\n                self.mobileInput.value = \"\";\n            self.selectedDates = [];\n            self.latestSelectedDateObj = undefined;\n            if (toInitial === true) {\n                self.currentYear = self._initialDate.getFullYear();\n                self.currentMonth = self._initialDate.getMonth();\n            }\n            if (self.config.enableTime === true) {\n                var _a = getDefaultHours(self.config), hours = _a.hours, minutes = _a.minutes, seconds = _a.seconds;\n                setHours(hours, minutes, seconds);\n            }\n            self.redraw();\n            if (triggerChangeEvent)\n                // triggerChangeEvent is true (default) or an Event\n                triggerEvent(\"onChange\");\n        }\n        function close() {\n            self.isOpen = false;\n            if (!self.isMobile) {\n                if (self.calendarContainer !== undefined) {\n                    self.calendarContainer.classList.remove(\"open\");\n                }\n                if (self._input !== undefined) {\n                    self._input.classList.remove(\"active\");\n                }\n            }\n            triggerEvent(\"onClose\");\n        }\n        function destroy() {\n            if (self.config !== undefined)\n                triggerEvent(\"onDestroy\");\n            for (var i = self._handlers.length; i--;) {\n                self._handlers[i].remove();\n            }\n            self._handlers = [];\n            if (self.mobileInput) {\n                if (self.mobileInput.parentNode)\n                    self.mobileInput.parentNode.removeChild(self.mobileInput);\n                self.mobileInput = undefined;\n            }\n            else if (self.calendarContainer && self.calendarContainer.parentNode) {\n                if (self.config.static && self.calendarContainer.parentNode) {\n                    var wrapper = self.calendarContainer.parentNode;\n                    wrapper.lastChild && wrapper.removeChild(wrapper.lastChild);\n                    if (wrapper.parentNode) {\n                        while (wrapper.firstChild)\n                            wrapper.parentNode.insertBefore(wrapper.firstChild, wrapper);\n                        wrapper.parentNode.removeChild(wrapper);\n                    }\n                }\n                else\n                    self.calendarContainer.parentNode.removeChild(self.calendarContainer);\n            }\n            if (self.altInput) {\n                self.input.type = \"text\";\n                if (self.altInput.parentNode)\n                    self.altInput.parentNode.removeChild(self.altInput);\n                delete self.altInput;\n            }\n            if (self.input) {\n                self.input.type = self.input._type;\n                self.input.classList.remove(\"flatpickr-input\");\n                self.input.removeAttribute(\"readonly\");\n            }\n            [\n                \"_showTimeInput\",\n                \"latestSelectedDateObj\",\n                \"_hideNextMonthArrow\",\n                \"_hidePrevMonthArrow\",\n                \"__hideNextMonthArrow\",\n                \"__hidePrevMonthArrow\",\n                \"isMobile\",\n                \"isOpen\",\n                \"selectedDateElem\",\n                \"minDateHasTime\",\n                \"maxDateHasTime\",\n                \"days\",\n                \"daysContainer\",\n                \"_input\",\n                \"_positionElement\",\n                \"innerContainer\",\n                \"rContainer\",\n                \"monthNav\",\n                \"todayDateElem\",\n                \"calendarContainer\",\n                \"weekdayContainer\",\n                \"prevMonthNav\",\n                \"nextMonthNav\",\n                \"monthsDropdownContainer\",\n                \"currentMonthElement\",\n                \"currentYearElement\",\n                \"navigationCurrentMonth\",\n                \"selectedDateElem\",\n                \"config\",\n            ].forEach(function (k) {\n                try {\n                    delete self[k];\n                }\n                catch (_) { }\n            });\n        }\n        function isCalendarElem(elem) {\n            return self.calendarContainer.contains(elem);\n        }\n        function documentClick(e) {\n            if (self.isOpen && !self.config.inline) {\n                var eventTarget_1 = getEventTarget(e);\n                var isCalendarElement = isCalendarElem(eventTarget_1);\n                var isInput = eventTarget_1 === self.input ||\n                    eventTarget_1 === self.altInput ||\n                    self.element.contains(eventTarget_1) ||\n                    // web components\n                    // e.path is not present in all browsers. circumventing typechecks\n                    (e.path &&\n                        e.path.indexOf &&\n                        (~e.path.indexOf(self.input) ||\n                            ~e.path.indexOf(self.altInput)));\n                var lostFocus = !isInput &&\n                    !isCalendarElement &&\n                    !isCalendarElem(e.relatedTarget);\n                var isIgnored = !self.config.ignoredFocusElements.some(function (elem) {\n                    return elem.contains(eventTarget_1);\n                });\n                if (lostFocus && isIgnored) {\n                    if (self.config.allowInput) {\n                        self.setDate(self._input.value, false, self.config.altInput\n                            ? self.config.altFormat\n                            : self.config.dateFormat);\n                    }\n                    if (self.timeContainer !== undefined &&\n                        self.minuteElement !== undefined &&\n                        self.hourElement !== undefined &&\n                        self.input.value !== \"\" &&\n                        self.input.value !== undefined) {\n                        updateTime();\n                    }\n                    self.close();\n                    if (self.config &&\n                        self.config.mode === \"range\" &&\n                        self.selectedDates.length === 1)\n                        self.clear(false);\n                }\n            }\n        }\n        function changeYear(newYear) {\n            if (!newYear ||\n                (self.config.minDate && newYear < self.config.minDate.getFullYear()) ||\n                (self.config.maxDate && newYear > self.config.maxDate.getFullYear()))\n                return;\n            var newYearNum = newYear, isNewYear = self.currentYear !== newYearNum;\n            self.currentYear = newYearNum || self.currentYear;\n            if (self.config.maxDate &&\n                self.currentYear === self.config.maxDate.getFullYear()) {\n                self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);\n            }\n            else if (self.config.minDate &&\n                self.currentYear === self.config.minDate.getFullYear()) {\n                self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);\n            }\n            if (isNewYear) {\n                self.redraw();\n                triggerEvent(\"onYearChange\");\n                buildMonthSwitch();\n            }\n        }\n        function isEnabled(date, timeless) {\n            var _a;\n            if (timeless === void 0) { timeless = true; }\n            var dateToCheck = self.parseDate(date, undefined, timeless); // timeless\n            if ((self.config.minDate &&\n                dateToCheck &&\n                compareDates(dateToCheck, self.config.minDate, timeless !== undefined ? timeless : !self.minDateHasTime) < 0) ||\n                (self.config.maxDate &&\n                    dateToCheck &&\n                    compareDates(dateToCheck, self.config.maxDate, timeless !== undefined ? timeless : !self.maxDateHasTime) > 0))\n                return false;\n            if (!self.config.enable && self.config.disable.length === 0)\n                return true;\n            if (dateToCheck === undefined)\n                return false;\n            var bool = !!self.config.enable, array = (_a = self.config.enable) !== null && _a !== void 0 ? _a : self.config.disable;\n            for (var i = 0, d = void 0; i < array.length; i++) {\n                d = array[i];\n                if (typeof d === \"function\" &&\n                    d(dateToCheck) // disabled by function\n                )\n                    return bool;\n                else if (d instanceof Date &&\n                    dateToCheck !== undefined &&\n                    d.getTime() === dateToCheck.getTime())\n                    // disabled by date\n                    return bool;\n                else if (typeof d === \"string\") {\n                    // disabled by date string\n                    var parsed = self.parseDate(d, undefined, true);\n                    return parsed && parsed.getTime() === dateToCheck.getTime()\n                        ? bool\n                        : !bool;\n                }\n                else if (\n                // disabled by range\n                typeof d === \"object\" &&\n                    dateToCheck !== undefined &&\n                    d.from &&\n                    d.to &&\n                    dateToCheck.getTime() >= d.from.getTime() &&\n                    dateToCheck.getTime() <= d.to.getTime())\n                    return bool;\n            }\n            return !bool;\n        }\n        function isInView(elem) {\n            if (self.daysContainer !== undefined)\n                return (elem.className.indexOf(\"hidden\") === -1 &&\n                    elem.className.indexOf(\"flatpickr-disabled\") === -1 &&\n                    self.daysContainer.contains(elem));\n            return false;\n        }\n        function onBlur(e) {\n            var isInput = e.target === self._input;\n            if (isInput &&\n                (self.selectedDates.length > 0 || self._input.value.length > 0) &&\n                !(e.relatedTarget && isCalendarElem(e.relatedTarget))) {\n                self.setDate(self._input.value, true, e.target === self.altInput\n                    ? self.config.altFormat\n                    : self.config.dateFormat);\n            }\n        }\n        function onKeyDown(e) {\n            // e.key                      e.keyCode\n            // \"Backspace\"                        8\n            // \"Tab\"                              9\n            // \"Enter\"                           13\n            // \"Escape\"     (IE \"Esc\")           27\n            // \"ArrowLeft\"  (IE \"Left\")          37\n            // \"ArrowUp\"    (IE \"Up\")            38\n            // \"ArrowRight\" (IE \"Right\")         39\n            // \"ArrowDown\"  (IE \"Down\")          40\n            // \"Delete\"     (IE \"Del\")           46\n            var eventTarget = getEventTarget(e);\n            var isInput = self.config.wrap\n                ? element.contains(eventTarget)\n                : eventTarget === self._input;\n            var allowInput = self.config.allowInput;\n            var allowKeydown = self.isOpen && (!allowInput || !isInput);\n            var allowInlineKeydown = self.config.inline && isInput && !allowInput;\n            if (e.keyCode === 13 && isInput) {\n                if (allowInput) {\n                    self.setDate(self._input.value, true, eventTarget === self.altInput\n                        ? self.config.altFormat\n                        : self.config.dateFormat);\n                    self.close();\n                    return eventTarget.blur();\n                }\n                else {\n                    self.open();\n                }\n            }\n            else if (isCalendarElem(eventTarget) ||\n                allowKeydown ||\n                allowInlineKeydown) {\n                var isTimeObj = !!self.timeContainer &&\n                    self.timeContainer.contains(eventTarget);\n                switch (e.keyCode) {\n                    case 13:\n                        if (isTimeObj) {\n                            e.preventDefault();\n                            updateTime();\n                            focusAndClose();\n                        }\n                        else\n                            selectDate(e);\n                        break;\n                    case 27: // escape\n                        e.preventDefault();\n                        focusAndClose();\n                        break;\n                    case 8:\n                    case 46:\n                        if (isInput && !self.config.allowInput) {\n                            e.preventDefault();\n                            self.clear();\n                        }\n                        break;\n                    case 37:\n                    case 39:\n                        if (!isTimeObj && !isInput) {\n                            e.preventDefault();\n                            var activeElement = getClosestActiveElement();\n                            if (self.daysContainer !== undefined &&\n                                (allowInput === false ||\n                                    (activeElement && isInView(activeElement)))) {\n                                var delta_1 = e.keyCode === 39 ? 1 : -1;\n                                if (!e.ctrlKey)\n                                    focusOnDay(undefined, delta_1);\n                                else {\n                                    e.stopPropagation();\n                                    changeMonth(delta_1);\n                                    focusOnDay(getFirstAvailableDay(1), 0);\n                                }\n                            }\n                        }\n                        else if (self.hourElement)\n                            self.hourElement.focus();\n                        break;\n                    case 38:\n                    case 40:\n                        e.preventDefault();\n                        var delta = e.keyCode === 40 ? 1 : -1;\n                        if ((self.daysContainer &&\n                            eventTarget.$i !== undefined) ||\n                            eventTarget === self.input ||\n                            eventTarget === self.altInput) {\n                            if (e.ctrlKey) {\n                                e.stopPropagation();\n                                changeYear(self.currentYear - delta);\n                                focusOnDay(getFirstAvailableDay(1), 0);\n                            }\n                            else if (!isTimeObj)\n                                focusOnDay(undefined, delta * 7);\n                        }\n                        else if (eventTarget === self.currentYearElement) {\n                            changeYear(self.currentYear - delta);\n                        }\n                        else if (self.config.enableTime) {\n                            if (!isTimeObj && self.hourElement)\n                                self.hourElement.focus();\n                            updateTime(e);\n                            self._debouncedChange();\n                        }\n                        break;\n                    case 9:\n                        if (isTimeObj) {\n                            var elems = [\n                                self.hourElement,\n                                self.minuteElement,\n                                self.secondElement,\n                                self.amPM,\n                            ]\n                                .concat(self.pluginElements)\n                                .filter(function (x) { return x; });\n                            var i = elems.indexOf(eventTarget);\n                            if (i !== -1) {\n                                var target = elems[i + (e.shiftKey ? -1 : 1)];\n                                e.preventDefault();\n                                (target || self._input).focus();\n                            }\n                        }\n                        else if (!self.config.noCalendar &&\n                            self.daysContainer &&\n                            self.daysContainer.contains(eventTarget) &&\n                            e.shiftKey) {\n                            e.preventDefault();\n                            self._input.focus();\n                        }\n                        break;\n                }\n            }\n            if (self.amPM !== undefined && eventTarget === self.amPM) {\n                switch (e.key) {\n                    case self.l10n.amPM[0].charAt(0):\n                    case self.l10n.amPM[0].charAt(0).toLowerCase():\n                        self.amPM.textContent = self.l10n.amPM[0];\n                        setHoursFromInputs();\n                        updateValue();\n                        break;\n                    case self.l10n.amPM[1].charAt(0):\n                    case self.l10n.amPM[1].charAt(0).toLowerCase():\n                        self.amPM.textContent = self.l10n.amPM[1];\n                        setHoursFromInputs();\n                        updateValue();\n                        break;\n                }\n            }\n            if (isInput || isCalendarElem(eventTarget)) {\n                triggerEvent(\"onKeyDown\", e);\n            }\n        }\n        function onMouseOver(elem, cellClass) {\n            if (cellClass === void 0) { cellClass = \"flatpickr-day\"; }\n            if (self.selectedDates.length !== 1 ||\n                (elem &&\n                    (!elem.classList.contains(cellClass) ||\n                        elem.classList.contains(\"flatpickr-disabled\"))))\n                return;\n            var hoverDate = elem\n                ? elem.dateObj.getTime()\n                : self.days.firstElementChild.dateObj.getTime(), initialDate = self.parseDate(self.selectedDates[0], undefined, true).getTime(), rangeStartDate = Math.min(hoverDate, self.selectedDates[0].getTime()), rangeEndDate = Math.max(hoverDate, self.selectedDates[0].getTime());\n            var containsDisabled = false;\n            var minRange = 0, maxRange = 0;\n            for (var t = rangeStartDate; t < rangeEndDate; t += duration.DAY) {\n                if (!isEnabled(new Date(t), true)) {\n                    containsDisabled =\n                        containsDisabled || (t > rangeStartDate && t < rangeEndDate);\n                    if (t < initialDate && (!minRange || t > minRange))\n                        minRange = t;\n                    else if (t > initialDate && (!maxRange || t < maxRange))\n                        maxRange = t;\n                }\n            }\n            var hoverableCells = Array.from(self.rContainer.querySelectorAll(\"*:nth-child(-n+\" + self.config.showMonths + \") > .\" + cellClass));\n            hoverableCells.forEach(function (dayElem) {\n                var date = dayElem.dateObj;\n                var timestamp = date.getTime();\n                var outOfRange = (minRange > 0 && timestamp < minRange) ||\n                    (maxRange > 0 && timestamp > maxRange);\n                if (outOfRange) {\n                    dayElem.classList.add(\"notAllowed\");\n                    [\"inRange\", \"startRange\", \"endRange\"].forEach(function (c) {\n                        dayElem.classList.remove(c);\n                    });\n                    return;\n                }\n                else if (containsDisabled && !outOfRange)\n                    return;\n                [\"startRange\", \"inRange\", \"endRange\", \"notAllowed\"].forEach(function (c) {\n                    dayElem.classList.remove(c);\n                });\n                if (elem !== undefined) {\n                    elem.classList.add(hoverDate <= self.selectedDates[0].getTime()\n                        ? \"startRange\"\n                        : \"endRange\");\n                    if (initialDate < hoverDate && timestamp === initialDate)\n                        dayElem.classList.add(\"startRange\");\n                    else if (initialDate > hoverDate && timestamp === initialDate)\n                        dayElem.classList.add(\"endRange\");\n                    if (timestamp >= minRange &&\n                        (maxRange === 0 || timestamp <= maxRange) &&\n                        isBetween(timestamp, initialDate, hoverDate))\n                        dayElem.classList.add(\"inRange\");\n                }\n            });\n        }\n        function onResize() {\n            if (self.isOpen && !self.config.static && !self.config.inline)\n                positionCalendar();\n        }\n        function open(e, positionElement) {\n            if (positionElement === void 0) { positionElement = self._positionElement; }\n            if (self.isMobile === true) {\n                if (e) {\n                    e.preventDefault();\n                    var eventTarget = getEventTarget(e);\n                    if (eventTarget) {\n                        eventTarget.blur();\n                    }\n                }\n                if (self.mobileInput !== undefined) {\n                    self.mobileInput.focus();\n                    self.mobileInput.click();\n                }\n                triggerEvent(\"onOpen\");\n                return;\n            }\n            else if (self._input.disabled || self.config.inline) {\n                return;\n            }\n            var wasOpen = self.isOpen;\n            self.isOpen = true;\n            if (!wasOpen) {\n                self.calendarContainer.classList.add(\"open\");\n                self._input.classList.add(\"active\");\n                triggerEvent(\"onOpen\");\n                positionCalendar(positionElement);\n            }\n            if (self.config.enableTime === true && self.config.noCalendar === true) {\n                if (self.config.allowInput === false &&\n                    (e === undefined ||\n                        !self.timeContainer.contains(e.relatedTarget))) {\n                    setTimeout(function () { return self.hourElement.select(); }, 50);\n                }\n            }\n        }\n        function minMaxDateSetter(type) {\n            return function (date) {\n                var dateObj = (self.config[\"_\" + type + \"Date\"] = self.parseDate(date, self.config.dateFormat));\n                var inverseDateObj = self.config[\"_\" + (type === \"min\" ? \"max\" : \"min\") + \"Date\"];\n                if (dateObj !== undefined) {\n                    self[type === \"min\" ? \"minDateHasTime\" : \"maxDateHasTime\"] =\n                        dateObj.getHours() > 0 ||\n                            dateObj.getMinutes() > 0 ||\n                            dateObj.getSeconds() > 0;\n                }\n                if (self.selectedDates) {\n                    self.selectedDates = self.selectedDates.filter(function (d) { return isEnabled(d); });\n                    if (!self.selectedDates.length && type === \"min\")\n                        setHoursFromDate(dateObj);\n                    updateValue();\n                }\n                if (self.daysContainer) {\n                    redraw();\n                    if (dateObj !== undefined)\n                        self.currentYearElement[type] = dateObj.getFullYear().toString();\n                    else\n                        self.currentYearElement.removeAttribute(type);\n                    self.currentYearElement.disabled =\n                        !!inverseDateObj &&\n                            dateObj !== undefined &&\n                            inverseDateObj.getFullYear() === dateObj.getFullYear();\n                }\n            };\n        }\n        function parseConfig() {\n            var boolOpts = [\n                \"wrap\",\n                \"weekNumbers\",\n                \"allowInput\",\n                \"allowInvalidPreload\",\n                \"clickOpens\",\n                \"time_24hr\",\n                \"enableTime\",\n                \"noCalendar\",\n                \"altInput\",\n                \"shorthandCurrentMonth\",\n                \"inline\",\n                \"static\",\n                \"enableSeconds\",\n                \"disableMobile\",\n            ];\n            var userConfig = __assign(__assign({}, JSON.parse(JSON.stringify(element.dataset || {}))), instanceConfig);\n            var formats = {};\n            self.config.parseDate = userConfig.parseDate;\n            self.config.formatDate = userConfig.formatDate;\n            Object.defineProperty(self.config, \"enable\", {\n                get: function () { return self.config._enable; },\n                set: function (dates) {\n                    self.config._enable = parseDateRules(dates);\n                },\n            });\n            Object.defineProperty(self.config, \"disable\", {\n                get: function () { return self.config._disable; },\n                set: function (dates) {\n                    self.config._disable = parseDateRules(dates);\n                },\n            });\n            var timeMode = userConfig.mode === \"time\";\n            if (!userConfig.dateFormat && (userConfig.enableTime || timeMode)) {\n                var defaultDateFormat = flatpickr.defaultConfig.dateFormat || defaults.dateFormat;\n                formats.dateFormat =\n                    userConfig.noCalendar || timeMode\n                        ? \"H:i\" + (userConfig.enableSeconds ? \":S\" : \"\")\n                        : defaultDateFormat + \" H:i\" + (userConfig.enableSeconds ? \":S\" : \"\");\n            }\n            if (userConfig.altInput &&\n                (userConfig.enableTime || timeMode) &&\n                !userConfig.altFormat) {\n                var defaultAltFormat = flatpickr.defaultConfig.altFormat || defaults.altFormat;\n                formats.altFormat =\n                    userConfig.noCalendar || timeMode\n                        ? \"h:i\" + (userConfig.enableSeconds ? \":S K\" : \" K\")\n                        : defaultAltFormat + (\" h:i\" + (userConfig.enableSeconds ? \":S\" : \"\") + \" K\");\n            }\n            Object.defineProperty(self.config, \"minDate\", {\n                get: function () { return self.config._minDate; },\n                set: minMaxDateSetter(\"min\"),\n            });\n            Object.defineProperty(self.config, \"maxDate\", {\n                get: function () { return self.config._maxDate; },\n                set: minMaxDateSetter(\"max\"),\n            });\n            var minMaxTimeSetter = function (type) { return function (val) {\n                self.config[type === \"min\" ? \"_minTime\" : \"_maxTime\"] = self.parseDate(val, \"H:i:S\");\n            }; };\n            Object.defineProperty(self.config, \"minTime\", {\n                get: function () { return self.config._minTime; },\n                set: minMaxTimeSetter(\"min\"),\n            });\n            Object.defineProperty(self.config, \"maxTime\", {\n                get: function () { return self.config._maxTime; },\n                set: minMaxTimeSetter(\"max\"),\n            });\n            if (userConfig.mode === \"time\") {\n                self.config.noCalendar = true;\n                self.config.enableTime = true;\n            }\n            Object.assign(self.config, formats, userConfig);\n            for (var i = 0; i < boolOpts.length; i++)\n                // https://github.com/microsoft/TypeScript/issues/31663\n                self.config[boolOpts[i]] =\n                    self.config[boolOpts[i]] === true ||\n                        self.config[boolOpts[i]] === \"true\";\n            HOOKS.filter(function (hook) { return self.config[hook] !== undefined; }).forEach(function (hook) {\n                self.config[hook] = arrayify(self.config[hook] || []).map(bindToInstance);\n            });\n            self.isMobile =\n                !self.config.disableMobile &&\n                    !self.config.inline &&\n                    self.config.mode === \"single\" &&\n                    !self.config.disable.length &&\n                    !self.config.enable &&\n                    !self.config.weekNumbers &&\n                    /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n            for (var i = 0; i < self.config.plugins.length; i++) {\n                var pluginConf = self.config.plugins[i](self) || {};\n                for (var key in pluginConf) {\n                    if (HOOKS.indexOf(key) > -1) {\n                        self.config[key] = arrayify(pluginConf[key])\n                            .map(bindToInstance)\n                            .concat(self.config[key]);\n                    }\n                    else if (typeof userConfig[key] === \"undefined\")\n                        self.config[key] = pluginConf[key];\n                }\n            }\n            if (!userConfig.altInputClass) {\n                self.config.altInputClass =\n                    getInputElem().className + \" \" + self.config.altInputClass;\n            }\n            triggerEvent(\"onParseConfig\");\n        }\n        function getInputElem() {\n            return self.config.wrap\n                ? element.querySelector(\"[data-input]\")\n                : element;\n        }\n        function setupLocale() {\n            if (typeof self.config.locale !== \"object\" &&\n                typeof flatpickr.l10ns[self.config.locale] === \"undefined\")\n                self.config.errorHandler(new Error(\"flatpickr: invalid locale \" + self.config.locale));\n            self.l10n = __assign(__assign({}, flatpickr.l10ns.default), (typeof self.config.locale === \"object\"\n                ? self.config.locale\n                : self.config.locale !== \"default\"\n                    ? flatpickr.l10ns[self.config.locale]\n                    : undefined));\n            tokenRegex.D = \"(\" + self.l10n.weekdays.shorthand.join(\"|\") + \")\";\n            tokenRegex.l = \"(\" + self.l10n.weekdays.longhand.join(\"|\") + \")\";\n            tokenRegex.M = \"(\" + self.l10n.months.shorthand.join(\"|\") + \")\";\n            tokenRegex.F = \"(\" + self.l10n.months.longhand.join(\"|\") + \")\";\n            tokenRegex.K = \"(\" + self.l10n.amPM[0] + \"|\" + self.l10n.amPM[1] + \"|\" + self.l10n.amPM[0].toLowerCase() + \"|\" + self.l10n.amPM[1].toLowerCase() + \")\";\n            var userConfig = __assign(__assign({}, instanceConfig), JSON.parse(JSON.stringify(element.dataset || {})));\n            if (userConfig.time_24hr === undefined &&\n                flatpickr.defaultConfig.time_24hr === undefined) {\n                self.config.time_24hr = self.l10n.time_24hr;\n            }\n            self.formatDate = createDateFormatter(self);\n            self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });\n        }\n        function positionCalendar(customPositionElement) {\n            if (typeof self.config.position === \"function\") {\n                return void self.config.position(self, customPositionElement);\n            }\n            if (self.calendarContainer === undefined)\n                return;\n            triggerEvent(\"onPreCalendarPosition\");\n            var positionElement = customPositionElement || self._positionElement;\n            var calendarHeight = Array.prototype.reduce.call(self.calendarContainer.children, (function (acc, child) { return acc + child.offsetHeight; }), 0), calendarWidth = self.calendarContainer.offsetWidth, configPos = self.config.position.split(\" \"), configPosVertical = configPos[0], configPosHorizontal = configPos.length > 1 ? configPos[1] : null, inputBounds = positionElement.getBoundingClientRect(), distanceFromBottom = window.innerHeight - inputBounds.bottom, showOnTop = configPosVertical === \"above\" ||\n                (configPosVertical !== \"below\" &&\n                    distanceFromBottom < calendarHeight &&\n                    inputBounds.top > calendarHeight);\n            var top = window.pageYOffset +\n                inputBounds.top +\n                (!showOnTop ? positionElement.offsetHeight + 2 : -calendarHeight - 2);\n            toggleClass(self.calendarContainer, \"arrowTop\", !showOnTop);\n            toggleClass(self.calendarContainer, \"arrowBottom\", showOnTop);\n            if (self.config.inline)\n                return;\n            var left = window.pageXOffset + inputBounds.left;\n            var isCenter = false;\n            var isRight = false;\n            if (configPosHorizontal === \"center\") {\n                left -= (calendarWidth - inputBounds.width) / 2;\n                isCenter = true;\n            }\n            else if (configPosHorizontal === \"right\") {\n                left -= calendarWidth - inputBounds.width;\n                isRight = true;\n            }\n            toggleClass(self.calendarContainer, \"arrowLeft\", !isCenter && !isRight);\n            toggleClass(self.calendarContainer, \"arrowCenter\", isCenter);\n            toggleClass(self.calendarContainer, \"arrowRight\", isRight);\n            var right = window.document.body.offsetWidth -\n                (window.pageXOffset + inputBounds.right);\n            var rightMost = left + calendarWidth > window.document.body.offsetWidth;\n            var centerMost = right + calendarWidth > window.document.body.offsetWidth;\n            toggleClass(self.calendarContainer, \"rightMost\", rightMost);\n            if (self.config.static)\n                return;\n            self.calendarContainer.style.top = top + \"px\";\n            if (!rightMost) {\n                self.calendarContainer.style.left = left + \"px\";\n                self.calendarContainer.style.right = \"auto\";\n            }\n            else if (!centerMost) {\n                self.calendarContainer.style.left = \"auto\";\n                self.calendarContainer.style.right = right + \"px\";\n            }\n            else {\n                var doc = getDocumentStyleSheet();\n                // some testing environments don't have css support\n                if (doc === undefined)\n                    return;\n                var bodyWidth = window.document.body.offsetWidth;\n                var centerLeft = Math.max(0, bodyWidth / 2 - calendarWidth / 2);\n                var centerBefore = \".flatpickr-calendar.centerMost:before\";\n                var centerAfter = \".flatpickr-calendar.centerMost:after\";\n                var centerIndex = doc.cssRules.length;\n                var centerStyle = \"{left:\" + inputBounds.left + \"px;right:auto;}\";\n                toggleClass(self.calendarContainer, \"rightMost\", false);\n                toggleClass(self.calendarContainer, \"centerMost\", true);\n                doc.insertRule(centerBefore + \",\" + centerAfter + centerStyle, centerIndex);\n                self.calendarContainer.style.left = centerLeft + \"px\";\n                self.calendarContainer.style.right = \"auto\";\n            }\n        }\n        function getDocumentStyleSheet() {\n            var editableSheet = null;\n            for (var i = 0; i < document.styleSheets.length; i++) {\n                var sheet = document.styleSheets[i];\n                if (!sheet.cssRules)\n                    continue;\n                try {\n                    sheet.cssRules;\n                }\n                catch (err) {\n                    continue;\n                }\n                editableSheet = sheet;\n                break;\n            }\n            return editableSheet != null ? editableSheet : createStyleSheet();\n        }\n        function createStyleSheet() {\n            var style = document.createElement(\"style\");\n            document.head.appendChild(style);\n            return style.sheet;\n        }\n        function redraw() {\n            if (self.config.noCalendar || self.isMobile)\n                return;\n            buildMonthSwitch();\n            updateNavigationCurrentMonth();\n            buildDays();\n        }\n        function focusAndClose() {\n            self._input.focus();\n            if (window.navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n                navigator.msMaxTouchPoints !== undefined) {\n                // hack - bugs in the way IE handles focus keeps the calendar open\n                setTimeout(self.close, 0);\n            }\n            else {\n                self.close();\n            }\n        }\n        function selectDate(e) {\n            e.preventDefault();\n            e.stopPropagation();\n            var isSelectable = function (day) {\n                return day.classList &&\n                    day.classList.contains(\"flatpickr-day\") &&\n                    !day.classList.contains(\"flatpickr-disabled\") &&\n                    !day.classList.contains(\"notAllowed\");\n            };\n            var t = findParent(getEventTarget(e), isSelectable);\n            if (t === undefined)\n                return;\n            var target = t;\n            var selectedDate = (self.latestSelectedDateObj = new Date(target.dateObj.getTime()));\n            var shouldChangeMonth = (selectedDate.getMonth() < self.currentMonth ||\n                selectedDate.getMonth() >\n                    self.currentMonth + self.config.showMonths - 1) &&\n                self.config.mode !== \"range\";\n            self.selectedDateElem = target;\n            if (self.config.mode === \"single\")\n                self.selectedDates = [selectedDate];\n            else if (self.config.mode === \"multiple\") {\n                var selectedIndex = isDateSelected(selectedDate);\n                if (selectedIndex)\n                    self.selectedDates.splice(parseInt(selectedIndex), 1);\n                else\n                    self.selectedDates.push(selectedDate);\n            }\n            else if (self.config.mode === \"range\") {\n                if (self.selectedDates.length === 2) {\n                    self.clear(false, false);\n                }\n                self.latestSelectedDateObj = selectedDate;\n                self.selectedDates.push(selectedDate);\n                // unless selecting same date twice, sort ascendingly\n                if (compareDates(selectedDate, self.selectedDates[0], true) !== 0)\n                    self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });\n            }\n            setHoursFromInputs();\n            if (shouldChangeMonth) {\n                var isNewYear = self.currentYear !== selectedDate.getFullYear();\n                self.currentYear = selectedDate.getFullYear();\n                self.currentMonth = selectedDate.getMonth();\n                if (isNewYear) {\n                    triggerEvent(\"onYearChange\");\n                    buildMonthSwitch();\n                }\n                triggerEvent(\"onMonthChange\");\n            }\n            updateNavigationCurrentMonth();\n            buildDays();\n            updateValue();\n            // maintain focus\n            if (!shouldChangeMonth &&\n                self.config.mode !== \"range\" &&\n                self.config.showMonths === 1)\n                focusOnDayElem(target);\n            else if (self.selectedDateElem !== undefined &&\n                self.hourElement === undefined) {\n                self.selectedDateElem && self.selectedDateElem.focus();\n            }\n            if (self.hourElement !== undefined)\n                self.hourElement !== undefined && self.hourElement.focus();\n            if (self.config.closeOnSelect) {\n                var single = self.config.mode === \"single\" && !self.config.enableTime;\n                var range = self.config.mode === \"range\" &&\n                    self.selectedDates.length === 2 &&\n                    !self.config.enableTime;\n                if (single || range) {\n                    focusAndClose();\n                }\n            }\n            triggerChange();\n        }\n        var CALLBACKS = {\n            locale: [setupLocale, updateWeekdays],\n            showMonths: [buildMonths, setCalendarWidth, buildWeekdays],\n            minDate: [jumpToDate],\n            maxDate: [jumpToDate],\n            positionElement: [updatePositionElement],\n            clickOpens: [\n                function () {\n                    if (self.config.clickOpens === true) {\n                        bind(self._input, \"focus\", self.open);\n                        bind(self._input, \"click\", self.open);\n                    }\n                    else {\n                        self._input.removeEventListener(\"focus\", self.open);\n                        self._input.removeEventListener(\"click\", self.open);\n                    }\n                },\n            ],\n        };\n        function set(option, value) {\n            if (option !== null && typeof option === \"object\") {\n                Object.assign(self.config, option);\n                for (var key in option) {\n                    if (CALLBACKS[key] !== undefined)\n                        CALLBACKS[key].forEach(function (x) { return x(); });\n                }\n            }\n            else {\n                self.config[option] = value;\n                if (CALLBACKS[option] !== undefined)\n                    CALLBACKS[option].forEach(function (x) { return x(); });\n                else if (HOOKS.indexOf(option) > -1)\n                    self.config[option] = arrayify(value);\n            }\n            self.redraw();\n            updateValue(true);\n        }\n        function setSelectedDate(inputDate, format) {\n            var dates = [];\n            if (inputDate instanceof Array)\n                dates = inputDate.map(function (d) { return self.parseDate(d, format); });\n            else if (inputDate instanceof Date || typeof inputDate === \"number\")\n                dates = [self.parseDate(inputDate, format)];\n            else if (typeof inputDate === \"string\") {\n                switch (self.config.mode) {\n                    case \"single\":\n                    case \"time\":\n                        dates = [self.parseDate(inputDate, format)];\n                        break;\n                    case \"multiple\":\n                        dates = inputDate\n                            .split(self.config.conjunction)\n                            .map(function (date) { return self.parseDate(date, format); });\n                        break;\n                    case \"range\":\n                        dates = inputDate\n                            .split(self.l10n.rangeSeparator)\n                            .map(function (date) { return self.parseDate(date, format); });\n                        break;\n                }\n            }\n            else\n                self.config.errorHandler(new Error(\"Invalid date supplied: \" + JSON.stringify(inputDate)));\n            self.selectedDates = (self.config.allowInvalidPreload\n                ? dates\n                : dates.filter(function (d) { return d instanceof Date && isEnabled(d, false); }));\n            if (self.config.mode === \"range\")\n                self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });\n        }\n        function setDate(date, triggerChange, format) {\n            if (triggerChange === void 0) { triggerChange = false; }\n            if (format === void 0) { format = self.config.dateFormat; }\n            if ((date !== 0 && !date) || (date instanceof Array && date.length === 0))\n                return self.clear(triggerChange);\n            setSelectedDate(date, format);\n            self.latestSelectedDateObj =\n                self.selectedDates[self.selectedDates.length - 1];\n            self.redraw();\n            jumpToDate(undefined, triggerChange);\n            setHoursFromDate();\n            if (self.selectedDates.length === 0) {\n                self.clear(false);\n            }\n            updateValue(triggerChange);\n            if (triggerChange)\n                triggerEvent(\"onChange\");\n        }\n        function parseDateRules(arr) {\n            return arr\n                .slice()\n                .map(function (rule) {\n                if (typeof rule === \"string\" ||\n                    typeof rule === \"number\" ||\n                    rule instanceof Date) {\n                    return self.parseDate(rule, undefined, true);\n                }\n                else if (rule &&\n                    typeof rule === \"object\" &&\n                    rule.from &&\n                    rule.to)\n                    return {\n                        from: self.parseDate(rule.from, undefined),\n                        to: self.parseDate(rule.to, undefined),\n                    };\n                return rule;\n            })\n                .filter(function (x) { return x; }); // remove falsy values\n        }\n        function setupDates() {\n            self.selectedDates = [];\n            self.now = self.parseDate(self.config.now) || new Date();\n            // Workaround IE11 setting placeholder as the input's value\n            var preloadedDate = self.config.defaultDate ||\n                ((self.input.nodeName === \"INPUT\" ||\n                    self.input.nodeName === \"TEXTAREA\") &&\n                    self.input.placeholder &&\n                    self.input.value === self.input.placeholder\n                    ? null\n                    : self.input.value);\n            if (preloadedDate)\n                setSelectedDate(preloadedDate, self.config.dateFormat);\n            self._initialDate =\n                self.selectedDates.length > 0\n                    ? self.selectedDates[0]\n                    : self.config.minDate &&\n                        self.config.minDate.getTime() > self.now.getTime()\n                        ? self.config.minDate\n                        : self.config.maxDate &&\n                            self.config.maxDate.getTime() < self.now.getTime()\n                            ? self.config.maxDate\n                            : self.now;\n            self.currentYear = self._initialDate.getFullYear();\n            self.currentMonth = self._initialDate.getMonth();\n            if (self.selectedDates.length > 0)\n                self.latestSelectedDateObj = self.selectedDates[0];\n            if (self.config.minTime !== undefined)\n                self.config.minTime = self.parseDate(self.config.minTime, \"H:i\");\n            if (self.config.maxTime !== undefined)\n                self.config.maxTime = self.parseDate(self.config.maxTime, \"H:i\");\n            self.minDateHasTime =\n                !!self.config.minDate &&\n                    (self.config.minDate.getHours() > 0 ||\n                        self.config.minDate.getMinutes() > 0 ||\n                        self.config.minDate.getSeconds() > 0);\n            self.maxDateHasTime =\n                !!self.config.maxDate &&\n                    (self.config.maxDate.getHours() > 0 ||\n                        self.config.maxDate.getMinutes() > 0 ||\n                        self.config.maxDate.getSeconds() > 0);\n        }\n        function setupInputs() {\n            self.input = getInputElem();\n            /* istanbul ignore next */\n            if (!self.input) {\n                self.config.errorHandler(new Error(\"Invalid input element specified\"));\n                return;\n            }\n            // hack: store previous type to restore it after destroy()\n            self.input._type = self.input.type;\n            self.input.type = \"text\";\n            self.input.classList.add(\"flatpickr-input\");\n            self._input = self.input;\n            if (self.config.altInput) {\n                // replicate self.element\n                self.altInput = createElement(self.input.nodeName, self.config.altInputClass);\n                self._input = self.altInput;\n                self.altInput.placeholder = self.input.placeholder;\n                self.altInput.disabled = self.input.disabled;\n                self.altInput.required = self.input.required;\n                self.altInput.tabIndex = self.input.tabIndex;\n                self.altInput.type = \"text\";\n                self.input.setAttribute(\"type\", \"hidden\");\n                if (!self.config.static && self.input.parentNode)\n                    self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);\n            }\n            if (!self.config.allowInput)\n                self._input.setAttribute(\"readonly\", \"readonly\");\n            updatePositionElement();\n        }\n        function updatePositionElement() {\n            self._positionElement = self.config.positionElement || self._input;\n        }\n        function setupMobile() {\n            var inputType = self.config.enableTime\n                ? self.config.noCalendar\n                    ? \"time\"\n                    : \"datetime-local\"\n                : \"date\";\n            self.mobileInput = createElement(\"input\", self.input.className + \" flatpickr-mobile\");\n            self.mobileInput.tabIndex = 1;\n            self.mobileInput.type = inputType;\n            self.mobileInput.disabled = self.input.disabled;\n            self.mobileInput.required = self.input.required;\n            self.mobileInput.placeholder = self.input.placeholder;\n            self.mobileFormatStr =\n                inputType === \"datetime-local\"\n                    ? \"Y-m-d\\\\TH:i:S\"\n                    : inputType === \"date\"\n                        ? \"Y-m-d\"\n                        : \"H:i:S\";\n            if (self.selectedDates.length > 0) {\n                self.mobileInput.defaultValue = self.mobileInput.value = self.formatDate(self.selectedDates[0], self.mobileFormatStr);\n            }\n            if (self.config.minDate)\n                self.mobileInput.min = self.formatDate(self.config.minDate, \"Y-m-d\");\n            if (self.config.maxDate)\n                self.mobileInput.max = self.formatDate(self.config.maxDate, \"Y-m-d\");\n            if (self.input.getAttribute(\"step\"))\n                self.mobileInput.step = String(self.input.getAttribute(\"step\"));\n            self.input.type = \"hidden\";\n            if (self.altInput !== undefined)\n                self.altInput.type = \"hidden\";\n            try {\n                if (self.input.parentNode)\n                    self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);\n            }\n            catch (_a) { }\n            bind(self.mobileInput, \"change\", function (e) {\n                self.setDate(getEventTarget(e).value, false, self.mobileFormatStr);\n                triggerEvent(\"onChange\");\n                triggerEvent(\"onClose\");\n            });\n        }\n        function toggle(e) {\n            if (self.isOpen === true)\n                return self.close();\n            self.open(e);\n        }\n        function triggerEvent(event, data) {\n            // If the instance has been destroyed already, all hooks have been removed\n            if (self.config === undefined)\n                return;\n            var hooks = self.config[event];\n            if (hooks !== undefined && hooks.length > 0) {\n                for (var i = 0; hooks[i] && i < hooks.length; i++)\n                    hooks[i](self.selectedDates, self.input.value, self, data);\n            }\n            if (event === \"onChange\") {\n                self.input.dispatchEvent(createEvent(\"change\"));\n                // many front-end frameworks bind to the input event\n                self.input.dispatchEvent(createEvent(\"input\"));\n            }\n        }\n        function createEvent(name) {\n            var e = document.createEvent(\"Event\");\n            e.initEvent(name, true, true);\n            return e;\n        }\n        function isDateSelected(date) {\n            for (var i = 0; i < self.selectedDates.length; i++) {\n                var selectedDate = self.selectedDates[i];\n                if (selectedDate instanceof Date && compareDates(selectedDate, date) === 0)\n                    return \"\" + i;\n            }\n            return false;\n        }\n        function isDateInRange(date) {\n            if (self.config.mode !== \"range\" || self.selectedDates.length < 2)\n                return false;\n            return (compareDates(date, self.selectedDates[0]) >= 0 &&\n                compareDates(date, self.selectedDates[1]) <= 0);\n        }\n        function updateNavigationCurrentMonth() {\n            if (self.config.noCalendar || self.isMobile || !self.monthNav)\n                return;\n            self.yearElements.forEach(function (yearElement, i) {\n                var d = new Date(self.currentYear, self.currentMonth, 1);\n                d.setMonth(self.currentMonth + i);\n                if (self.config.showMonths > 1 ||\n                    self.config.monthSelectorType === \"static\") {\n                    self.monthElements[i].textContent =\n                        monthToStr(d.getMonth(), self.config.shorthandCurrentMonth, self.l10n) + \" \";\n                }\n                else {\n                    self.monthsDropdownContainer.value = d.getMonth().toString();\n                }\n                yearElement.value = d.getFullYear().toString();\n            });\n            self._hidePrevMonthArrow =\n                self.config.minDate !== undefined &&\n                    (self.currentYear === self.config.minDate.getFullYear()\n                        ? self.currentMonth <= self.config.minDate.getMonth()\n                        : self.currentYear < self.config.minDate.getFullYear());\n            self._hideNextMonthArrow =\n                self.config.maxDate !== undefined &&\n                    (self.currentYear === self.config.maxDate.getFullYear()\n                        ? self.currentMonth + 1 > self.config.maxDate.getMonth()\n                        : self.currentYear > self.config.maxDate.getFullYear());\n        }\n        function getDateStr(format) {\n            return self.selectedDates\n                .map(function (dObj) { return self.formatDate(dObj, format); })\n                .filter(function (d, i, arr) {\n                return self.config.mode !== \"range\" ||\n                    self.config.enableTime ||\n                    arr.indexOf(d) === i;\n            })\n                .join(self.config.mode !== \"range\"\n                ? self.config.conjunction\n                : self.l10n.rangeSeparator);\n        }\n        /**\n         * Updates the values of inputs associated with the calendar\n         */\n        function updateValue(triggerChange) {\n            if (triggerChange === void 0) { triggerChange = true; }\n            if (self.mobileInput !== undefined && self.mobileFormatStr) {\n                self.mobileInput.value =\n                    self.latestSelectedDateObj !== undefined\n                        ? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr)\n                        : \"\";\n            }\n            self.input.value = getDateStr(self.config.dateFormat);\n            if (self.altInput !== undefined) {\n                self.altInput.value = getDateStr(self.config.altFormat);\n            }\n            if (triggerChange !== false)\n                triggerEvent(\"onValueUpdate\");\n        }\n        function onMonthNavClick(e) {\n            var eventTarget = getEventTarget(e);\n            var isPrevMonth = self.prevMonthNav.contains(eventTarget);\n            var isNextMonth = self.nextMonthNav.contains(eventTarget);\n            if (isPrevMonth || isNextMonth) {\n                changeMonth(isPrevMonth ? -1 : 1);\n            }\n            else if (self.yearElements.indexOf(eventTarget) >= 0) {\n                eventTarget.select();\n            }\n            else if (eventTarget.classList.contains(\"arrowUp\")) {\n                self.changeYear(self.currentYear + 1);\n            }\n            else if (eventTarget.classList.contains(\"arrowDown\")) {\n                self.changeYear(self.currentYear - 1);\n            }\n        }\n        function timeWrapper(e) {\n            e.preventDefault();\n            var isKeyDown = e.type === \"keydown\", eventTarget = getEventTarget(e), input = eventTarget;\n            if (self.amPM !== undefined && eventTarget === self.amPM) {\n                self.amPM.textContent =\n                    self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];\n            }\n            var min = parseFloat(input.getAttribute(\"min\")), max = parseFloat(input.getAttribute(\"max\")), step = parseFloat(input.getAttribute(\"step\")), curValue = parseInt(input.value, 10), delta = e.delta ||\n                (isKeyDown ? (e.which === 38 ? 1 : -1) : 0);\n            var newValue = curValue + step * delta;\n            if (typeof input.value !== \"undefined\" && input.value.length === 2) {\n                var isHourElem = input === self.hourElement, isMinuteElem = input === self.minuteElement;\n                if (newValue < min) {\n                    newValue =\n                        max +\n                            newValue +\n                            int(!isHourElem) +\n                            (int(isHourElem) && int(!self.amPM));\n                    if (isMinuteElem)\n                        incrementNumInput(undefined, -1, self.hourElement);\n                }\n                else if (newValue > max) {\n                    newValue =\n                        input === self.hourElement ? newValue - max - int(!self.amPM) : min;\n                    if (isMinuteElem)\n                        incrementNumInput(undefined, 1, self.hourElement);\n                }\n                if (self.amPM &&\n                    isHourElem &&\n                    (step === 1\n                        ? newValue + curValue === 23\n                        : Math.abs(newValue - curValue) > step)) {\n                    self.amPM.textContent =\n                        self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];\n                }\n                input.value = pad(newValue);\n            }\n        }\n        init();\n        return self;\n    }\n    /* istanbul ignore next */\n    function _flatpickr(nodeList, config) {\n        // static list\n        var nodes = Array.prototype.slice\n            .call(nodeList)\n            .filter(function (x) { return x instanceof HTMLElement; });\n        var instances = [];\n        for (var i = 0; i < nodes.length; i++) {\n            var node = nodes[i];\n            try {\n                if (node.getAttribute(\"data-fp-omit\") !== null)\n                    continue;\n                if (node._flatpickr !== undefined) {\n                    node._flatpickr.destroy();\n                    node._flatpickr = undefined;\n                }\n                node._flatpickr = FlatpickrInstance(node, config || {});\n                instances.push(node._flatpickr);\n            }\n            catch (e) {\n                console.error(e);\n            }\n        }\n        return instances.length === 1 ? instances[0] : instances;\n    }\n    /* istanbul ignore next */\n    if (typeof HTMLElement !== \"undefined\" &&\n        typeof HTMLCollection !== \"undefined\" &&\n        typeof NodeList !== \"undefined\") {\n        // browser env\n        HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function (config) {\n            return _flatpickr(this, config);\n        };\n        HTMLElement.prototype.flatpickr = function (config) {\n            return _flatpickr([this], config);\n        };\n    }\n    /* istanbul ignore next */\n    var flatpickr = function (selector, config) {\n        if (typeof selector === \"string\") {\n            return _flatpickr(window.document.querySelectorAll(selector), config);\n        }\n        else if (selector instanceof Node) {\n            return _flatpickr([selector], config);\n        }\n        else {\n            return _flatpickr(selector, config);\n        }\n    };\n    /* istanbul ignore next */\n    flatpickr.defaultConfig = {};\n    flatpickr.l10ns = {\n        en: __assign({}, english),\n        default: __assign({}, english),\n    };\n    flatpickr.localize = function (l10n) {\n        flatpickr.l10ns.default = __assign(__assign({}, flatpickr.l10ns.default), l10n);\n    };\n    flatpickr.setDefaults = function (config) {\n        flatpickr.defaultConfig = __assign(__assign({}, flatpickr.defaultConfig), config);\n    };\n    flatpickr.parseDate = createDateParser({});\n    flatpickr.formatDate = createDateFormatter({});\n    flatpickr.compareDates = compareDates;\n    /* istanbul ignore next */\n    if (typeof jQuery !== \"undefined\" && typeof jQuery.fn !== \"undefined\") {\n        jQuery.fn.flatpickr = function (config) {\n            return _flatpickr(this, config);\n        };\n    }\n    Date.prototype.fp_incr = function (days) {\n        return new Date(this.getFullYear(), this.getMonth(), this.getDate() + (typeof days === \"string\" ? parseInt(days, 10) : days));\n    };\n    if (typeof window !== \"undefined\") {\n        window.flatpickr = flatpickr;\n    }\n\n    return flatpickr;\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['ar-dz'] = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var AlgerianArabic = {\n      weekdays: {\n          shorthand: [\"أحد\", \"اثنين\", \"ثلاثاء\", \"أربعاء\", \"خميس\", \"جمعة\", \"سبت\"],\n          longhand: [\n              \"الأحد\",\n              \"الاثنين\",\n              \"الثلاثاء\",\n              \"الأربعاء\",\n              \"الخميس\",\n              \"الجمعة\",\n              \"السبت\",\n          ],\n      },\n      months: {\n          shorthand: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n          longhand: [\n              \"جانفي\",\n              \"فيفري\",\n              \"مارس\",\n              \"أفريل\",\n              \"ماي\",\n              \"جوان\",\n              \"جويليه\",\n              \"أوت\",\n              \"سبتمبر\",\n              \"أكتوبر\",\n              \"نوفمبر\",\n              \"ديسمبر\",\n          ],\n      },\n      firstDayOfWeek: 0,\n      rangeSeparator: \" إلى \",\n      weekAbbreviation: \"Wk\",\n      scrollTitle: \"قم بالتمرير للزيادة\",\n      toggleTitle: \"اضغط للتبديل\",\n      yearAriaLabel: \"سنة\",\n      monthAriaLabel: \"شهر\",\n      hourAriaLabel: \"ساعة\",\n      minuteAriaLabel: \"دقيقة\",\n      time_24hr: true,\n  };\n  fp.l10ns.ar = AlgerianArabic;\n  var arDz = fp.l10ns;\n\n  exports.AlgerianArabic = AlgerianArabic;\n  exports.default = arDz;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ar = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Arabic = {\n      weekdays: {\n          shorthand: [\"أحد\", \"اثنين\", \"ثلاثاء\", \"أربعاء\", \"خميس\", \"جمعة\", \"سبت\"],\n          longhand: [\n              \"الأحد\",\n              \"الاثنين\",\n              \"الثلاثاء\",\n              \"الأربعاء\",\n              \"الخميس\",\n              \"الجمعة\",\n              \"السبت\",\n          ],\n      },\n      months: {\n          shorthand: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n          longhand: [\n              \"يناير\",\n              \"فبراير\",\n              \"مارس\",\n              \"أبريل\",\n              \"مايو\",\n              \"يونيو\",\n              \"يوليو\",\n              \"أغسطس\",\n              \"سبتمبر\",\n              \"أكتوبر\",\n              \"نوفمبر\",\n              \"ديسمبر\",\n          ],\n      },\n      firstDayOfWeek: 6,\n      rangeSeparator: \" إلى \",\n      weekAbbreviation: \"Wk\",\n      scrollTitle: \"قم بالتمرير للزيادة\",\n      toggleTitle: \"اضغط للتبديل\",\n      amPM: [\"ص\", \"م\"],\n      yearAriaLabel: \"سنة\",\n      monthAriaLabel: \"شهر\",\n      hourAriaLabel: \"ساعة\",\n      minuteAriaLabel: \"دقيقة\",\n      time_24hr: false,\n  };\n  fp.l10ns.ar = Arabic;\n  var ar = fp.l10ns;\n\n  exports.Arabic = Arabic;\n  exports.default = ar;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.at = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Austria = {\n      weekdays: {\n          shorthand: [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\"],\n          longhand: [\n              \"Sonntag\",\n              \"Montag\",\n              \"Dienstag\",\n              \"Mittwoch\",\n              \"Donnerstag\",\n              \"Freitag\",\n              \"Samstag\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jän\",\n              \"Feb\",\n              \"Mär\",\n              \"Apr\",\n              \"Mai\",\n              \"Jun\",\n              \"Jul\",\n              \"Aug\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dez\",\n          ],\n          longhand: [\n              \"Jänner\",\n              \"Februar\",\n              \"März\",\n              \"April\",\n              \"Mai\",\n              \"Juni\",\n              \"Juli\",\n              \"August\",\n              \"September\",\n              \"Oktober\",\n              \"November\",\n              \"Dezember\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      weekAbbreviation: \"KW\",\n      rangeSeparator: \" bis \",\n      scrollTitle: \"Zum Ändern scrollen\",\n      toggleTitle: \"Zum Umschalten klicken\",\n      time_24hr: true,\n  };\n  fp.l10ns.at = Austria;\n  var at = fp.l10ns;\n\n  exports.Austria = Austria;\n  exports.default = at;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.az = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Azerbaijan = {\n      weekdays: {\n          shorthand: [\"B.\", \"B.e.\", \"Ç.a.\", \"Ç.\", \"C.a.\", \"C.\", \"Ş.\"],\n          longhand: [\n              \"Bazar\",\n              \"Bazar ertəsi\",\n              \"Çərşənbə axşamı\",\n              \"Çərşənbə\",\n              \"Cümə axşamı\",\n              \"Cümə\",\n              \"Şənbə\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Yan\",\n              \"Fev\",\n              \"Mar\",\n              \"Apr\",\n              \"May\",\n              \"İyn\",\n              \"İyl\",\n              \"Avq\",\n              \"Sen\",\n              \"Okt\",\n              \"Noy\",\n              \"Dek\",\n          ],\n          longhand: [\n              \"Yanvar\",\n              \"Fevral\",\n              \"Mart\",\n              \"Aprel\",\n              \"May\",\n              \"İyun\",\n              \"İyul\",\n              \"Avqust\",\n              \"Sentyabr\",\n              \"Oktyabr\",\n              \"Noyabr\",\n              \"Dekabr\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \".\";\n      },\n      rangeSeparator: \" - \",\n      weekAbbreviation: \"Hf\",\n      scrollTitle: \"Artırmaq üçün sürüşdürün\",\n      toggleTitle: \"Aç / Bağla\",\n      amPM: [\"GƏ\", \"GS\"],\n      time_24hr: true,\n  };\n  fp.l10ns.az = Azerbaijan;\n  var az = fp.l10ns;\n\n  exports.Azerbaijan = Azerbaijan;\n  exports.default = az;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.be = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Belarusian = {\n      weekdays: {\n          shorthand: [\"Нд\", \"Пн\", \"Аў\", \"Ср\", \"Чц\", \"Пт\", \"Сб\"],\n          longhand: [\n              \"Нядзеля\",\n              \"Панядзелак\",\n              \"Аўторак\",\n              \"Серада\",\n              \"Чацвер\",\n              \"Пятніца\",\n              \"Субота\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Сту\",\n              \"Лют\",\n              \"Сак\",\n              \"Кра\",\n              \"Тра\",\n              \"Чэр\",\n              \"Ліп\",\n              \"Жні\",\n              \"Вер\",\n              \"Кас\",\n              \"Ліс\",\n              \"Сне\",\n          ],\n          longhand: [\n              \"Студзень\",\n              \"Люты\",\n              \"Сакавік\",\n              \"Красавік\",\n              \"Травень\",\n              \"Чэрвень\",\n              \"Ліпень\",\n              \"Жнівень\",\n              \"Верасень\",\n              \"Кастрычнік\",\n              \"Лістапад\",\n              \"Снежань\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      rangeSeparator: \" — \",\n      weekAbbreviation: \"Тыд.\",\n      scrollTitle: \"Пракруціце для павелічэння\",\n      toggleTitle: \"Націсніце для пераключэння\",\n      amPM: [\"ДП\", \"ПП\"],\n      yearAriaLabel: \"Год\",\n      time_24hr: true,\n  };\n  fp.l10ns.be = Belarusian;\n  var be = fp.l10ns;\n\n  exports.Belarusian = Belarusian;\n  exports.default = be;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.bg = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Bulgarian = {\n      weekdays: {\n          shorthand: [\"Нд\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\"],\n          longhand: [\n              \"Неделя\",\n              \"Понеделник\",\n              \"Вторник\",\n              \"Сряда\",\n              \"Четвъртък\",\n              \"Петък\",\n              \"Събота\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Яну\",\n              \"Фев\",\n              \"Март\",\n              \"Апр\",\n              \"Май\",\n              \"Юни\",\n              \"Юли\",\n              \"Авг\",\n              \"Сеп\",\n              \"Окт\",\n              \"Ное\",\n              \"Дек\",\n          ],\n          longhand: [\n              \"Януари\",\n              \"Февруари\",\n              \"Март\",\n              \"Април\",\n              \"Май\",\n              \"Юни\",\n              \"Юли\",\n              \"Август\",\n              \"Септември\",\n              \"Октомври\",\n              \"Ноември\",\n              \"Декември\",\n          ],\n      },\n      time_24hr: true,\n      firstDayOfWeek: 1,\n  };\n  fp.l10ns.bg = Bulgarian;\n  var bg = fp.l10ns;\n\n  exports.Bulgarian = Bulgarian;\n  exports.default = bg;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.bn = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Bangla = {\n      weekdays: {\n          shorthand: [\"রবি\", \"সোম\", \"মঙ্গল\", \"বুধ\", \"বৃহস্পতি\", \"শুক্র\", \"শনি\"],\n          longhand: [\n              \"রবিবার\",\n              \"সোমবার\",\n              \"মঙ্গলবার\",\n              \"বুধবার\",\n              \"বৃহস্পতিবার\",\n              \"শুক্রবার\",\n              \"শনিবার\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"জানু\",\n              \"ফেব্রু\",\n              \"মার্চ\",\n              \"এপ্রিল\",\n              \"মে\",\n              \"জুন\",\n              \"জুলাই\",\n              \"আগ\",\n              \"সেপ্টে\",\n              \"অক্টো\",\n              \"নভে\",\n              \"ডিসে\",\n          ],\n          longhand: [\n              \"জানুয়ারী\",\n              \"ফেব্রুয়ারী\",\n              \"মার্চ\",\n              \"এপ্রিল\",\n              \"মে\",\n              \"জুন\",\n              \"জুলাই\",\n              \"আগস্ট\",\n              \"সেপ্টেম্বর\",\n              \"অক্টোবর\",\n              \"নভেম্বর\",\n              \"ডিসেম্বর\",\n          ],\n      },\n  };\n  fp.l10ns.bn = Bangla;\n  var bn = fp.l10ns;\n\n  exports.Bangla = Bangla;\n  exports.default = bn;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.bs = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Bosnian = {\n      firstDayOfWeek: 1,\n      weekdays: {\n          shorthand: [\"Ned\", \"Pon\", \"Uto\", \"Sri\", \"Čet\", \"Pet\", \"Sub\"],\n          longhand: [\n              \"Nedjelja\",\n              \"Ponedjeljak\",\n              \"Utorak\",\n              \"Srijeda\",\n              \"Četvrtak\",\n              \"Petak\",\n              \"Subota\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Maj\",\n              \"Jun\",\n              \"Jul\",\n              \"Avg\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dec\",\n          ],\n          longhand: [\n              \"Januar\",\n              \"Februar\",\n              \"Mart\",\n              \"April\",\n              \"Maj\",\n              \"Juni\",\n              \"Juli\",\n              \"Avgust\",\n              \"Septembar\",\n              \"Oktobar\",\n              \"Novembar\",\n              \"Decembar\",\n          ],\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.bs = Bosnian;\n  var bs = fp.l10ns;\n\n  exports.Bosnian = Bosnian;\n  exports.default = bs;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.cat = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Catalan = {\n      weekdays: {\n          shorthand: [\"Dg\", \"Dl\", \"Dt\", \"Dc\", \"Dj\", \"Dv\", \"Ds\"],\n          longhand: [\n              \"Diumenge\",\n              \"Dilluns\",\n              \"Dimarts\",\n              \"Dimecres\",\n              \"Dijous\",\n              \"Divendres\",\n              \"Dissabte\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Gen\",\n              \"Febr\",\n              \"Març\",\n              \"Abr\",\n              \"Maig\",\n              \"Juny\",\n              \"Jul\",\n              \"Ag\",\n              \"Set\",\n              \"Oct\",\n              \"Nov\",\n              \"Des\",\n          ],\n          longhand: [\n              \"Gener\",\n              \"Febrer\",\n              \"Març\",\n              \"Abril\",\n              \"Maig\",\n              \"Juny\",\n              \"Juliol\",\n              \"Agost\",\n              \"Setembre\",\n              \"Octubre\",\n              \"Novembre\",\n              \"Desembre\",\n          ],\n      },\n      ordinal: function (nth) {\n          var s = nth % 100;\n          if (s > 3 && s < 21)\n              return \"è\";\n          switch (s % 10) {\n              case 1:\n                  return \"r\";\n              case 2:\n                  return \"n\";\n              case 3:\n                  return \"r\";\n              case 4:\n                  return \"t\";\n              default:\n                  return \"è\";\n          }\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" a \",\n      time_24hr: true,\n  };\n  fp.l10ns.cat = fp.l10ns.ca = Catalan;\n  var cat = fp.l10ns;\n\n  exports.Catalan = Catalan;\n  exports.default = cat;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ckb = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Kurdish = {\n      weekdays: {\n          shorthand: [\"یەکشەممە\", \"دووشەممە\", \"سێشەممە\", \"چوارشەممە\", \"پێنجشەممە\", \"هەینی\", \"شەممە\"],\n          longhand: [\n              \"یەکشەممە\",\n              \"دووشەممە\",\n              \"سێشەممە\",\n              \"چوارشەممە\",\n              \"پێنجشەممە\",\n              \"هەینی\",\n              \"شەممە\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"ڕێبەندان\",\n              \"ڕەشەمە\",\n              \"نەورۆز\",\n              \"گوڵان\",\n              \"جۆزەردان\",\n              \"پووشپەڕ\",\n              \"گەلاوێژ\",\n              \"خەرمانان\",\n              \"ڕەزبەر\",\n              \"گەڵاڕێزان\",\n              \"سەرماوەز\",\n              \"بەفرانبار\",\n          ],\n          longhand: [\n              \"ڕێبەندان\",\n              \"ڕەشەمە\",\n              \"نەورۆز\",\n              \"گوڵان\",\n              \"جۆزەردان\",\n              \"پووشپەڕ\",\n              \"گەلاوێژ\",\n              \"خەرمانان\",\n              \"ڕەزبەر\",\n              \"گەڵاڕێزان\",\n              \"سەرماوەز\",\n              \"بەفرانبار\",\n          ],\n      },\n      firstDayOfWeek: 6,\n      ordinal: function () {\n          return \"\";\n      },\n  };\n  fp.l10ns.ckb = Kurdish;\n  var ckb = fp.l10ns;\n\n  exports.Kurdish = Kurdish;\n  exports.default = ckb;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.cs = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Czech = {\n      weekdays: {\n          shorthand: [\"Ne\", \"Po\", \"Út\", \"St\", \"Čt\", \"Pá\", \"So\"],\n          longhand: [\n              \"Neděle\",\n              \"Pondělí\",\n              \"Úterý\",\n              \"Středa\",\n              \"Čtvrtek\",\n              \"Pátek\",\n              \"Sobota\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Led\",\n              \"Ún\",\n              \"Bře\",\n              \"Dub\",\n              \"Kvě\",\n              \"Čer\",\n              \"Čvc\",\n              \"Srp\",\n              \"Zář\",\n              \"Říj\",\n              \"Lis\",\n              \"Pro\",\n          ],\n          longhand: [\n              \"Leden\",\n              \"Únor\",\n              \"Březen\",\n              \"Duben\",\n              \"Květen\",\n              \"Červen\",\n              \"Červenec\",\n              \"Srpen\",\n              \"Září\",\n              \"Říjen\",\n              \"Listopad\",\n              \"Prosinec\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \".\";\n      },\n      rangeSeparator: \" do \",\n      weekAbbreviation: \"Týd.\",\n      scrollTitle: \"Rolujte pro změnu\",\n      toggleTitle: \"Přepnout dopoledne/odpoledne\",\n      amPM: [\"dop.\", \"odp.\"],\n      yearAriaLabel: \"Rok\",\n      time_24hr: true,\n  };\n  fp.l10ns.cs = Czech;\n  var cs = fp.l10ns;\n\n  exports.Czech = Czech;\n  exports.default = cs;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.cy = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Welsh = {\n      weekdays: {\n          shorthand: [\"Sul\", \"Llun\", \"Maw\", \"Mer\", \"Iau\", \"Gwe\", \"Sad\"],\n          longhand: [\n              \"Dydd Sul\",\n              \"Dydd Llun\",\n              \"Dydd Mawrth\",\n              \"Dydd Mercher\",\n              \"Dydd Iau\",\n              \"Dydd Gwener\",\n              \"Dydd Sadwrn\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Ion\",\n              \"Chwef\",\n              \"Maw\",\n              \"Ebr\",\n              \"Mai\",\n              \"Meh\",\n              \"Gorff\",\n              \"Awst\",\n              \"Medi\",\n              \"Hyd\",\n              \"Tach\",\n              \"Rhag\",\n          ],\n          longhand: [\n              \"Ionawr\",\n              \"Chwefror\",\n              \"Mawrth\",\n              \"Ebrill\",\n              \"Mai\",\n              \"Mehefin\",\n              \"Gorffennaf\",\n              \"Awst\",\n              \"Medi\",\n              \"Hydref\",\n              \"Tachwedd\",\n              \"Rhagfyr\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function (nth) {\n          if (nth === 1)\n              return \"af\";\n          if (nth === 2)\n              return \"ail\";\n          if (nth === 3 || nth === 4)\n              return \"ydd\";\n          if (nth === 5 || nth === 6)\n              return \"ed\";\n          if ((nth >= 7 && nth <= 10) ||\n              nth == 12 ||\n              nth == 15 ||\n              nth == 18 ||\n              nth == 20)\n              return \"fed\";\n          if (nth == 11 ||\n              nth == 13 ||\n              nth == 14 ||\n              nth == 16 ||\n              nth == 17 ||\n              nth == 19)\n              return \"eg\";\n          if (nth >= 21 && nth <= 39)\n              return \"ain\";\n          // Inconclusive.\n          return \"\";\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.cy = Welsh;\n  var cy = fp.l10ns;\n\n  exports.Welsh = Welsh;\n  exports.default = cy;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.da = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Danish = {\n      weekdays: {\n          shorthand: [\"søn\", \"man\", \"tir\", \"ons\", \"tors\", \"fre\", \"lør\"],\n          longhand: [\n              \"søndag\",\n              \"mandag\",\n              \"tirsdag\",\n              \"onsdag\",\n              \"torsdag\",\n              \"fredag\",\n              \"lørdag\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"jan\",\n              \"feb\",\n              \"mar\",\n              \"apr\",\n              \"maj\",\n              \"jun\",\n              \"jul\",\n              \"aug\",\n              \"sep\",\n              \"okt\",\n              \"nov\",\n              \"dec\",\n          ],\n          longhand: [\n              \"januar\",\n              \"februar\",\n              \"marts\",\n              \"april\",\n              \"maj\",\n              \"juni\",\n              \"juli\",\n              \"august\",\n              \"september\",\n              \"oktober\",\n              \"november\",\n              \"december\",\n          ],\n      },\n      ordinal: function () {\n          return \".\";\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" til \",\n      weekAbbreviation: \"uge\",\n      time_24hr: true,\n  };\n  fp.l10ns.da = Danish;\n  var da = fp.l10ns;\n\n  exports.Danish = Danish;\n  exports.default = da;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.de = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var German = {\n      weekdays: {\n          shorthand: [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\"],\n          longhand: [\n              \"Sonntag\",\n              \"Montag\",\n              \"Dienstag\",\n              \"Mittwoch\",\n              \"Donnerstag\",\n              \"Freitag\",\n              \"Samstag\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mär\",\n              \"Apr\",\n              \"Mai\",\n              \"Jun\",\n              \"Jul\",\n              \"Aug\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dez\",\n          ],\n          longhand: [\n              \"Januar\",\n              \"Februar\",\n              \"März\",\n              \"April\",\n              \"Mai\",\n              \"Juni\",\n              \"Juli\",\n              \"August\",\n              \"September\",\n              \"Oktober\",\n              \"November\",\n              \"Dezember\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      weekAbbreviation: \"KW\",\n      rangeSeparator: \" bis \",\n      scrollTitle: \"Zum Ändern scrollen\",\n      toggleTitle: \"Zum Umschalten klicken\",\n      time_24hr: true,\n  };\n  fp.l10ns.de = German;\n  var de = fp.l10ns;\n\n  exports.German = German;\n  exports.default = de;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.default = {}));\n}(this, (function (exports) { 'use strict';\n\n  var english = {\n      weekdays: {\n          shorthand: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n          longhand: [\n              \"Sunday\",\n              \"Monday\",\n              \"Tuesday\",\n              \"Wednesday\",\n              \"Thursday\",\n              \"Friday\",\n              \"Saturday\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"May\",\n              \"Jun\",\n              \"Jul\",\n              \"Aug\",\n              \"Sep\",\n              \"Oct\",\n              \"Nov\",\n              \"Dec\",\n          ],\n          longhand: [\n              \"January\",\n              \"February\",\n              \"March\",\n              \"April\",\n              \"May\",\n              \"June\",\n              \"July\",\n              \"August\",\n              \"September\",\n              \"October\",\n              \"November\",\n              \"December\",\n          ],\n      },\n      daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],\n      firstDayOfWeek: 0,\n      ordinal: function (nth) {\n          var s = nth % 100;\n          if (s > 3 && s < 21)\n              return \"th\";\n          switch (s % 10) {\n              case 1:\n                  return \"st\";\n              case 2:\n                  return \"nd\";\n              case 3:\n                  return \"rd\";\n              default:\n                  return \"th\";\n          }\n      },\n      rangeSeparator: \" to \",\n      weekAbbreviation: \"Wk\",\n      scrollTitle: \"Scroll to increment\",\n      toggleTitle: \"Click to toggle\",\n      amPM: [\"AM\", \"PM\"],\n      yearAriaLabel: \"Year\",\n      monthAriaLabel: \"Month\",\n      hourAriaLabel: \"Hour\",\n      minuteAriaLabel: \"Minute\",\n      time_24hr: false,\n  };\n\n  exports.default = english;\n  exports.english = english;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.eo = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Esperanto = {\n      firstDayOfWeek: 1,\n      rangeSeparator: \" ĝis \",\n      weekAbbreviation: \"Sem\",\n      scrollTitle: \"Rulumu por pligrandigi la valoron\",\n      toggleTitle: \"Klaku por ŝalti\",\n      weekdays: {\n          shorthand: [\"Dim\", \"Lun\", \"Mar\", \"Mer\", \"Ĵaŭ\", \"Ven\", \"Sab\"],\n          longhand: [\n              \"dimanĉo\",\n              \"lundo\",\n              \"mardo\",\n              \"merkredo\",\n              \"ĵaŭdo\",\n              \"vendredo\",\n              \"sabato\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Maj\",\n              \"Jun\",\n              \"Jul\",\n              \"Aŭg\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dec\",\n          ],\n          longhand: [\n              \"januaro\",\n              \"februaro\",\n              \"marto\",\n              \"aprilo\",\n              \"majo\",\n              \"junio\",\n              \"julio\",\n              \"aŭgusto\",\n              \"septembro\",\n              \"oktobro\",\n              \"novembro\",\n              \"decembro\",\n          ],\n      },\n      ordinal: function () {\n          return \"-a\";\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.eo = Esperanto;\n  var eo = fp.l10ns;\n\n  exports.Esperanto = Esperanto;\n  exports.default = eo;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.es = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Spanish = {\n      weekdays: {\n          shorthand: [\"Dom\", \"Lun\", \"Mar\", \"Mié\", \"Jue\", \"Vie\", \"Sáb\"],\n          longhand: [\n              \"Domingo\",\n              \"Lunes\",\n              \"Martes\",\n              \"Miércoles\",\n              \"Jueves\",\n              \"Viernes\",\n              \"Sábado\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Ene\",\n              \"Feb\",\n              \"Mar\",\n              \"Abr\",\n              \"May\",\n              \"Jun\",\n              \"Jul\",\n              \"Ago\",\n              \"Sep\",\n              \"Oct\",\n              \"Nov\",\n              \"Dic\",\n          ],\n          longhand: [\n              \"Enero\",\n              \"Febrero\",\n              \"Marzo\",\n              \"Abril\",\n              \"Mayo\",\n              \"Junio\",\n              \"Julio\",\n              \"Agosto\",\n              \"Septiembre\",\n              \"Octubre\",\n              \"Noviembre\",\n              \"Diciembre\",\n          ],\n      },\n      ordinal: function () {\n          return \"º\";\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" a \",\n      time_24hr: true,\n  };\n  fp.l10ns.es = Spanish;\n  var es = fp.l10ns;\n\n  exports.Spanish = Spanish;\n  exports.default = es;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.et = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Estonian = {\n      weekdays: {\n          shorthand: [\"P\", \"E\", \"T\", \"K\", \"N\", \"R\", \"L\"],\n          longhand: [\n              \"Pühapäev\",\n              \"Esmaspäev\",\n              \"Teisipäev\",\n              \"Kolmapäev\",\n              \"Neljapäev\",\n              \"Reede\",\n              \"Laupäev\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jaan\",\n              \"Veebr\",\n              \"Märts\",\n              \"Apr\",\n              \"Mai\",\n              \"Juuni\",\n              \"Juuli\",\n              \"Aug\",\n              \"Sept\",\n              \"Okt\",\n              \"Nov\",\n              \"Dets\",\n          ],\n          longhand: [\n              \"Jaanuar\",\n              \"Veebruar\",\n              \"Märts\",\n              \"Aprill\",\n              \"Mai\",\n              \"Juuni\",\n              \"Juuli\",\n              \"August\",\n              \"September\",\n              \"Oktoober\",\n              \"November\",\n              \"Detsember\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \".\";\n      },\n      weekAbbreviation: \"Näd\",\n      rangeSeparator: \" kuni \",\n      scrollTitle: \"Keri, et suurendada\",\n      toggleTitle: \"Klõpsa, et vahetada\",\n      time_24hr: true,\n  };\n  fp.l10ns.et = Estonian;\n  var et = fp.l10ns;\n\n  exports.Estonian = Estonian;\n  exports.default = et;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.fa = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Persian = {\n      weekdays: {\n          shorthand: [\"یک\", \"دو\", \"سه\", \"چهار\", \"پنج\", \"جمعه\", \"شنبه\"],\n          longhand: [\n              \"یک‌شنبه\",\n              \"دوشنبه\",\n              \"سه‌شنبه\",\n              \"چهارشنبه\",\n              \"پنچ‌شنبه\",\n              \"جمعه\",\n              \"شنبه\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"ژانویه\",\n              \"فوریه\",\n              \"مارس\",\n              \"آوریل\",\n              \"مه\",\n              \"ژوئن\",\n              \"ژوئیه\",\n              \"اوت\",\n              \"سپتامبر\",\n              \"اکتبر\",\n              \"نوامبر\",\n              \"دسامبر\",\n          ],\n          longhand: [\n              \"ژانویه\",\n              \"فوریه\",\n              \"مارس\",\n              \"آوریل\",\n              \"مه\",\n              \"ژوئن\",\n              \"ژوئیه\",\n              \"اوت\",\n              \"سپتامبر\",\n              \"اکتبر\",\n              \"نوامبر\",\n              \"دسامبر\",\n          ],\n      },\n      firstDayOfWeek: 6,\n      ordinal: function () {\n          return \"\";\n      },\n  };\n  fp.l10ns.fa = Persian;\n  var fa = fp.l10ns;\n\n  exports.Persian = Persian;\n  exports.default = fa;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.fi = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Finnish = {\n      firstDayOfWeek: 1,\n      weekdays: {\n          shorthand: [\"su\", \"ma\", \"ti\", \"ke\", \"to\", \"pe\", \"la\"],\n          longhand: [\n              \"sunnuntai\",\n              \"maanantai\",\n              \"tiistai\",\n              \"keskiviikko\",\n              \"torstai\",\n              \"perjantai\",\n              \"lauantai\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"tammi\",\n              \"helmi\",\n              \"maalis\",\n              \"huhti\",\n              \"touko\",\n              \"kesä\",\n              \"heinä\",\n              \"elo\",\n              \"syys\",\n              \"loka\",\n              \"marras\",\n              \"joulu\",\n          ],\n          longhand: [\n              \"tammikuu\",\n              \"helmikuu\",\n              \"maaliskuu\",\n              \"huhtikuu\",\n              \"toukokuu\",\n              \"kesäkuu\",\n              \"heinäkuu\",\n              \"elokuu\",\n              \"syyskuu\",\n              \"lokakuu\",\n              \"marraskuu\",\n              \"joulukuu\",\n          ],\n      },\n      ordinal: function () {\n          return \".\";\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.fi = Finnish;\n  var fi = fp.l10ns;\n\n  exports.Finnish = Finnish;\n  exports.default = fi;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.fo = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Faroese = {\n      weekdays: {\n          shorthand: [\"Sun\", \"Mán\", \"Týs\", \"Mik\", \"Hós\", \"Frí\", \"Ley\"],\n          longhand: [\n              \"Sunnudagur\",\n              \"Mánadagur\",\n              \"Týsdagur\",\n              \"Mikudagur\",\n              \"Hósdagur\",\n              \"Fríggjadagur\",\n              \"Leygardagur\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Mai\",\n              \"Jun\",\n              \"Jul\",\n              \"Aug\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Des\",\n          ],\n          longhand: [\n              \"Januar\",\n              \"Februar\",\n              \"Mars\",\n              \"Apríl\",\n              \"Mai\",\n              \"Juni\",\n              \"Juli\",\n              \"August\",\n              \"Septembur\",\n              \"Oktobur\",\n              \"Novembur\",\n              \"Desembur\",\n          ],\n      },\n      ordinal: function () {\n          return \".\";\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" til \",\n      weekAbbreviation: \"vika\",\n      scrollTitle: \"Rulla fyri at broyta\",\n      toggleTitle: \"Trýst fyri at skifta\",\n      yearAriaLabel: \"Ár\",\n      time_24hr: true,\n  };\n  fp.l10ns.fo = Faroese;\n  var fo = fp.l10ns;\n\n  exports.Faroese = Faroese;\n  exports.default = fo;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.fr = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var French = {\n      firstDayOfWeek: 1,\n      weekdays: {\n          shorthand: [\"dim\", \"lun\", \"mar\", \"mer\", \"jeu\", \"ven\", \"sam\"],\n          longhand: [\n              \"dimanche\",\n              \"lundi\",\n              \"mardi\",\n              \"mercredi\",\n              \"jeudi\",\n              \"vendredi\",\n              \"samedi\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"janv\",\n              \"févr\",\n              \"mars\",\n              \"avr\",\n              \"mai\",\n              \"juin\",\n              \"juil\",\n              \"août\",\n              \"sept\",\n              \"oct\",\n              \"nov\",\n              \"déc\",\n          ],\n          longhand: [\n              \"janvier\",\n              \"février\",\n              \"mars\",\n              \"avril\",\n              \"mai\",\n              \"juin\",\n              \"juillet\",\n              \"août\",\n              \"septembre\",\n              \"octobre\",\n              \"novembre\",\n              \"décembre\",\n          ],\n      },\n      ordinal: function (nth) {\n          if (nth > 1)\n              return \"\";\n          return \"er\";\n      },\n      rangeSeparator: \" au \",\n      weekAbbreviation: \"Sem\",\n      scrollTitle: \"Défiler pour augmenter la valeur\",\n      toggleTitle: \"Cliquer pour basculer\",\n      time_24hr: true,\n  };\n  fp.l10ns.fr = French;\n  var fr = fp.l10ns;\n\n  exports.French = French;\n  exports.default = fr;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ga = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Irish = {\n      firstDayOfWeek: 1,\n      weekdays: {\n          shorthand: [\"Dom\", \"Lua\", \"Mái\", \"Céa\", \"Déa\", \"Aoi\", \"Sat\"],\n          longhand: [\n              \"Dé Domhnaigh\",\n              \"Dé Luain\",\n              \"Dé Máirt\",\n              \"Dé Céadaoin\",\n              \"Déardaoin\",\n              \"Dé hAoine\",\n              \"Dé Sathairn\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Ean\",\n              \"Fea\",\n              \"Már\",\n              \"Aib\",\n              \"Bea\",\n              \"Mei\",\n              \"Iúi\",\n              \"Lún\",\n              \"MFo\",\n              \"DFo\",\n              \"Sam\",\n              \"Nol\",\n          ],\n          longhand: [\n              \"Eanáir\",\n              \"Feabhra\",\n              \"Márta\",\n              \"Aibreán\",\n              \"Bealtaine\",\n              \"Meitheamh\",\n              \"Iúil\",\n              \"Lúnasa\",\n              \"Meán Fómhair\",\n              \"Deireadh Fómhair\",\n              \"Samhain\",\n              \"Nollaig\",\n          ],\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.hr = Irish;\n  var ga = fp.l10ns;\n\n  exports.Irish = Irish;\n  exports.default = ga;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.gr = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Greek = {\n      weekdays: {\n          shorthand: [\"Κυ\", \"Δε\", \"Τρ\", \"Τε\", \"Πέ\", \"Πα\", \"Σά\"],\n          longhand: [\n              \"Κυριακή\",\n              \"Δευτέρα\",\n              \"Τρίτη\",\n              \"Τετάρτη\",\n              \"Πέμπτη\",\n              \"Παρασκευή\",\n              \"Σάββατο\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Ιαν\",\n              \"Φεβ\",\n              \"Μάρ\",\n              \"Απρ\",\n              \"Μάι\",\n              \"Ιούν\",\n              \"Ιούλ\",\n              \"Αύγ\",\n              \"Σεπ\",\n              \"Οκτ\",\n              \"Νοέ\",\n              \"Δεκ\",\n          ],\n          longhand: [\n              \"Ιανουάριος\",\n              \"Φεβρουάριος\",\n              \"Μάρτιος\",\n              \"Απρίλιος\",\n              \"Μάιος\",\n              \"Ιούνιος\",\n              \"Ιούλιος\",\n              \"Αύγουστος\",\n              \"Σεπτέμβριος\",\n              \"Οκτώβριος\",\n              \"Νοέμβριος\",\n              \"Δεκέμβριος\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      weekAbbreviation: \"Εβδ\",\n      rangeSeparator: \" έως \",\n      scrollTitle: \"Μετακυλήστε για προσαύξηση\",\n      toggleTitle: \"Κάντε κλικ για αλλαγή\",\n      amPM: [\"ΠΜ\", \"ΜΜ\"],\n      yearAriaLabel: \"χρόνος\",\n      monthAriaLabel: \"μήνας\",\n      hourAriaLabel: \"ώρα\",\n      minuteAriaLabel: \"λεπτό\",\n  };\n  fp.l10ns.gr = Greek;\n  var gr = fp.l10ns;\n\n  exports.Greek = Greek;\n  exports.default = gr;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.he = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Hebrew = {\n      weekdays: {\n          shorthand: [\"א\", \"ב\", \"ג\", \"ד\", \"ה\", \"ו\", \"ש\"],\n          longhand: [\"ראשון\", \"שני\", \"שלישי\", \"רביעי\", \"חמישי\", \"שישי\", \"שבת\"],\n      },\n      months: {\n          shorthand: [\n              \"ינו׳\",\n              \"פבר׳\",\n              \"מרץ\",\n              \"אפר׳\",\n              \"מאי\",\n              \"יוני\",\n              \"יולי\",\n              \"אוג׳\",\n              \"ספט׳\",\n              \"אוק׳\",\n              \"נוב׳\",\n              \"דצמ׳\",\n          ],\n          longhand: [\n              \"ינואר\",\n              \"פברואר\",\n              \"מרץ\",\n              \"אפריל\",\n              \"מאי\",\n              \"יוני\",\n              \"יולי\",\n              \"אוגוסט\",\n              \"ספטמבר\",\n              \"אוקטובר\",\n              \"נובמבר\",\n              \"דצמבר\",\n          ],\n      },\n      rangeSeparator: \" אל \",\n      time_24hr: true,\n  };\n  fp.l10ns.he = Hebrew;\n  var he = fp.l10ns;\n\n  exports.Hebrew = Hebrew;\n  exports.default = he;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.hi = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Hindi = {\n      weekdays: {\n          shorthand: [\"रवि\", \"सोम\", \"मंगल\", \"बुध\", \"गुरु\", \"शुक्र\", \"शनि\"],\n          longhand: [\n              \"रविवार\",\n              \"सोमवार\",\n              \"मंगलवार\",\n              \"बुधवार\",\n              \"गुरुवार\",\n              \"शुक्रवार\",\n              \"शनिवार\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"जन\",\n              \"फर\",\n              \"मार्च\",\n              \"अप्रेल\",\n              \"मई\",\n              \"जून\",\n              \"जूलाई\",\n              \"अग\",\n              \"सित\",\n              \"अक्ट\",\n              \"नव\",\n              \"दि\",\n          ],\n          longhand: [\n              \"जनवरी \",\n              \"फरवरी\",\n              \"मार्च\",\n              \"अप्रेल\",\n              \"मई\",\n              \"जून\",\n              \"जूलाई\",\n              \"अगस्त \",\n              \"सितम्बर\",\n              \"अक्टूबर\",\n              \"नवम्बर\",\n              \"दिसम्बर\",\n          ],\n      },\n  };\n  fp.l10ns.hi = Hindi;\n  var hi = fp.l10ns;\n\n  exports.Hindi = Hindi;\n  exports.default = hi;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.hr = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Croatian = {\n      firstDayOfWeek: 1,\n      weekdays: {\n          shorthand: [\"Ned\", \"Pon\", \"Uto\", \"Sri\", \"Čet\", \"Pet\", \"Sub\"],\n          longhand: [\n              \"Nedjelja\",\n              \"Ponedjeljak\",\n              \"Utorak\",\n              \"Srijeda\",\n              \"Četvrtak\",\n              \"Petak\",\n              \"Subota\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Sij\",\n              \"Velj\",\n              \"Ožu\",\n              \"Tra\",\n              \"Svi\",\n              \"Lip\",\n              \"Srp\",\n              \"Kol\",\n              \"Ruj\",\n              \"Lis\",\n              \"Stu\",\n              \"Pro\",\n          ],\n          longhand: [\n              \"Siječanj\",\n              \"Veljača\",\n              \"Ožujak\",\n              \"Travanj\",\n              \"Svibanj\",\n              \"Lipanj\",\n              \"Srpanj\",\n              \"Kolovoz\",\n              \"Rujan\",\n              \"Listopad\",\n              \"Studeni\",\n              \"Prosinac\",\n          ],\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.hr = Croatian;\n  var hr = fp.l10ns;\n\n  exports.Croatian = Croatian;\n  exports.default = hr;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.hu = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Hungarian = {\n      firstDayOfWeek: 1,\n      weekdays: {\n          shorthand: [\"V\", \"H\", \"K\", \"Sz\", \"Cs\", \"P\", \"Szo\"],\n          longhand: [\n              \"Vasárnap\",\n              \"Hétfő\",\n              \"Kedd\",\n              \"Szerda\",\n              \"Csütörtök\",\n              \"Péntek\",\n              \"Szombat\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Már\",\n              \"Ápr\",\n              \"Máj\",\n              \"Jún\",\n              \"Júl\",\n              \"Aug\",\n              \"Szep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dec\",\n          ],\n          longhand: [\n              \"Január\",\n              \"Február\",\n              \"Március\",\n              \"Április\",\n              \"Május\",\n              \"Június\",\n              \"Július\",\n              \"Augusztus\",\n              \"Szeptember\",\n              \"Október\",\n              \"November\",\n              \"December\",\n          ],\n      },\n      ordinal: function () {\n          return \".\";\n      },\n      weekAbbreviation: \"Hét\",\n      scrollTitle: \"Görgessen\",\n      toggleTitle: \"Kattintson a váltáshoz\",\n      rangeSeparator: \" - \",\n      time_24hr: true,\n  };\n  fp.l10ns.hu = Hungarian;\n  var hu = fp.l10ns;\n\n  exports.Hungarian = Hungarian;\n  exports.default = hu;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.hy = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Armenian = {\n      weekdays: {\n          shorthand: [\n              \"Կիր\",\n              \"Երկ\",\n              \"Երք\",\n              \"Չրք\",\n              \"Հնգ\",\n              \"Ուրբ\",\n              \"Շբթ\",\n          ],\n          longhand: [\n              \"Կիրակի\",\n              \"Եկուշաբթի\",\n              \"Երեքշաբթի\",\n              \"Չորեքշաբթի\",\n              \"Հինգշաբթի\",\n              \"Ուրբաթ\",\n              \"Շաբաթ\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Հնվ\",\n              \"Փտր\",\n              \"Մար\",\n              \"Ապր\",\n              \"Մայ\",\n              \"Հնս\",\n              \"Հլս\",\n              \"Օգս\",\n              \"Սեպ\",\n              \"Հոկ\",\n              \"Նմբ\",\n              \"Դեկ\",\n          ],\n          longhand: [\n              \"Հունվար\",\n              \"Փետրվար\",\n              \"Մարտ\",\n              \"Ապրիլ\",\n              \"Մայիս\",\n              \"Հունիս\",\n              \"Հուլիս\",\n              \"Օգոստոս\",\n              \"Սեպտեմբեր\",\n              \"Հոկտեմբեր\",\n              \"Նոյեմբեր\",\n              \"Դեկտեմբեր\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      rangeSeparator: \" — \",\n      weekAbbreviation: \"ՇԲՏ\",\n      scrollTitle: \"Ոլորեք՝ մեծացնելու համար\",\n      toggleTitle: \"Սեղմեք՝ փոխելու համար\",\n      amPM: [\"ՄԿ\", \"ԿՀ\"],\n      yearAriaLabel: \"Տարի\",\n      monthAriaLabel: \"Ամիս\",\n      hourAriaLabel: \"Ժամ\",\n      minuteAriaLabel: \"Րոպե\",\n      time_24hr: true,\n  };\n  fp.l10ns.hy = Armenian;\n  var hy = fp.l10ns;\n\n  exports.Armenian = Armenian;\n  exports.default = hy;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.id = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Indonesian = {\n      weekdays: {\n          shorthand: [\"Min\", \"Sen\", \"Sel\", \"Rab\", \"Kam\", \"Jum\", \"Sab\"],\n          longhand: [\"Minggu\", \"Senin\", \"Selasa\", \"Rabu\", \"Kamis\", \"Jumat\", \"Sabtu\"],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Mei\",\n              \"Jun\",\n              \"Jul\",\n              \"Agu\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Des\",\n          ],\n          longhand: [\n              \"Januari\",\n              \"Februari\",\n              \"Maret\",\n              \"April\",\n              \"Mei\",\n              \"Juni\",\n              \"Juli\",\n              \"Agustus\",\n              \"September\",\n              \"Oktober\",\n              \"November\",\n              \"Desember\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      time_24hr: true,\n      rangeSeparator: \" - \",\n  };\n  fp.l10ns.id = Indonesian;\n  var id = fp.l10ns;\n\n  exports.Indonesian = Indonesian;\n  exports.default = id;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n    typeof define === 'function' && define.amd ? define(['exports'], factory) :\n    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.index = {}));\n}(this, (function (exports) { 'use strict';\n\n    /*! *****************************************************************************\r\n    Copyright (c) Microsoft Corporation.\r\n\r\n    Permission to use, copy, modify, and/or distribute this software for any\r\n    purpose with or without fee is hereby granted.\r\n\r\n    THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\n    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\n    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\n    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\n    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\n    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\n    PERFORMANCE OF THIS SOFTWARE.\r\n    ***************************************************************************** */\r\n\r\n    var __assign = function() {\r\n        __assign = Object.assign || function __assign(t) {\r\n            for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n                s = arguments[i];\r\n                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n            }\r\n            return t;\r\n        };\r\n        return __assign.apply(this, arguments);\r\n    };\n\n    var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Arabic = {\n        weekdays: {\n            shorthand: [\"أحد\", \"اثنين\", \"ثلاثاء\", \"أربعاء\", \"خميس\", \"جمعة\", \"سبت\"],\n            longhand: [\n                \"الأحد\",\n                \"الاثنين\",\n                \"الثلاثاء\",\n                \"الأربعاء\",\n                \"الخميس\",\n                \"الجمعة\",\n                \"السبت\",\n            ],\n        },\n        months: {\n            shorthand: [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\"],\n            longhand: [\n                \"يناير\",\n                \"فبراير\",\n                \"مارس\",\n                \"أبريل\",\n                \"مايو\",\n                \"يونيو\",\n                \"يوليو\",\n                \"أغسطس\",\n                \"سبتمبر\",\n                \"أكتوبر\",\n                \"نوفمبر\",\n                \"ديسمبر\",\n            ],\n        },\n        firstDayOfWeek: 6,\n        rangeSeparator: \" إلى \",\n        weekAbbreviation: \"Wk\",\n        scrollTitle: \"قم بالتمرير للزيادة\",\n        toggleTitle: \"اضغط للتبديل\",\n        amPM: [\"ص\", \"م\"],\n        yearAriaLabel: \"سنة\",\n        monthAriaLabel: \"شهر\",\n        hourAriaLabel: \"ساعة\",\n        minuteAriaLabel: \"دقيقة\",\n        time_24hr: false,\n    };\n    fp.l10ns.ar = Arabic;\n    fp.l10ns;\n\n    var fp$1 = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Austria = {\n        weekdays: {\n            shorthand: [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\"],\n            longhand: [\n                \"Sonntag\",\n                \"Montag\",\n                \"Dienstag\",\n                \"Mittwoch\",\n                \"Donnerstag\",\n                \"Freitag\",\n                \"Samstag\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jän\",\n                \"Feb\",\n                \"Mär\",\n                \"Apr\",\n                \"Mai\",\n                \"Jun\",\n                \"Jul\",\n                \"Aug\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dez\",\n            ],\n            longhand: [\n                \"Jänner\",\n                \"Februar\",\n                \"März\",\n                \"April\",\n                \"Mai\",\n                \"Juni\",\n                \"Juli\",\n                \"August\",\n                \"September\",\n                \"Oktober\",\n                \"November\",\n                \"Dezember\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        weekAbbreviation: \"KW\",\n        rangeSeparator: \" bis \",\n        scrollTitle: \"Zum Ändern scrollen\",\n        toggleTitle: \"Zum Umschalten klicken\",\n        time_24hr: true,\n    };\n    fp$1.l10ns.at = Austria;\n    fp$1.l10ns;\n\n    var fp$2 = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Azerbaijan = {\n        weekdays: {\n            shorthand: [\"B.\", \"B.e.\", \"Ç.a.\", \"Ç.\", \"C.a.\", \"C.\", \"Ş.\"],\n            longhand: [\n                \"Bazar\",\n                \"Bazar ertəsi\",\n                \"Çərşənbə axşamı\",\n                \"Çərşənbə\",\n                \"Cümə axşamı\",\n                \"Cümə\",\n                \"Şənbə\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Yan\",\n                \"Fev\",\n                \"Mar\",\n                \"Apr\",\n                \"May\",\n                \"İyn\",\n                \"İyl\",\n                \"Avq\",\n                \"Sen\",\n                \"Okt\",\n                \"Noy\",\n                \"Dek\",\n            ],\n            longhand: [\n                \"Yanvar\",\n                \"Fevral\",\n                \"Mart\",\n                \"Aprel\",\n                \"May\",\n                \"İyun\",\n                \"İyul\",\n                \"Avqust\",\n                \"Sentyabr\",\n                \"Oktyabr\",\n                \"Noyabr\",\n                \"Dekabr\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \".\";\n        },\n        rangeSeparator: \" - \",\n        weekAbbreviation: \"Hf\",\n        scrollTitle: \"Artırmaq üçün sürüşdürün\",\n        toggleTitle: \"Aç / Bağla\",\n        amPM: [\"GƏ\", \"GS\"],\n        time_24hr: true,\n    };\n    fp$2.l10ns.az = Azerbaijan;\n    fp$2.l10ns;\n\n    var fp$3 = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Belarusian = {\n        weekdays: {\n            shorthand: [\"Нд\", \"Пн\", \"Аў\", \"Ср\", \"Чц\", \"Пт\", \"Сб\"],\n            longhand: [\n                \"Нядзеля\",\n                \"Панядзелак\",\n                \"Аўторак\",\n                \"Серада\",\n                \"Чацвер\",\n                \"Пятніца\",\n                \"Субота\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Сту\",\n                \"Лют\",\n                \"Сак\",\n                \"Кра\",\n                \"Тра\",\n                \"Чэр\",\n                \"Ліп\",\n                \"Жні\",\n                \"Вер\",\n                \"Кас\",\n                \"Ліс\",\n                \"Сне\",\n            ],\n            longhand: [\n                \"Студзень\",\n                \"Люты\",\n                \"Сакавік\",\n                \"Красавік\",\n                \"Травень\",\n                \"Чэрвень\",\n                \"Ліпень\",\n                \"Жнівень\",\n                \"Верасень\",\n                \"Кастрычнік\",\n                \"Лістапад\",\n                \"Снежань\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        rangeSeparator: \" — \",\n        weekAbbreviation: \"Тыд.\",\n        scrollTitle: \"Пракруціце для павелічэння\",\n        toggleTitle: \"Націсніце для пераключэння\",\n        amPM: [\"ДП\", \"ПП\"],\n        yearAriaLabel: \"Год\",\n        time_24hr: true,\n    };\n    fp$3.l10ns.be = Belarusian;\n    fp$3.l10ns;\n\n    var fp$4 = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Bosnian = {\n        firstDayOfWeek: 1,\n        weekdays: {\n            shorthand: [\"Ned\", \"Pon\", \"Uto\", \"Sri\", \"Čet\", \"Pet\", \"Sub\"],\n            longhand: [\n                \"Nedjelja\",\n                \"Ponedjeljak\",\n                \"Utorak\",\n                \"Srijeda\",\n                \"Četvrtak\",\n                \"Petak\",\n                \"Subota\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Maj\",\n                \"Jun\",\n                \"Jul\",\n                \"Avg\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"Januar\",\n                \"Februar\",\n                \"Mart\",\n                \"April\",\n                \"Maj\",\n                \"Juni\",\n                \"Juli\",\n                \"Avgust\",\n                \"Septembar\",\n                \"Oktobar\",\n                \"Novembar\",\n                \"Decembar\",\n            ],\n        },\n        time_24hr: true,\n    };\n    fp$4.l10ns.bs = Bosnian;\n    fp$4.l10ns;\n\n    var fp$5 = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Bulgarian = {\n        weekdays: {\n            shorthand: [\"Нд\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\"],\n            longhand: [\n                \"Неделя\",\n                \"Понеделник\",\n                \"Вторник\",\n                \"Сряда\",\n                \"Четвъртък\",\n                \"Петък\",\n                \"Събота\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Яну\",\n                \"Фев\",\n                \"Март\",\n                \"Апр\",\n                \"Май\",\n                \"Юни\",\n                \"Юли\",\n                \"Авг\",\n                \"Сеп\",\n                \"Окт\",\n                \"Ное\",\n                \"Дек\",\n            ],\n            longhand: [\n                \"Януари\",\n                \"Февруари\",\n                \"Март\",\n                \"Април\",\n                \"Май\",\n                \"Юни\",\n                \"Юли\",\n                \"Август\",\n                \"Септември\",\n                \"Октомври\",\n                \"Ноември\",\n                \"Декември\",\n            ],\n        },\n        time_24hr: true,\n        firstDayOfWeek: 1,\n    };\n    fp$5.l10ns.bg = Bulgarian;\n    fp$5.l10ns;\n\n    var fp$6 = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Bangla = {\n        weekdays: {\n            shorthand: [\"রবি\", \"সোম\", \"মঙ্গল\", \"বুধ\", \"বৃহস্পতি\", \"শুক্র\", \"শনি\"],\n            longhand: [\n                \"রবিবার\",\n                \"সোমবার\",\n                \"মঙ্গলবার\",\n                \"বুধবার\",\n                \"বৃহস্পতিবার\",\n                \"শুক্রবার\",\n                \"শনিবার\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"জানু\",\n                \"ফেব্রু\",\n                \"মার্চ\",\n                \"এপ্রিল\",\n                \"মে\",\n                \"জুন\",\n                \"জুলাই\",\n                \"আগ\",\n                \"সেপ্টে\",\n                \"অক্টো\",\n                \"নভে\",\n                \"ডিসে\",\n            ],\n            longhand: [\n                \"জানুয়ারী\",\n                \"ফেব্রুয়ারী\",\n                \"মার্চ\",\n                \"এপ্রিল\",\n                \"মে\",\n                \"জুন\",\n                \"জুলাই\",\n                \"আগস্ট\",\n                \"সেপ্টেম্বর\",\n                \"অক্টোবর\",\n                \"নভেম্বর\",\n                \"ডিসেম্বর\",\n            ],\n        },\n    };\n    fp$6.l10ns.bn = Bangla;\n    fp$6.l10ns;\n\n    var fp$7 = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Catalan = {\n        weekdays: {\n            shorthand: [\"Dg\", \"Dl\", \"Dt\", \"Dc\", \"Dj\", \"Dv\", \"Ds\"],\n            longhand: [\n                \"Diumenge\",\n                \"Dilluns\",\n                \"Dimarts\",\n                \"Dimecres\",\n                \"Dijous\",\n                \"Divendres\",\n                \"Dissabte\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Gen\",\n                \"Febr\",\n                \"Març\",\n                \"Abr\",\n                \"Maig\",\n                \"Juny\",\n                \"Jul\",\n                \"Ag\",\n                \"Set\",\n                \"Oct\",\n                \"Nov\",\n                \"Des\",\n            ],\n            longhand: [\n                \"Gener\",\n                \"Febrer\",\n                \"Març\",\n                \"Abril\",\n                \"Maig\",\n                \"Juny\",\n                \"Juliol\",\n                \"Agost\",\n                \"Setembre\",\n                \"Octubre\",\n                \"Novembre\",\n                \"Desembre\",\n            ],\n        },\n        ordinal: function (nth) {\n            var s = nth % 100;\n            if (s > 3 && s < 21)\n                return \"è\";\n            switch (s % 10) {\n                case 1:\n                    return \"r\";\n                case 2:\n                    return \"n\";\n                case 3:\n                    return \"r\";\n                case 4:\n                    return \"t\";\n                default:\n                    return \"è\";\n            }\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" a \",\n        time_24hr: true,\n    };\n    fp$7.l10ns.cat = fp$7.l10ns.ca = Catalan;\n    fp$7.l10ns;\n\n    var fp$8 = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Kurdish = {\n        weekdays: {\n            shorthand: [\"یەکشەممە\", \"دووشەممە\", \"سێشەممە\", \"چوارشەممە\", \"پێنجشەممە\", \"هەینی\", \"شەممە\"],\n            longhand: [\n                \"یەکشەممە\",\n                \"دووشەممە\",\n                \"سێشەممە\",\n                \"چوارشەممە\",\n                \"پێنجشەممە\",\n                \"هەینی\",\n                \"شەممە\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"ڕێبەندان\",\n                \"ڕەشەمە\",\n                \"نەورۆز\",\n                \"گوڵان\",\n                \"جۆزەردان\",\n                \"پووشپەڕ\",\n                \"گەلاوێژ\",\n                \"خەرمانان\",\n                \"ڕەزبەر\",\n                \"گەڵاڕێزان\",\n                \"سەرماوەز\",\n                \"بەفرانبار\",\n            ],\n            longhand: [\n                \"ڕێبەندان\",\n                \"ڕەشەمە\",\n                \"نەورۆز\",\n                \"گوڵان\",\n                \"جۆزەردان\",\n                \"پووشپەڕ\",\n                \"گەلاوێژ\",\n                \"خەرمانان\",\n                \"ڕەزبەر\",\n                \"گەڵاڕێزان\",\n                \"سەرماوەز\",\n                \"بەفرانبار\",\n            ],\n        },\n        firstDayOfWeek: 6,\n        ordinal: function () {\n            return \"\";\n        },\n    };\n    fp$8.l10ns.ckb = Kurdish;\n    fp$8.l10ns;\n\n    var fp$9 = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Czech = {\n        weekdays: {\n            shorthand: [\"Ne\", \"Po\", \"Út\", \"St\", \"Čt\", \"Pá\", \"So\"],\n            longhand: [\n                \"Neděle\",\n                \"Pondělí\",\n                \"Úterý\",\n                \"Středa\",\n                \"Čtvrtek\",\n                \"Pátek\",\n                \"Sobota\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Led\",\n                \"Ún\",\n                \"Bře\",\n                \"Dub\",\n                \"Kvě\",\n                \"Čer\",\n                \"Čvc\",\n                \"Srp\",\n                \"Zář\",\n                \"Říj\",\n                \"Lis\",\n                \"Pro\",\n            ],\n            longhand: [\n                \"Leden\",\n                \"Únor\",\n                \"Březen\",\n                \"Duben\",\n                \"Květen\",\n                \"Červen\",\n                \"Červenec\",\n                \"Srpen\",\n                \"Září\",\n                \"Říjen\",\n                \"Listopad\",\n                \"Prosinec\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \".\";\n        },\n        rangeSeparator: \" do \",\n        weekAbbreviation: \"Týd.\",\n        scrollTitle: \"Rolujte pro změnu\",\n        toggleTitle: \"Přepnout dopoledne/odpoledne\",\n        amPM: [\"dop.\", \"odp.\"],\n        yearAriaLabel: \"Rok\",\n        time_24hr: true,\n    };\n    fp$9.l10ns.cs = Czech;\n    fp$9.l10ns;\n\n    var fp$a = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Welsh = {\n        weekdays: {\n            shorthand: [\"Sul\", \"Llun\", \"Maw\", \"Mer\", \"Iau\", \"Gwe\", \"Sad\"],\n            longhand: [\n                \"Dydd Sul\",\n                \"Dydd Llun\",\n                \"Dydd Mawrth\",\n                \"Dydd Mercher\",\n                \"Dydd Iau\",\n                \"Dydd Gwener\",\n                \"Dydd Sadwrn\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Ion\",\n                \"Chwef\",\n                \"Maw\",\n                \"Ebr\",\n                \"Mai\",\n                \"Meh\",\n                \"Gorff\",\n                \"Awst\",\n                \"Medi\",\n                \"Hyd\",\n                \"Tach\",\n                \"Rhag\",\n            ],\n            longhand: [\n                \"Ionawr\",\n                \"Chwefror\",\n                \"Mawrth\",\n                \"Ebrill\",\n                \"Mai\",\n                \"Mehefin\",\n                \"Gorffennaf\",\n                \"Awst\",\n                \"Medi\",\n                \"Hydref\",\n                \"Tachwedd\",\n                \"Rhagfyr\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function (nth) {\n            if (nth === 1)\n                return \"af\";\n            if (nth === 2)\n                return \"ail\";\n            if (nth === 3 || nth === 4)\n                return \"ydd\";\n            if (nth === 5 || nth === 6)\n                return \"ed\";\n            if ((nth >= 7 && nth <= 10) ||\n                nth == 12 ||\n                nth == 15 ||\n                nth == 18 ||\n                nth == 20)\n                return \"fed\";\n            if (nth == 11 ||\n                nth == 13 ||\n                nth == 14 ||\n                nth == 16 ||\n                nth == 17 ||\n                nth == 19)\n                return \"eg\";\n            if (nth >= 21 && nth <= 39)\n                return \"ain\";\n            // Inconclusive.\n            return \"\";\n        },\n        time_24hr: true,\n    };\n    fp$a.l10ns.cy = Welsh;\n    fp$a.l10ns;\n\n    var fp$b = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Danish = {\n        weekdays: {\n            shorthand: [\"søn\", \"man\", \"tir\", \"ons\", \"tors\", \"fre\", \"lør\"],\n            longhand: [\n                \"søndag\",\n                \"mandag\",\n                \"tirsdag\",\n                \"onsdag\",\n                \"torsdag\",\n                \"fredag\",\n                \"lørdag\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"jan\",\n                \"feb\",\n                \"mar\",\n                \"apr\",\n                \"maj\",\n                \"jun\",\n                \"jul\",\n                \"aug\",\n                \"sep\",\n                \"okt\",\n                \"nov\",\n                \"dec\",\n            ],\n            longhand: [\n                \"januar\",\n                \"februar\",\n                \"marts\",\n                \"april\",\n                \"maj\",\n                \"juni\",\n                \"juli\",\n                \"august\",\n                \"september\",\n                \"oktober\",\n                \"november\",\n                \"december\",\n            ],\n        },\n        ordinal: function () {\n            return \".\";\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" til \",\n        weekAbbreviation: \"uge\",\n        time_24hr: true,\n    };\n    fp$b.l10ns.da = Danish;\n    fp$b.l10ns;\n\n    var fp$c = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var German = {\n        weekdays: {\n            shorthand: [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\"],\n            longhand: [\n                \"Sonntag\",\n                \"Montag\",\n                \"Dienstag\",\n                \"Mittwoch\",\n                \"Donnerstag\",\n                \"Freitag\",\n                \"Samstag\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mär\",\n                \"Apr\",\n                \"Mai\",\n                \"Jun\",\n                \"Jul\",\n                \"Aug\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dez\",\n            ],\n            longhand: [\n                \"Januar\",\n                \"Februar\",\n                \"März\",\n                \"April\",\n                \"Mai\",\n                \"Juni\",\n                \"Juli\",\n                \"August\",\n                \"September\",\n                \"Oktober\",\n                \"November\",\n                \"Dezember\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        weekAbbreviation: \"KW\",\n        rangeSeparator: \" bis \",\n        scrollTitle: \"Zum Ändern scrollen\",\n        toggleTitle: \"Zum Umschalten klicken\",\n        time_24hr: true,\n    };\n    fp$c.l10ns.de = German;\n    fp$c.l10ns;\n\n    var english = {\n        weekdays: {\n            shorthand: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n            longhand: [\n                \"Sunday\",\n                \"Monday\",\n                \"Tuesday\",\n                \"Wednesday\",\n                \"Thursday\",\n                \"Friday\",\n                \"Saturday\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"May\",\n                \"Jun\",\n                \"Jul\",\n                \"Aug\",\n                \"Sep\",\n                \"Oct\",\n                \"Nov\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"January\",\n                \"February\",\n                \"March\",\n                \"April\",\n                \"May\",\n                \"June\",\n                \"July\",\n                \"August\",\n                \"September\",\n                \"October\",\n                \"November\",\n                \"December\",\n            ],\n        },\n        daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],\n        firstDayOfWeek: 0,\n        ordinal: function (nth) {\n            var s = nth % 100;\n            if (s > 3 && s < 21)\n                return \"th\";\n            switch (s % 10) {\n                case 1:\n                    return \"st\";\n                case 2:\n                    return \"nd\";\n                case 3:\n                    return \"rd\";\n                default:\n                    return \"th\";\n            }\n        },\n        rangeSeparator: \" to \",\n        weekAbbreviation: \"Wk\",\n        scrollTitle: \"Scroll to increment\",\n        toggleTitle: \"Click to toggle\",\n        amPM: [\"AM\", \"PM\"],\n        yearAriaLabel: \"Year\",\n        monthAriaLabel: \"Month\",\n        hourAriaLabel: \"Hour\",\n        minuteAriaLabel: \"Minute\",\n        time_24hr: false,\n    };\n\n    var fp$d = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Esperanto = {\n        firstDayOfWeek: 1,\n        rangeSeparator: \" ĝis \",\n        weekAbbreviation: \"Sem\",\n        scrollTitle: \"Rulumu por pligrandigi la valoron\",\n        toggleTitle: \"Klaku por ŝalti\",\n        weekdays: {\n            shorthand: [\"Dim\", \"Lun\", \"Mar\", \"Mer\", \"Ĵaŭ\", \"Ven\", \"Sab\"],\n            longhand: [\n                \"dimanĉo\",\n                \"lundo\",\n                \"mardo\",\n                \"merkredo\",\n                \"ĵaŭdo\",\n                \"vendredo\",\n                \"sabato\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Maj\",\n                \"Jun\",\n                \"Jul\",\n                \"Aŭg\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"januaro\",\n                \"februaro\",\n                \"marto\",\n                \"aprilo\",\n                \"majo\",\n                \"junio\",\n                \"julio\",\n                \"aŭgusto\",\n                \"septembro\",\n                \"oktobro\",\n                \"novembro\",\n                \"decembro\",\n            ],\n        },\n        ordinal: function () {\n            return \"-a\";\n        },\n        time_24hr: true,\n    };\n    fp$d.l10ns.eo = Esperanto;\n    fp$d.l10ns;\n\n    var fp$e = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Spanish = {\n        weekdays: {\n            shorthand: [\"Dom\", \"Lun\", \"Mar\", \"Mié\", \"Jue\", \"Vie\", \"Sáb\"],\n            longhand: [\n                \"Domingo\",\n                \"Lunes\",\n                \"Martes\",\n                \"Miércoles\",\n                \"Jueves\",\n                \"Viernes\",\n                \"Sábado\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Ene\",\n                \"Feb\",\n                \"Mar\",\n                \"Abr\",\n                \"May\",\n                \"Jun\",\n                \"Jul\",\n                \"Ago\",\n                \"Sep\",\n                \"Oct\",\n                \"Nov\",\n                \"Dic\",\n            ],\n            longhand: [\n                \"Enero\",\n                \"Febrero\",\n                \"Marzo\",\n                \"Abril\",\n                \"Mayo\",\n                \"Junio\",\n                \"Julio\",\n                \"Agosto\",\n                \"Septiembre\",\n                \"Octubre\",\n                \"Noviembre\",\n                \"Diciembre\",\n            ],\n        },\n        ordinal: function () {\n            return \"º\";\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" a \",\n        time_24hr: true,\n    };\n    fp$e.l10ns.es = Spanish;\n    fp$e.l10ns;\n\n    var fp$f = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Estonian = {\n        weekdays: {\n            shorthand: [\"P\", \"E\", \"T\", \"K\", \"N\", \"R\", \"L\"],\n            longhand: [\n                \"Pühapäev\",\n                \"Esmaspäev\",\n                \"Teisipäev\",\n                \"Kolmapäev\",\n                \"Neljapäev\",\n                \"Reede\",\n                \"Laupäev\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jaan\",\n                \"Veebr\",\n                \"Märts\",\n                \"Apr\",\n                \"Mai\",\n                \"Juuni\",\n                \"Juuli\",\n                \"Aug\",\n                \"Sept\",\n                \"Okt\",\n                \"Nov\",\n                \"Dets\",\n            ],\n            longhand: [\n                \"Jaanuar\",\n                \"Veebruar\",\n                \"Märts\",\n                \"Aprill\",\n                \"Mai\",\n                \"Juuni\",\n                \"Juuli\",\n                \"August\",\n                \"September\",\n                \"Oktoober\",\n                \"November\",\n                \"Detsember\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \".\";\n        },\n        weekAbbreviation: \"Näd\",\n        rangeSeparator: \" kuni \",\n        scrollTitle: \"Keri, et suurendada\",\n        toggleTitle: \"Klõpsa, et vahetada\",\n        time_24hr: true,\n    };\n    fp$f.l10ns.et = Estonian;\n    fp$f.l10ns;\n\n    var fp$g = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Persian = {\n        weekdays: {\n            shorthand: [\"یک\", \"دو\", \"سه\", \"چهار\", \"پنج\", \"جمعه\", \"شنبه\"],\n            longhand: [\n                \"یک‌شنبه\",\n                \"دوشنبه\",\n                \"سه‌شنبه\",\n                \"چهارشنبه\",\n                \"پنچ‌شنبه\",\n                \"جمعه\",\n                \"شنبه\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"ژانویه\",\n                \"فوریه\",\n                \"مارس\",\n                \"آوریل\",\n                \"مه\",\n                \"ژوئن\",\n                \"ژوئیه\",\n                \"اوت\",\n                \"سپتامبر\",\n                \"اکتبر\",\n                \"نوامبر\",\n                \"دسامبر\",\n            ],\n            longhand: [\n                \"ژانویه\",\n                \"فوریه\",\n                \"مارس\",\n                \"آوریل\",\n                \"مه\",\n                \"ژوئن\",\n                \"ژوئیه\",\n                \"اوت\",\n                \"سپتامبر\",\n                \"اکتبر\",\n                \"نوامبر\",\n                \"دسامبر\",\n            ],\n        },\n        firstDayOfWeek: 6,\n        ordinal: function () {\n            return \"\";\n        },\n    };\n    fp$g.l10ns.fa = Persian;\n    fp$g.l10ns;\n\n    var fp$h = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Finnish = {\n        firstDayOfWeek: 1,\n        weekdays: {\n            shorthand: [\"su\", \"ma\", \"ti\", \"ke\", \"to\", \"pe\", \"la\"],\n            longhand: [\n                \"sunnuntai\",\n                \"maanantai\",\n                \"tiistai\",\n                \"keskiviikko\",\n                \"torstai\",\n                \"perjantai\",\n                \"lauantai\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"tammi\",\n                \"helmi\",\n                \"maalis\",\n                \"huhti\",\n                \"touko\",\n                \"kesä\",\n                \"heinä\",\n                \"elo\",\n                \"syys\",\n                \"loka\",\n                \"marras\",\n                \"joulu\",\n            ],\n            longhand: [\n                \"tammikuu\",\n                \"helmikuu\",\n                \"maaliskuu\",\n                \"huhtikuu\",\n                \"toukokuu\",\n                \"kesäkuu\",\n                \"heinäkuu\",\n                \"elokuu\",\n                \"syyskuu\",\n                \"lokakuu\",\n                \"marraskuu\",\n                \"joulukuu\",\n            ],\n        },\n        ordinal: function () {\n            return \".\";\n        },\n        time_24hr: true,\n    };\n    fp$h.l10ns.fi = Finnish;\n    fp$h.l10ns;\n\n    var fp$i = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Faroese = {\n        weekdays: {\n            shorthand: [\"Sun\", \"Mán\", \"Týs\", \"Mik\", \"Hós\", \"Frí\", \"Ley\"],\n            longhand: [\n                \"Sunnudagur\",\n                \"Mánadagur\",\n                \"Týsdagur\",\n                \"Mikudagur\",\n                \"Hósdagur\",\n                \"Fríggjadagur\",\n                \"Leygardagur\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Mai\",\n                \"Jun\",\n                \"Jul\",\n                \"Aug\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Des\",\n            ],\n            longhand: [\n                \"Januar\",\n                \"Februar\",\n                \"Mars\",\n                \"Apríl\",\n                \"Mai\",\n                \"Juni\",\n                \"Juli\",\n                \"August\",\n                \"Septembur\",\n                \"Oktobur\",\n                \"Novembur\",\n                \"Desembur\",\n            ],\n        },\n        ordinal: function () {\n            return \".\";\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" til \",\n        weekAbbreviation: \"vika\",\n        scrollTitle: \"Rulla fyri at broyta\",\n        toggleTitle: \"Trýst fyri at skifta\",\n        yearAriaLabel: \"Ár\",\n        time_24hr: true,\n    };\n    fp$i.l10ns.fo = Faroese;\n    fp$i.l10ns;\n\n    var fp$j = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var French = {\n        firstDayOfWeek: 1,\n        weekdays: {\n            shorthand: [\"dim\", \"lun\", \"mar\", \"mer\", \"jeu\", \"ven\", \"sam\"],\n            longhand: [\n                \"dimanche\",\n                \"lundi\",\n                \"mardi\",\n                \"mercredi\",\n                \"jeudi\",\n                \"vendredi\",\n                \"samedi\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"janv\",\n                \"févr\",\n                \"mars\",\n                \"avr\",\n                \"mai\",\n                \"juin\",\n                \"juil\",\n                \"août\",\n                \"sept\",\n                \"oct\",\n                \"nov\",\n                \"déc\",\n            ],\n            longhand: [\n                \"janvier\",\n                \"février\",\n                \"mars\",\n                \"avril\",\n                \"mai\",\n                \"juin\",\n                \"juillet\",\n                \"août\",\n                \"septembre\",\n                \"octobre\",\n                \"novembre\",\n                \"décembre\",\n            ],\n        },\n        ordinal: function (nth) {\n            if (nth > 1)\n                return \"\";\n            return \"er\";\n        },\n        rangeSeparator: \" au \",\n        weekAbbreviation: \"Sem\",\n        scrollTitle: \"Défiler pour augmenter la valeur\",\n        toggleTitle: \"Cliquer pour basculer\",\n        time_24hr: true,\n    };\n    fp$j.l10ns.fr = French;\n    fp$j.l10ns;\n\n    var fp$k = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Greek = {\n        weekdays: {\n            shorthand: [\"Κυ\", \"Δε\", \"Τρ\", \"Τε\", \"Πέ\", \"Πα\", \"Σά\"],\n            longhand: [\n                \"Κυριακή\",\n                \"Δευτέρα\",\n                \"Τρίτη\",\n                \"Τετάρτη\",\n                \"Πέμπτη\",\n                \"Παρασκευή\",\n                \"Σάββατο\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Ιαν\",\n                \"Φεβ\",\n                \"Μάρ\",\n                \"Απρ\",\n                \"Μάι\",\n                \"Ιούν\",\n                \"Ιούλ\",\n                \"Αύγ\",\n                \"Σεπ\",\n                \"Οκτ\",\n                \"Νοέ\",\n                \"Δεκ\",\n            ],\n            longhand: [\n                \"Ιανουάριος\",\n                \"Φεβρουάριος\",\n                \"Μάρτιος\",\n                \"Απρίλιος\",\n                \"Μάιος\",\n                \"Ιούνιος\",\n                \"Ιούλιος\",\n                \"Αύγουστος\",\n                \"Σεπτέμβριος\",\n                \"Οκτώβριος\",\n                \"Νοέμβριος\",\n                \"Δεκέμβριος\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        weekAbbreviation: \"Εβδ\",\n        rangeSeparator: \" έως \",\n        scrollTitle: \"Μετακυλήστε για προσαύξηση\",\n        toggleTitle: \"Κάντε κλικ για αλλαγή\",\n        amPM: [\"ΠΜ\", \"ΜΜ\"],\n        yearAriaLabel: \"χρόνος\",\n        monthAriaLabel: \"μήνας\",\n        hourAriaLabel: \"ώρα\",\n        minuteAriaLabel: \"λεπτό\",\n    };\n    fp$k.l10ns.gr = Greek;\n    fp$k.l10ns;\n\n    var fp$l = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Hebrew = {\n        weekdays: {\n            shorthand: [\"א\", \"ב\", \"ג\", \"ד\", \"ה\", \"ו\", \"ש\"],\n            longhand: [\"ראשון\", \"שני\", \"שלישי\", \"רביעי\", \"חמישי\", \"שישי\", \"שבת\"],\n        },\n        months: {\n            shorthand: [\n                \"ינו׳\",\n                \"פבר׳\",\n                \"מרץ\",\n                \"אפר׳\",\n                \"מאי\",\n                \"יוני\",\n                \"יולי\",\n                \"אוג׳\",\n                \"ספט׳\",\n                \"אוק׳\",\n                \"נוב׳\",\n                \"דצמ׳\",\n            ],\n            longhand: [\n                \"ינואר\",\n                \"פברואר\",\n                \"מרץ\",\n                \"אפריל\",\n                \"מאי\",\n                \"יוני\",\n                \"יולי\",\n                \"אוגוסט\",\n                \"ספטמבר\",\n                \"אוקטובר\",\n                \"נובמבר\",\n                \"דצמבר\",\n            ],\n        },\n        rangeSeparator: \" אל \",\n        time_24hr: true,\n    };\n    fp$l.l10ns.he = Hebrew;\n    fp$l.l10ns;\n\n    var fp$m = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Hindi = {\n        weekdays: {\n            shorthand: [\"रवि\", \"सोम\", \"मंगल\", \"बुध\", \"गुरु\", \"शुक्र\", \"शनि\"],\n            longhand: [\n                \"रविवार\",\n                \"सोमवार\",\n                \"मंगलवार\",\n                \"बुधवार\",\n                \"गुरुवार\",\n                \"शुक्रवार\",\n                \"शनिवार\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"जन\",\n                \"फर\",\n                \"मार्च\",\n                \"अप्रेल\",\n                \"मई\",\n                \"जून\",\n                \"जूलाई\",\n                \"अग\",\n                \"सित\",\n                \"अक्ट\",\n                \"नव\",\n                \"दि\",\n            ],\n            longhand: [\n                \"जनवरी \",\n                \"फरवरी\",\n                \"मार्च\",\n                \"अप्रेल\",\n                \"मई\",\n                \"जून\",\n                \"जूलाई\",\n                \"अगस्त \",\n                \"सितम्बर\",\n                \"अक्टूबर\",\n                \"नवम्बर\",\n                \"दिसम्बर\",\n            ],\n        },\n    };\n    fp$m.l10ns.hi = Hindi;\n    fp$m.l10ns;\n\n    var fp$n = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Croatian = {\n        firstDayOfWeek: 1,\n        weekdays: {\n            shorthand: [\"Ned\", \"Pon\", \"Uto\", \"Sri\", \"Čet\", \"Pet\", \"Sub\"],\n            longhand: [\n                \"Nedjelja\",\n                \"Ponedjeljak\",\n                \"Utorak\",\n                \"Srijeda\",\n                \"Četvrtak\",\n                \"Petak\",\n                \"Subota\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Sij\",\n                \"Velj\",\n                \"Ožu\",\n                \"Tra\",\n                \"Svi\",\n                \"Lip\",\n                \"Srp\",\n                \"Kol\",\n                \"Ruj\",\n                \"Lis\",\n                \"Stu\",\n                \"Pro\",\n            ],\n            longhand: [\n                \"Siječanj\",\n                \"Veljača\",\n                \"Ožujak\",\n                \"Travanj\",\n                \"Svibanj\",\n                \"Lipanj\",\n                \"Srpanj\",\n                \"Kolovoz\",\n                \"Rujan\",\n                \"Listopad\",\n                \"Studeni\",\n                \"Prosinac\",\n            ],\n        },\n        time_24hr: true,\n    };\n    fp$n.l10ns.hr = Croatian;\n    fp$n.l10ns;\n\n    var fp$o = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Hungarian = {\n        firstDayOfWeek: 1,\n        weekdays: {\n            shorthand: [\"V\", \"H\", \"K\", \"Sz\", \"Cs\", \"P\", \"Szo\"],\n            longhand: [\n                \"Vasárnap\",\n                \"Hétfő\",\n                \"Kedd\",\n                \"Szerda\",\n                \"Csütörtök\",\n                \"Péntek\",\n                \"Szombat\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Már\",\n                \"Ápr\",\n                \"Máj\",\n                \"Jún\",\n                \"Júl\",\n                \"Aug\",\n                \"Szep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"Január\",\n                \"Február\",\n                \"Március\",\n                \"Április\",\n                \"Május\",\n                \"Június\",\n                \"Július\",\n                \"Augusztus\",\n                \"Szeptember\",\n                \"Október\",\n                \"November\",\n                \"December\",\n            ],\n        },\n        ordinal: function () {\n            return \".\";\n        },\n        weekAbbreviation: \"Hét\",\n        scrollTitle: \"Görgessen\",\n        toggleTitle: \"Kattintson a váltáshoz\",\n        rangeSeparator: \" - \",\n        time_24hr: true,\n    };\n    fp$o.l10ns.hu = Hungarian;\n    fp$o.l10ns;\n\n    var fp$p = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Armenian = {\n        weekdays: {\n            shorthand: [\n                \"Կիր\",\n                \"Երկ\",\n                \"Երք\",\n                \"Չրք\",\n                \"Հնգ\",\n                \"Ուրբ\",\n                \"Շբթ\",\n            ],\n            longhand: [\n                \"Կիրակի\",\n                \"Եկուշաբթի\",\n                \"Երեքշաբթի\",\n                \"Չորեքշաբթի\",\n                \"Հինգշաբթի\",\n                \"Ուրբաթ\",\n                \"Շաբաթ\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Հնվ\",\n                \"Փտր\",\n                \"Մար\",\n                \"Ապր\",\n                \"Մայ\",\n                \"Հնս\",\n                \"Հլս\",\n                \"Օգս\",\n                \"Սեպ\",\n                \"Հոկ\",\n                \"Նմբ\",\n                \"Դեկ\",\n            ],\n            longhand: [\n                \"Հունվար\",\n                \"Փետրվար\",\n                \"Մարտ\",\n                \"Ապրիլ\",\n                \"Մայիս\",\n                \"Հունիս\",\n                \"Հուլիս\",\n                \"Օգոստոս\",\n                \"Սեպտեմբեր\",\n                \"Հոկտեմբեր\",\n                \"Նոյեմբեր\",\n                \"Դեկտեմբեր\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        rangeSeparator: \" — \",\n        weekAbbreviation: \"ՇԲՏ\",\n        scrollTitle: \"Ոլորեք՝ մեծացնելու համար\",\n        toggleTitle: \"Սեղմեք՝ փոխելու համար\",\n        amPM: [\"ՄԿ\", \"ԿՀ\"],\n        yearAriaLabel: \"Տարի\",\n        monthAriaLabel: \"Ամիս\",\n        hourAriaLabel: \"Ժամ\",\n        minuteAriaLabel: \"Րոպե\",\n        time_24hr: true,\n    };\n    fp$p.l10ns.hy = Armenian;\n    fp$p.l10ns;\n\n    var fp$q = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Indonesian = {\n        weekdays: {\n            shorthand: [\"Min\", \"Sen\", \"Sel\", \"Rab\", \"Kam\", \"Jum\", \"Sab\"],\n            longhand: [\"Minggu\", \"Senin\", \"Selasa\", \"Rabu\", \"Kamis\", \"Jumat\", \"Sabtu\"],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Mei\",\n                \"Jun\",\n                \"Jul\",\n                \"Agu\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Des\",\n            ],\n            longhand: [\n                \"Januari\",\n                \"Februari\",\n                \"Maret\",\n                \"April\",\n                \"Mei\",\n                \"Juni\",\n                \"Juli\",\n                \"Agustus\",\n                \"September\",\n                \"Oktober\",\n                \"November\",\n                \"Desember\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        time_24hr: true,\n        rangeSeparator: \" - \",\n    };\n    fp$q.l10ns.id = Indonesian;\n    fp$q.l10ns;\n\n    var fp$r = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Icelandic = {\n        weekdays: {\n            shorthand: [\"Sun\", \"Mán\", \"Þri\", \"Mið\", \"Fim\", \"Fös\", \"Lau\"],\n            longhand: [\n                \"Sunnudagur\",\n                \"Mánudagur\",\n                \"Þriðjudagur\",\n                \"Miðvikudagur\",\n                \"Fimmtudagur\",\n                \"Föstudagur\",\n                \"Laugardagur\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Maí\",\n                \"Jún\",\n                \"Júl\",\n                \"Ágú\",\n                \"Sep\",\n                \"Okt\",\n                \"Nóv\",\n                \"Des\",\n            ],\n            longhand: [\n                \"Janúar\",\n                \"Febrúar\",\n                \"Mars\",\n                \"Apríl\",\n                \"Maí\",\n                \"Júní\",\n                \"Júlí\",\n                \"Ágúst\",\n                \"September\",\n                \"Október\",\n                \"Nóvember\",\n                \"Desember\",\n            ],\n        },\n        ordinal: function () {\n            return \".\";\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" til \",\n        weekAbbreviation: \"vika\",\n        yearAriaLabel: \"Ár\",\n        time_24hr: true,\n    };\n    fp$r.l10ns.is = Icelandic;\n    fp$r.l10ns;\n\n    var fp$s = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Italian = {\n        weekdays: {\n            shorthand: [\"Dom\", \"Lun\", \"Mar\", \"Mer\", \"Gio\", \"Ven\", \"Sab\"],\n            longhand: [\n                \"Domenica\",\n                \"Lunedì\",\n                \"Martedì\",\n                \"Mercoledì\",\n                \"Giovedì\",\n                \"Venerdì\",\n                \"Sabato\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Gen\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Mag\",\n                \"Giu\",\n                \"Lug\",\n                \"Ago\",\n                \"Set\",\n                \"Ott\",\n                \"Nov\",\n                \"Dic\",\n            ],\n            longhand: [\n                \"Gennaio\",\n                \"Febbraio\",\n                \"Marzo\",\n                \"Aprile\",\n                \"Maggio\",\n                \"Giugno\",\n                \"Luglio\",\n                \"Agosto\",\n                \"Settembre\",\n                \"Ottobre\",\n                \"Novembre\",\n                \"Dicembre\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () { return \"°\"; },\n        rangeSeparator: \" al \",\n        weekAbbreviation: \"Se\",\n        scrollTitle: \"Scrolla per aumentare\",\n        toggleTitle: \"Clicca per cambiare\",\n        time_24hr: true,\n    };\n    fp$s.l10ns.it = Italian;\n    fp$s.l10ns;\n\n    var fp$t = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Japanese = {\n        weekdays: {\n            shorthand: [\"日\", \"月\", \"火\", \"水\", \"木\", \"金\", \"土\"],\n            longhand: [\n                \"日曜日\",\n                \"月曜日\",\n                \"火曜日\",\n                \"水曜日\",\n                \"木曜日\",\n                \"金曜日\",\n                \"土曜日\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"1月\",\n                \"2月\",\n                \"3月\",\n                \"4月\",\n                \"5月\",\n                \"6月\",\n                \"7月\",\n                \"8月\",\n                \"9月\",\n                \"10月\",\n                \"11月\",\n                \"12月\",\n            ],\n            longhand: [\n                \"1月\",\n                \"2月\",\n                \"3月\",\n                \"4月\",\n                \"5月\",\n                \"6月\",\n                \"7月\",\n                \"8月\",\n                \"9月\",\n                \"10月\",\n                \"11月\",\n                \"12月\",\n            ],\n        },\n        time_24hr: true,\n        rangeSeparator: \" から \",\n        monthAriaLabel: \"月\",\n        amPM: [\"午前\", \"午後\"],\n        yearAriaLabel: \"年\",\n        hourAriaLabel: \"時間\",\n        minuteAriaLabel: \"分\",\n    };\n    fp$t.l10ns.ja = Japanese;\n    fp$t.l10ns;\n\n    var fp$u = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Georgian = {\n        weekdays: {\n            shorthand: [\"კვ\", \"ორ\", \"სა\", \"ოთ\", \"ხუ\", \"პა\", \"შა\"],\n            longhand: [\n                \"კვირა\",\n                \"ორშაბათი\",\n                \"სამშაბათი\",\n                \"ოთხშაბათი\",\n                \"ხუთშაბათი\",\n                \"პარასკევი\",\n                \"შაბათი\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"იან\",\n                \"თებ\",\n                \"მარ\",\n                \"აპრ\",\n                \"მაი\",\n                \"ივნ\",\n                \"ივლ\",\n                \"აგვ\",\n                \"სექ\",\n                \"ოქტ\",\n                \"ნოე\",\n                \"დეკ\",\n            ],\n            longhand: [\n                \"იანვარი\",\n                \"თებერვალი\",\n                \"მარტი\",\n                \"აპრილი\",\n                \"მაისი\",\n                \"ივნისი\",\n                \"ივლისი\",\n                \"აგვისტო\",\n                \"სექტემბერი\",\n                \"ოქტომბერი\",\n                \"ნოემბერი\",\n                \"დეკემბერი\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        rangeSeparator: \" — \",\n        weekAbbreviation: \"კვ.\",\n        scrollTitle: \"დასქროლეთ გასადიდებლად\",\n        toggleTitle: \"დააკლიკეთ გადართვისთვის\",\n        amPM: [\"AM\", \"PM\"],\n        yearAriaLabel: \"წელი\",\n        time_24hr: true,\n    };\n    fp$u.l10ns.ka = Georgian;\n    fp$u.l10ns;\n\n    var fp$v = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Korean = {\n        weekdays: {\n            shorthand: [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\"],\n            longhand: [\n                \"일요일\",\n                \"월요일\",\n                \"화요일\",\n                \"수요일\",\n                \"목요일\",\n                \"금요일\",\n                \"토요일\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"1월\",\n                \"2월\",\n                \"3월\",\n                \"4월\",\n                \"5월\",\n                \"6월\",\n                \"7월\",\n                \"8월\",\n                \"9월\",\n                \"10월\",\n                \"11월\",\n                \"12월\",\n            ],\n            longhand: [\n                \"1월\",\n                \"2월\",\n                \"3월\",\n                \"4월\",\n                \"5월\",\n                \"6월\",\n                \"7월\",\n                \"8월\",\n                \"9월\",\n                \"10월\",\n                \"11월\",\n                \"12월\",\n            ],\n        },\n        ordinal: function () {\n            return \"일\";\n        },\n        rangeSeparator: \" ~ \",\n        amPM: [\"오전\", \"오후\"],\n    };\n    fp$v.l10ns.ko = Korean;\n    fp$v.l10ns;\n\n    var fp$w = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Khmer = {\n        weekdays: {\n            shorthand: [\"អាទិត្យ\", \"ចន្ទ\", \"អង្គារ\", \"ពុធ\", \"ព្រហស.\", \"សុក្រ\", \"សៅរ៍\"],\n            longhand: [\n                \"អាទិត្យ\",\n                \"ចន្ទ\",\n                \"អង្គារ\",\n                \"ពុធ\",\n                \"ព្រហស្បតិ៍\",\n                \"សុក្រ\",\n                \"សៅរ៍\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"មករា\",\n                \"កុម្ភះ\",\n                \"មីនា\",\n                \"មេសា\",\n                \"ឧសភា\",\n                \"មិថុនា\",\n                \"កក្កដា\",\n                \"សីហា\",\n                \"កញ្ញា\",\n                \"តុលា\",\n                \"វិច្ឆិកា\",\n                \"ធ្នូ\",\n            ],\n            longhand: [\n                \"មករា\",\n                \"កុម្ភះ\",\n                \"មីនា\",\n                \"មេសា\",\n                \"ឧសភា\",\n                \"មិថុនា\",\n                \"កក្កដា\",\n                \"សីហា\",\n                \"កញ្ញា\",\n                \"តុលា\",\n                \"វិច្ឆិកា\",\n                \"ធ្នូ\",\n            ],\n        },\n        ordinal: function () {\n            return \"\";\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" ដល់ \",\n        weekAbbreviation: \"សប្តាហ៍\",\n        scrollTitle: \"រំកិលដើម្បីបង្កើន\",\n        toggleTitle: \"ចុចដើម្បីផ្លាស់ប្ដូរ\",\n        yearAriaLabel: \"ឆ្នាំ\",\n        time_24hr: true,\n    };\n    fp$w.l10ns.km = Khmer;\n    fp$w.l10ns;\n\n    var fp$x = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Kazakh = {\n        weekdays: {\n            shorthand: [\"Жс\", \"Дс\", \"Сc\", \"Ср\", \"Бс\", \"Жм\", \"Сб\"],\n            longhand: [\n                \"Жексенбi\",\n                \"Дүйсенбi\",\n                \"Сейсенбi\",\n                \"Сәрсенбi\",\n                \"Бейсенбi\",\n                \"Жұма\",\n                \"Сенбi\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Қаң\",\n                \"Ақп\",\n                \"Нау\",\n                \"Сәу\",\n                \"Мам\",\n                \"Мау\",\n                \"Шiл\",\n                \"Там\",\n                \"Қыр\",\n                \"Қаз\",\n                \"Қар\",\n                \"Жел\",\n            ],\n            longhand: [\n                \"Қаңтар\",\n                \"Ақпан\",\n                \"Наурыз\",\n                \"Сәуiр\",\n                \"Мамыр\",\n                \"Маусым\",\n                \"Шiлде\",\n                \"Тамыз\",\n                \"Қыркүйек\",\n                \"Қазан\",\n                \"Қараша\",\n                \"Желтоқсан\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        rangeSeparator: \" — \",\n        weekAbbreviation: \"Апта\",\n        scrollTitle: \"Үлкейту үшін айналдырыңыз\",\n        toggleTitle: \"Ауыстыру үшін басыңыз\",\n        amPM: [\"ТД\", \"ТК\"],\n        yearAriaLabel: \"Жыл\",\n    };\n    fp$x.l10ns.kz = Kazakh;\n    fp$x.l10ns;\n\n    var fp$y = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Lithuanian = {\n        weekdays: {\n            shorthand: [\"S\", \"Pr\", \"A\", \"T\", \"K\", \"Pn\", \"Š\"],\n            longhand: [\n                \"Sekmadienis\",\n                \"Pirmadienis\",\n                \"Antradienis\",\n                \"Trečiadienis\",\n                \"Ketvirtadienis\",\n                \"Penktadienis\",\n                \"Šeštadienis\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Sau\",\n                \"Vas\",\n                \"Kov\",\n                \"Bal\",\n                \"Geg\",\n                \"Bir\",\n                \"Lie\",\n                \"Rgp\",\n                \"Rgs\",\n                \"Spl\",\n                \"Lap\",\n                \"Grd\",\n            ],\n            longhand: [\n                \"Sausis\",\n                \"Vasaris\",\n                \"Kovas\",\n                \"Balandis\",\n                \"Gegužė\",\n                \"Birželis\",\n                \"Liepa\",\n                \"Rugpjūtis\",\n                \"Rugsėjis\",\n                \"Spalis\",\n                \"Lapkritis\",\n                \"Gruodis\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"-a\";\n        },\n        rangeSeparator: \" iki \",\n        weekAbbreviation: \"Sav\",\n        scrollTitle: \"Keisti laiką pelės rateliu\",\n        toggleTitle: \"Perjungti laiko formatą\",\n        time_24hr: true,\n    };\n    fp$y.l10ns.lt = Lithuanian;\n    fp$y.l10ns;\n\n    var fp$z = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Latvian = {\n        firstDayOfWeek: 1,\n        weekdays: {\n            shorthand: [\"Sv\", \"Pr\", \"Ot\", \"Tr\", \"Ce\", \"Pk\", \"Se\"],\n            longhand: [\n                \"Svētdiena\",\n                \"Pirmdiena\",\n                \"Otrdiena\",\n                \"Trešdiena\",\n                \"Ceturtdiena\",\n                \"Piektdiena\",\n                \"Sestdiena\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Mai\",\n                \"Jūn\",\n                \"Jūl\",\n                \"Aug\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"Janvāris\",\n                \"Februāris\",\n                \"Marts\",\n                \"Aprīlis\",\n                \"Maijs\",\n                \"Jūnijs\",\n                \"Jūlijs\",\n                \"Augusts\",\n                \"Septembris\",\n                \"Oktobris\",\n                \"Novembris\",\n                \"Decembris\",\n            ],\n        },\n        rangeSeparator: \" līdz \",\n        time_24hr: true,\n    };\n    fp$z.l10ns.lv = Latvian;\n    fp$z.l10ns;\n\n    var fp$A = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Macedonian = {\n        weekdays: {\n            shorthand: [\"Не\", \"По\", \"Вт\", \"Ср\", \"Че\", \"Пе\", \"Са\"],\n            longhand: [\n                \"Недела\",\n                \"Понеделник\",\n                \"Вторник\",\n                \"Среда\",\n                \"Четврток\",\n                \"Петок\",\n                \"Сабота\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Јан\",\n                \"Фев\",\n                \"Мар\",\n                \"Апр\",\n                \"Мај\",\n                \"Јун\",\n                \"Јул\",\n                \"Авг\",\n                \"Сеп\",\n                \"Окт\",\n                \"Ное\",\n                \"Дек\",\n            ],\n            longhand: [\n                \"Јануари\",\n                \"Февруари\",\n                \"Март\",\n                \"Април\",\n                \"Мај\",\n                \"Јуни\",\n                \"Јули\",\n                \"Август\",\n                \"Септември\",\n                \"Октомври\",\n                \"Ноември\",\n                \"Декември\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        weekAbbreviation: \"Нед.\",\n        rangeSeparator: \" до \",\n        time_24hr: true,\n    };\n    fp$A.l10ns.mk = Macedonian;\n    fp$A.l10ns;\n\n    var fp$B = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Mongolian = {\n        firstDayOfWeek: 1,\n        weekdays: {\n            shorthand: [\"Да\", \"Мя\", \"Лх\", \"Пү\", \"Ба\", \"Бя\", \"Ня\"],\n            longhand: [\"Даваа\", \"Мягмар\", \"Лхагва\", \"Пүрэв\", \"Баасан\", \"Бямба\", \"Ням\"],\n        },\n        months: {\n            shorthand: [\n                \"1-р сар\",\n                \"2-р сар\",\n                \"3-р сар\",\n                \"4-р сар\",\n                \"5-р сар\",\n                \"6-р сар\",\n                \"7-р сар\",\n                \"8-р сар\",\n                \"9-р сар\",\n                \"10-р сар\",\n                \"11-р сар\",\n                \"12-р сар\",\n            ],\n            longhand: [\n                \"Нэгдүгээр сар\",\n                \"Хоёрдугаар сар\",\n                \"Гуравдугаар сар\",\n                \"Дөрөвдүгээр сар\",\n                \"Тавдугаар сар\",\n                \"Зургаадугаар сар\",\n                \"Долдугаар сар\",\n                \"Наймдугаар сар\",\n                \"Есдүгээр сар\",\n                \"Аравдугаар сар\",\n                \"Арваннэгдүгээр сар\",\n                \"Арванхоёрдугаар сар\",\n            ],\n        },\n        rangeSeparator: \"-с \",\n        time_24hr: true,\n    };\n    fp$B.l10ns.mn = Mongolian;\n    fp$B.l10ns;\n\n    var fp$C = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Malaysian = {\n        weekdays: {\n            shorthand: [\"Aha\", \"Isn\", \"Sel\", \"Rab\", \"Kha\", \"Jum\", \"Sab\"],\n            longhand: [\n                \"Ahad\",\n                \"Isnin\",\n                \"Selasa\",\n                \"Rabu\",\n                \"Khamis\",\n                \"Jumaat\",\n                \"Sabtu\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mac\",\n                \"Apr\",\n                \"Mei\",\n                \"Jun\",\n                \"Jul\",\n                \"Ogo\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dis\",\n            ],\n            longhand: [\n                \"Januari\",\n                \"Februari\",\n                \"Mac\",\n                \"April\",\n                \"Mei\",\n                \"Jun\",\n                \"Julai\",\n                \"Ogos\",\n                \"September\",\n                \"Oktober\",\n                \"November\",\n                \"Disember\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n    };\n    fp$C.l10ns;\n\n    var fp$D = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Burmese = {\n        weekdays: {\n            shorthand: [\"နွေ\", \"လာ\", \"ဂါ\", \"ဟူး\", \"ကြာ\", \"သော\", \"နေ\"],\n            longhand: [\n                \"တနင်္ဂနွေ\",\n                \"တနင်္လာ\",\n                \"အင်္ဂါ\",\n                \"ဗုဒ္ဓဟူး\",\n                \"ကြာသပတေး\",\n                \"သောကြာ\",\n                \"စနေ\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"ဇန်\",\n                \"ဖေ\",\n                \"မတ်\",\n                \"ပြီ\",\n                \"မေ\",\n                \"ဇွန်\",\n                \"လိုင်\",\n                \"သြ\",\n                \"စက်\",\n                \"အောက်\",\n                \"နို\",\n                \"ဒီ\",\n            ],\n            longhand: [\n                \"ဇန်နဝါရီ\",\n                \"ဖေဖော်ဝါရီ\",\n                \"မတ်\",\n                \"ဧပြီ\",\n                \"မေ\",\n                \"ဇွန်\",\n                \"ဇူလိုင်\",\n                \"သြဂုတ်\",\n                \"စက်တင်ဘာ\",\n                \"အောက်တိုဘာ\",\n                \"နိုဝင်ဘာ\",\n                \"ဒီဇင်ဘာ\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        time_24hr: true,\n    };\n    fp$D.l10ns.my = Burmese;\n    fp$D.l10ns;\n\n    var fp$E = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Dutch = {\n        weekdays: {\n            shorthand: [\"zo\", \"ma\", \"di\", \"wo\", \"do\", \"vr\", \"za\"],\n            longhand: [\n                \"zondag\",\n                \"maandag\",\n                \"dinsdag\",\n                \"woensdag\",\n                \"donderdag\",\n                \"vrijdag\",\n                \"zaterdag\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"jan\",\n                \"feb\",\n                \"mrt\",\n                \"apr\",\n                \"mei\",\n                \"jun\",\n                \"jul\",\n                \"aug\",\n                \"sept\",\n                \"okt\",\n                \"nov\",\n                \"dec\",\n            ],\n            longhand: [\n                \"januari\",\n                \"februari\",\n                \"maart\",\n                \"april\",\n                \"mei\",\n                \"juni\",\n                \"juli\",\n                \"augustus\",\n                \"september\",\n                \"oktober\",\n                \"november\",\n                \"december\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        weekAbbreviation: \"wk\",\n        rangeSeparator: \" t/m \",\n        scrollTitle: \"Scroll voor volgende / vorige\",\n        toggleTitle: \"Klik om te wisselen\",\n        time_24hr: true,\n        ordinal: function (nth) {\n            if (nth === 1 || nth === 8 || nth >= 20)\n                return \"ste\";\n            return \"de\";\n        },\n    };\n    fp$E.l10ns.nl = Dutch;\n    fp$E.l10ns;\n\n    var fp$F = typeof window !== 'undefined' && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var NorwegianNynorsk = {\n        weekdays: {\n            shorthand: ['Sø.', 'Må.', 'Ty.', 'On.', 'To.', 'Fr.', 'La.'],\n            longhand: [\n                'Søndag',\n                'Måndag',\n                'Tysdag',\n                'Onsdag',\n                'Torsdag',\n                'Fredag',\n                'Laurdag',\n            ],\n        },\n        months: {\n            shorthand: [\n                'Jan',\n                'Feb',\n                'Mars',\n                'Apr',\n                'Mai',\n                'Juni',\n                'Juli',\n                'Aug',\n                'Sep',\n                'Okt',\n                'Nov',\n                'Des',\n            ],\n            longhand: [\n                'Januar',\n                'Februar',\n                'Mars',\n                'April',\n                'Mai',\n                'Juni',\n                'Juli',\n                'August',\n                'September',\n                'Oktober',\n                'November',\n                'Desember',\n            ],\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: ' til ',\n        weekAbbreviation: 'Veke',\n        scrollTitle: 'Scroll for å endre',\n        toggleTitle: 'Klikk for å veksle',\n        time_24hr: true,\n        ordinal: function () {\n            return '.';\n        },\n    };\n    fp$F.l10ns.nn = NorwegianNynorsk;\n    fp$F.l10ns;\n\n    var fp$G = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Norwegian = {\n        weekdays: {\n            shorthand: [\"Søn\", \"Man\", \"Tir\", \"Ons\", \"Tor\", \"Fre\", \"Lør\"],\n            longhand: [\n                \"Søndag\",\n                \"Mandag\",\n                \"Tirsdag\",\n                \"Onsdag\",\n                \"Torsdag\",\n                \"Fredag\",\n                \"Lørdag\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Mai\",\n                \"Jun\",\n                \"Jul\",\n                \"Aug\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Des\",\n            ],\n            longhand: [\n                \"Januar\",\n                \"Februar\",\n                \"Mars\",\n                \"April\",\n                \"Mai\",\n                \"Juni\",\n                \"Juli\",\n                \"August\",\n                \"September\",\n                \"Oktober\",\n                \"November\",\n                \"Desember\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" til \",\n        weekAbbreviation: \"Uke\",\n        scrollTitle: \"Scroll for å endre\",\n        toggleTitle: \"Klikk for å veksle\",\n        time_24hr: true,\n        ordinal: function () {\n            return \".\";\n        },\n    };\n    fp$G.l10ns.no = Norwegian;\n    fp$G.l10ns;\n\n    var fp$H = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Punjabi = {\n        weekdays: {\n            shorthand: [\"ਐਤ\", \"ਸੋਮ\", \"ਮੰਗਲ\", \"ਬੁੱਧ\", \"ਵੀਰ\", \"ਸ਼ੁੱਕਰ\", \"ਸ਼ਨਿੱਚਰ\"],\n            longhand: [\n                \"ਐਤਵਾਰ\",\n                \"ਸੋਮਵਾਰ\",\n                \"ਮੰਗਲਵਾਰ\",\n                \"ਬੁੱਧਵਾਰ\",\n                \"ਵੀਰਵਾਰ\",\n                \"ਸ਼ੁੱਕਰਵਾਰ\",\n                \"ਸ਼ਨਿੱਚਰਵਾਰ\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"ਜਨ\",\n                \"ਫ਼ਰ\",\n                \"ਮਾਰ\",\n                \"ਅਪ੍ਰੈ\",\n                \"ਮਈ\",\n                \"ਜੂਨ\",\n                \"ਜੁਲਾ\",\n                \"ਅਗ\",\n                \"ਸਤੰ\",\n                \"ਅਕ\",\n                \"ਨਵੰ\",\n                \"ਦਸੰ\",\n            ],\n            longhand: [\n                \"ਜਨਵਰੀ\",\n                \"ਫ਼ਰਵਰੀ\",\n                \"ਮਾਰਚ\",\n                \"ਅਪ੍ਰੈਲ\",\n                \"ਮਈ\",\n                \"ਜੂਨ\",\n                \"ਜੁਲਾਈ\",\n                \"ਅਗਸਤ\",\n                \"ਸਤੰਬਰ\",\n                \"ਅਕਤੂਬਰ\",\n                \"ਨਵੰਬਰ\",\n                \"ਦਸੰਬਰ\",\n            ],\n        },\n        time_24hr: true,\n    };\n    fp$H.l10ns.pa = Punjabi;\n    fp$H.l10ns;\n\n    var fp$I = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Polish = {\n        weekdays: {\n            shorthand: [\"Nd\", \"Pn\", \"Wt\", \"Śr\", \"Cz\", \"Pt\", \"So\"],\n            longhand: [\n                \"Niedziela\",\n                \"Poniedziałek\",\n                \"Wtorek\",\n                \"Środa\",\n                \"Czwartek\",\n                \"Piątek\",\n                \"Sobota\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Sty\",\n                \"Lut\",\n                \"Mar\",\n                \"Kwi\",\n                \"Maj\",\n                \"Cze\",\n                \"Lip\",\n                \"Sie\",\n                \"Wrz\",\n                \"Paź\",\n                \"Lis\",\n                \"Gru\",\n            ],\n            longhand: [\n                \"Styczeń\",\n                \"Luty\",\n                \"Marzec\",\n                \"Kwiecień\",\n                \"Maj\",\n                \"Czerwiec\",\n                \"Lipiec\",\n                \"Sierpień\",\n                \"Wrzesień\",\n                \"Październik\",\n                \"Listopad\",\n                \"Grudzień\",\n            ],\n        },\n        rangeSeparator: \" do \",\n        weekAbbreviation: \"tydz.\",\n        scrollTitle: \"Przewiń, aby zwiększyć\",\n        toggleTitle: \"Kliknij, aby przełączyć\",\n        firstDayOfWeek: 1,\n        time_24hr: true,\n        ordinal: function () {\n            return \".\";\n        },\n    };\n    fp$I.l10ns.pl = Polish;\n    fp$I.l10ns;\n\n    var fp$J = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Portuguese = {\n        weekdays: {\n            shorthand: [\"Dom\", \"Seg\", \"Ter\", \"Qua\", \"Qui\", \"Sex\", \"Sáb\"],\n            longhand: [\n                \"Domingo\",\n                \"Segunda-feira\",\n                \"Terça-feira\",\n                \"Quarta-feira\",\n                \"Quinta-feira\",\n                \"Sexta-feira\",\n                \"Sábado\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Fev\",\n                \"Mar\",\n                \"Abr\",\n                \"Mai\",\n                \"Jun\",\n                \"Jul\",\n                \"Ago\",\n                \"Set\",\n                \"Out\",\n                \"Nov\",\n                \"Dez\",\n            ],\n            longhand: [\n                \"Janeiro\",\n                \"Fevereiro\",\n                \"Março\",\n                \"Abril\",\n                \"Maio\",\n                \"Junho\",\n                \"Julho\",\n                \"Agosto\",\n                \"Setembro\",\n                \"Outubro\",\n                \"Novembro\",\n                \"Dezembro\",\n            ],\n        },\n        rangeSeparator: \" até \",\n        time_24hr: true,\n    };\n    fp$J.l10ns.pt = Portuguese;\n    fp$J.l10ns;\n\n    var fp$K = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Romanian = {\n        weekdays: {\n            shorthand: [\"Dum\", \"Lun\", \"Mar\", \"Mie\", \"Joi\", \"Vin\", \"Sâm\"],\n            longhand: [\n                \"Duminică\",\n                \"Luni\",\n                \"Marți\",\n                \"Miercuri\",\n                \"Joi\",\n                \"Vineri\",\n                \"Sâmbătă\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Ian\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Mai\",\n                \"Iun\",\n                \"Iul\",\n                \"Aug\",\n                \"Sep\",\n                \"Oct\",\n                \"Noi\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"Ianuarie\",\n                \"Februarie\",\n                \"Martie\",\n                \"Aprilie\",\n                \"Mai\",\n                \"Iunie\",\n                \"Iulie\",\n                \"August\",\n                \"Septembrie\",\n                \"Octombrie\",\n                \"Noiembrie\",\n                \"Decembrie\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        time_24hr: true,\n        ordinal: function () {\n            return \"\";\n        },\n    };\n    fp$K.l10ns.ro = Romanian;\n    fp$K.l10ns;\n\n    var fp$L = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Russian = {\n        weekdays: {\n            shorthand: [\"Вс\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\"],\n            longhand: [\n                \"Воскресенье\",\n                \"Понедельник\",\n                \"Вторник\",\n                \"Среда\",\n                \"Четверг\",\n                \"Пятница\",\n                \"Суббота\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Янв\",\n                \"Фев\",\n                \"Март\",\n                \"Апр\",\n                \"Май\",\n                \"Июнь\",\n                \"Июль\",\n                \"Авг\",\n                \"Сен\",\n                \"Окт\",\n                \"Ноя\",\n                \"Дек\",\n            ],\n            longhand: [\n                \"Январь\",\n                \"Февраль\",\n                \"Март\",\n                \"Апрель\",\n                \"Май\",\n                \"Июнь\",\n                \"Июль\",\n                \"Август\",\n                \"Сентябрь\",\n                \"Октябрь\",\n                \"Ноябрь\",\n                \"Декабрь\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        rangeSeparator: \" — \",\n        weekAbbreviation: \"Нед.\",\n        scrollTitle: \"Прокрутите для увеличения\",\n        toggleTitle: \"Нажмите для переключения\",\n        amPM: [\"ДП\", \"ПП\"],\n        yearAriaLabel: \"Год\",\n        time_24hr: true,\n    };\n    fp$L.l10ns.ru = Russian;\n    fp$L.l10ns;\n\n    var fp$M = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Sinhala = {\n        weekdays: {\n            shorthand: [\"ඉ\", \"ස\", \"අ\", \"බ\", \"බ්‍ර\", \"සි\", \"සෙ\"],\n            longhand: [\n                \"ඉරිදා\",\n                \"සඳුදා\",\n                \"අඟහරුවාදා\",\n                \"බදාදා\",\n                \"බ්‍රහස්පතින්දා\",\n                \"සිකුරාදා\",\n                \"සෙනසුරාදා\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"ජන\",\n                \"පෙබ\",\n                \"මාර්\",\n                \"අප්‍රේ\",\n                \"මැයි\",\n                \"ජුනි\",\n                \"ජූලි\",\n                \"අගෝ\",\n                \"සැප්\",\n                \"ඔක්\",\n                \"නොවැ\",\n                \"දෙසැ\",\n            ],\n            longhand: [\n                \"ජනවාරි\",\n                \"පෙබරවාරි\",\n                \"මාර්තු\",\n                \"අප්‍රේල්\",\n                \"මැයි\",\n                \"ජුනි\",\n                \"ජූලි\",\n                \"අගෝස්තු\",\n                \"සැප්තැම්බර්\",\n                \"ඔක්තෝබර්\",\n                \"නොවැම්බර්\",\n                \"දෙසැම්බර්\",\n            ],\n        },\n        time_24hr: true,\n    };\n    fp$M.l10ns.si = Sinhala;\n    fp$M.l10ns;\n\n    var fp$N = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Slovak = {\n        weekdays: {\n            shorthand: [\"Ned\", \"Pon\", \"Ut\", \"Str\", \"Štv\", \"Pia\", \"Sob\"],\n            longhand: [\n                \"Nedeľa\",\n                \"Pondelok\",\n                \"Utorok\",\n                \"Streda\",\n                \"Štvrtok\",\n                \"Piatok\",\n                \"Sobota\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Máj\",\n                \"Jún\",\n                \"Júl\",\n                \"Aug\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"Január\",\n                \"Február\",\n                \"Marec\",\n                \"Apríl\",\n                \"Máj\",\n                \"Jún\",\n                \"Júl\",\n                \"August\",\n                \"September\",\n                \"Október\",\n                \"November\",\n                \"December\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" do \",\n        time_24hr: true,\n        ordinal: function () {\n            return \".\";\n        },\n    };\n    fp$N.l10ns.sk = Slovak;\n    fp$N.l10ns;\n\n    var fp$O = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Slovenian = {\n        weekdays: {\n            shorthand: [\"Ned\", \"Pon\", \"Tor\", \"Sre\", \"Čet\", \"Pet\", \"Sob\"],\n            longhand: [\n                \"Nedelja\",\n                \"Ponedeljek\",\n                \"Torek\",\n                \"Sreda\",\n                \"Četrtek\",\n                \"Petek\",\n                \"Sobota\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Maj\",\n                \"Jun\",\n                \"Jul\",\n                \"Avg\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"Januar\",\n                \"Februar\",\n                \"Marec\",\n                \"April\",\n                \"Maj\",\n                \"Junij\",\n                \"Julij\",\n                \"Avgust\",\n                \"September\",\n                \"Oktober\",\n                \"November\",\n                \"December\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" do \",\n        time_24hr: true,\n        ordinal: function () {\n            return \".\";\n        },\n    };\n    fp$O.l10ns.sl = Slovenian;\n    fp$O.l10ns;\n\n    var fp$P = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Albanian = {\n        weekdays: {\n            shorthand: [\"Di\", \"Hë\", \"Ma\", \"Më\", \"En\", \"Pr\", \"Sh\"],\n            longhand: [\n                \"E Diel\",\n                \"E Hënë\",\n                \"E Martë\",\n                \"E Mërkurë\",\n                \"E Enjte\",\n                \"E Premte\",\n                \"E Shtunë\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Shk\",\n                \"Mar\",\n                \"Pri\",\n                \"Maj\",\n                \"Qer\",\n                \"Kor\",\n                \"Gus\",\n                \"Sht\",\n                \"Tet\",\n                \"Nën\",\n                \"Dhj\",\n            ],\n            longhand: [\n                \"Janar\",\n                \"Shkurt\",\n                \"Mars\",\n                \"Prill\",\n                \"Maj\",\n                \"Qershor\",\n                \"Korrik\",\n                \"Gusht\",\n                \"Shtator\",\n                \"Tetor\",\n                \"Nëntor\",\n                \"Dhjetor\",\n            ],\n        },\n        time_24hr: true,\n    };\n    fp$P.l10ns.sq = Albanian;\n    fp$P.l10ns;\n\n    var fp$Q = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Serbian = {\n        weekdays: {\n            shorthand: [\"Ned\", \"Pon\", \"Uto\", \"Sre\", \"Čet\", \"Pet\", \"Sub\"],\n            longhand: [\n                \"Nedelja\",\n                \"Ponedeljak\",\n                \"Utorak\",\n                \"Sreda\",\n                \"Četvrtak\",\n                \"Petak\",\n                \"Subota\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Jan\",\n                \"Feb\",\n                \"Mar\",\n                \"Apr\",\n                \"Maj\",\n                \"Jun\",\n                \"Jul\",\n                \"Avg\",\n                \"Sep\",\n                \"Okt\",\n                \"Nov\",\n                \"Dec\",\n            ],\n            longhand: [\n                \"Januar\",\n                \"Februar\",\n                \"Mart\",\n                \"April\",\n                \"Maj\",\n                \"Jun\",\n                \"Jul\",\n                \"Avgust\",\n                \"Septembar\",\n                \"Oktobar\",\n                \"Novembar\",\n                \"Decembar\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        weekAbbreviation: \"Ned.\",\n        rangeSeparator: \" do \",\n        time_24hr: true,\n    };\n    fp$Q.l10ns.sr = Serbian;\n    fp$Q.l10ns;\n\n    var fp$R = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Swedish = {\n        firstDayOfWeek: 1,\n        weekAbbreviation: \"v\",\n        weekdays: {\n            shorthand: [\"sön\", \"mån\", \"tis\", \"ons\", \"tor\", \"fre\", \"lör\"],\n            longhand: [\n                \"söndag\",\n                \"måndag\",\n                \"tisdag\",\n                \"onsdag\",\n                \"torsdag\",\n                \"fredag\",\n                \"lördag\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"jan\",\n                \"feb\",\n                \"mar\",\n                \"apr\",\n                \"maj\",\n                \"jun\",\n                \"jul\",\n                \"aug\",\n                \"sep\",\n                \"okt\",\n                \"nov\",\n                \"dec\",\n            ],\n            longhand: [\n                \"januari\",\n                \"februari\",\n                \"mars\",\n                \"april\",\n                \"maj\",\n                \"juni\",\n                \"juli\",\n                \"augusti\",\n                \"september\",\n                \"oktober\",\n                \"november\",\n                \"december\",\n            ],\n        },\n        rangeSeparator: ' till ',\n        time_24hr: true,\n        ordinal: function () {\n            return \".\";\n        },\n    };\n    fp$R.l10ns.sv = Swedish;\n    fp$R.l10ns;\n\n    var fp$S = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Thai = {\n        weekdays: {\n            shorthand: [\"อา\", \"จ\", \"อ\", \"พ\", \"พฤ\", \"ศ\", \"ส\"],\n            longhand: [\n                \"อาทิตย์\",\n                \"จันทร์\",\n                \"อังคาร\",\n                \"พุธ\",\n                \"พฤหัสบดี\",\n                \"ศุกร์\",\n                \"เสาร์\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"ม.ค.\",\n                \"ก.พ.\",\n                \"มี.ค.\",\n                \"เม.ย.\",\n                \"พ.ค.\",\n                \"มิ.ย.\",\n                \"ก.ค.\",\n                \"ส.ค.\",\n                \"ก.ย.\",\n                \"ต.ค.\",\n                \"พ.ย.\",\n                \"ธ.ค.\",\n            ],\n            longhand: [\n                \"มกราคม\",\n                \"กุมภาพันธ์\",\n                \"มีนาคม\",\n                \"เมษายน\",\n                \"พฤษภาคม\",\n                \"มิถุนายน\",\n                \"กรกฎาคม\",\n                \"สิงหาคม\",\n                \"กันยายน\",\n                \"ตุลาคม\",\n                \"พฤศจิกายน\",\n                \"ธันวาคม\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" ถึง \",\n        scrollTitle: \"เลื่อนเพื่อเพิ่มหรือลด\",\n        toggleTitle: \"คลิกเพื่อเปลี่ยน\",\n        time_24hr: true,\n        ordinal: function () {\n            return \"\";\n        },\n    };\n    fp$S.l10ns.th = Thai;\n    fp$S.l10ns;\n\n    var fp$T = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Turkish = {\n        weekdays: {\n            shorthand: [\"Paz\", \"Pzt\", \"Sal\", \"Çar\", \"Per\", \"Cum\", \"Cmt\"],\n            longhand: [\n                \"Pazar\",\n                \"Pazartesi\",\n                \"Salı\",\n                \"Çarşamba\",\n                \"Perşembe\",\n                \"Cuma\",\n                \"Cumartesi\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Oca\",\n                \"Şub\",\n                \"Mar\",\n                \"Nis\",\n                \"May\",\n                \"Haz\",\n                \"Tem\",\n                \"Ağu\",\n                \"Eyl\",\n                \"Eki\",\n                \"Kas\",\n                \"Ara\",\n            ],\n            longhand: [\n                \"Ocak\",\n                \"Şubat\",\n                \"Mart\",\n                \"Nisan\",\n                \"Mayıs\",\n                \"Haziran\",\n                \"Temmuz\",\n                \"Ağustos\",\n                \"Eylül\",\n                \"Ekim\",\n                \"Kasım\",\n                \"Aralık\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \".\";\n        },\n        rangeSeparator: \" - \",\n        weekAbbreviation: \"Hf\",\n        scrollTitle: \"Artırmak için kaydırın\",\n        toggleTitle: \"Aç/Kapa\",\n        amPM: [\"ÖÖ\", \"ÖS\"],\n        time_24hr: true,\n    };\n    fp$T.l10ns.tr = Turkish;\n    fp$T.l10ns;\n\n    var fp$U = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Ukrainian = {\n        firstDayOfWeek: 1,\n        weekdays: {\n            shorthand: [\"Нд\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\"],\n            longhand: [\n                \"Неділя\",\n                \"Понеділок\",\n                \"Вівторок\",\n                \"Середа\",\n                \"Четвер\",\n                \"П'ятниця\",\n                \"Субота\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Січ\",\n                \"Лют\",\n                \"Бер\",\n                \"Кві\",\n                \"Тра\",\n                \"Чер\",\n                \"Лип\",\n                \"Сер\",\n                \"Вер\",\n                \"Жов\",\n                \"Лис\",\n                \"Гру\",\n            ],\n            longhand: [\n                \"Січень\",\n                \"Лютий\",\n                \"Березень\",\n                \"Квітень\",\n                \"Травень\",\n                \"Червень\",\n                \"Липень\",\n                \"Серпень\",\n                \"Вересень\",\n                \"Жовтень\",\n                \"Листопад\",\n                \"Грудень\",\n            ],\n        },\n        time_24hr: true,\n    };\n    fp$U.l10ns.uk = Ukrainian;\n    fp$U.l10ns;\n\n    var fp$V = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Uzbek = {\n        weekdays: {\n            shorthand: [\"Якш\", \"Душ\", \"Сеш\", \"Чор\", \"Пай\", \"Жум\", \"Шан\"],\n            longhand: [\n                \"Якшанба\",\n                \"Душанба\",\n                \"Сешанба\",\n                \"Чоршанба\",\n                \"Пайшанба\",\n                \"Жума\",\n                \"Шанба\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Янв\",\n                \"Фев\",\n                \"Мар\",\n                \"Апр\",\n                \"Май\",\n                \"Июн\",\n                \"Июл\",\n                \"Авг\",\n                \"Сен\",\n                \"Окт\",\n                \"Ноя\",\n                \"Дек\",\n            ],\n            longhand: [\n                \"Январ\",\n                \"Феврал\",\n                \"Март\",\n                \"Апрел\",\n                \"Май\",\n                \"Июн\",\n                \"Июл\",\n                \"Август\",\n                \"Сентябр\",\n                \"Октябр\",\n                \"Ноябр\",\n                \"Декабр\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        rangeSeparator: \" — \",\n        weekAbbreviation: \"Ҳафта\",\n        scrollTitle: \"Катталаштириш учун айлантиринг\",\n        toggleTitle: \"Ўтиш учун босинг\",\n        amPM: [\"AM\", \"PM\"],\n        yearAriaLabel: \"Йил\",\n        time_24hr: true,\n    };\n    fp$V.l10ns.uz = Uzbek;\n    fp$V.l10ns;\n\n    var fp$W = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var UzbekLatin = {\n        weekdays: {\n            shorthand: [\"Ya\", \"Du\", \"Se\", \"Cho\", \"Pa\", \"Ju\", \"Sha\"],\n            longhand: [\n                \"Yakshanba\",\n                \"Dushanba\",\n                \"Seshanba\",\n                \"Chorshanba\",\n                \"Payshanba\",\n                \"Juma\",\n                \"Shanba\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Yan\",\n                \"Fev\",\n                \"Mar\",\n                \"Apr\",\n                \"May\",\n                \"Iyun\",\n                \"Iyul\",\n                \"Avg\",\n                \"Sen\",\n                \"Okt\",\n                \"Noy\",\n                \"Dek\",\n            ],\n            longhand: [\n                \"Yanvar\",\n                \"Fevral\",\n                \"Mart\",\n                \"Aprel\",\n                \"May\",\n                \"Iyun\",\n                \"Iyul\",\n                \"Avgust\",\n                \"Sentabr\",\n                \"Oktabr\",\n                \"Noyabr\",\n                \"Dekabr\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        ordinal: function () {\n            return \"\";\n        },\n        rangeSeparator: \" — \",\n        weekAbbreviation: \"Hafta\",\n        scrollTitle: \"Kattalashtirish uchun aylantiring\",\n        toggleTitle: \"O‘tish uchun bosing\",\n        amPM: [\"AM\", \"PM\"],\n        yearAriaLabel: \"Yil\",\n        time_24hr: true,\n    };\n    fp$W.l10ns[\"uz_latn\"] = UzbekLatin;\n    fp$W.l10ns;\n\n    var fp$X = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Vietnamese = {\n        weekdays: {\n            shorthand: [\"CN\", \"T2\", \"T3\", \"T4\", \"T5\", \"T6\", \"T7\"],\n            longhand: [\n                \"Chủ nhật\",\n                \"Thứ hai\",\n                \"Thứ ba\",\n                \"Thứ tư\",\n                \"Thứ năm\",\n                \"Thứ sáu\",\n                \"Thứ bảy\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"Th1\",\n                \"Th2\",\n                \"Th3\",\n                \"Th4\",\n                \"Th5\",\n                \"Th6\",\n                \"Th7\",\n                \"Th8\",\n                \"Th9\",\n                \"Th10\",\n                \"Th11\",\n                \"Th12\",\n            ],\n            longhand: [\n                \"Tháng một\",\n                \"Tháng hai\",\n                \"Tháng ba\",\n                \"Tháng tư\",\n                \"Tháng năm\",\n                \"Tháng sáu\",\n                \"Tháng bảy\",\n                \"Tháng tám\",\n                \"Tháng chín\",\n                \"Tháng mười\",\n                \"Tháng mười một\",\n                \"Tháng mười hai\",\n            ],\n        },\n        firstDayOfWeek: 1,\n        rangeSeparator: \" đến \",\n    };\n    fp$X.l10ns.vn = Vietnamese;\n    fp$X.l10ns;\n\n    var fp$Y = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var Mandarin = {\n        weekdays: {\n            shorthand: [\"周日\", \"周一\", \"周二\", \"周三\", \"周四\", \"周五\", \"周六\"],\n            longhand: [\n                \"星期日\",\n                \"星期一\",\n                \"星期二\",\n                \"星期三\",\n                \"星期四\",\n                \"星期五\",\n                \"星期六\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"一月\",\n                \"二月\",\n                \"三月\",\n                \"四月\",\n                \"五月\",\n                \"六月\",\n                \"七月\",\n                \"八月\",\n                \"九月\",\n                \"十月\",\n                \"十一月\",\n                \"十二月\",\n            ],\n            longhand: [\n                \"一月\",\n                \"二月\",\n                \"三月\",\n                \"四月\",\n                \"五月\",\n                \"六月\",\n                \"七月\",\n                \"八月\",\n                \"九月\",\n                \"十月\",\n                \"十一月\",\n                \"十二月\",\n            ],\n        },\n        rangeSeparator: \" 至 \",\n        weekAbbreviation: \"周\",\n        scrollTitle: \"滚动切换\",\n        toggleTitle: \"点击切换 12/24 小时时制\",\n    };\n    fp$Y.l10ns.zh = Mandarin;\n    fp$Y.l10ns;\n\n    var fp$Z = typeof window !== \"undefined\" && window.flatpickr !== undefined\n        ? window.flatpickr\n        : {\n            l10ns: {},\n        };\n    var MandarinTraditional = {\n        weekdays: {\n            shorthand: [\"週日\", \"週一\", \"週二\", \"週三\", \"週四\", \"週五\", \"週六\"],\n            longhand: [\n                \"星期日\",\n                \"星期一\",\n                \"星期二\",\n                \"星期三\",\n                \"星期四\",\n                \"星期五\",\n                \"星期六\",\n            ],\n        },\n        months: {\n            shorthand: [\n                \"一月\",\n                \"二月\",\n                \"三月\",\n                \"四月\",\n                \"五月\",\n                \"六月\",\n                \"七月\",\n                \"八月\",\n                \"九月\",\n                \"十月\",\n                \"十一月\",\n                \"十二月\",\n            ],\n            longhand: [\n                \"一月\",\n                \"二月\",\n                \"三月\",\n                \"四月\",\n                \"五月\",\n                \"六月\",\n                \"七月\",\n                \"八月\",\n                \"九月\",\n                \"十月\",\n                \"十一月\",\n                \"十二月\",\n            ],\n        },\n        rangeSeparator: \" 至 \",\n        weekAbbreviation: \"週\",\n        scrollTitle: \"滾動切換\",\n        toggleTitle: \"點擊切換 12/24 小時時制\",\n    };\n    fp$Z.l10ns.zh_tw = MandarinTraditional;\n    fp$Z.l10ns;\n\n    var l10n = {\n        ar: Arabic,\n        at: Austria,\n        az: Azerbaijan,\n        be: Belarusian,\n        bg: Bulgarian,\n        bn: Bangla,\n        bs: Bosnian,\n        ca: Catalan,\n        ckb: Kurdish,\n        cat: Catalan,\n        cs: Czech,\n        cy: Welsh,\n        da: Danish,\n        de: German,\n        default: __assign({}, english),\n        en: english,\n        eo: Esperanto,\n        es: Spanish,\n        et: Estonian,\n        fa: Persian,\n        fi: Finnish,\n        fo: Faroese,\n        fr: French,\n        gr: Greek,\n        he: Hebrew,\n        hi: Hindi,\n        hr: Croatian,\n        hu: Hungarian,\n        hy: Armenian,\n        id: Indonesian,\n        is: Icelandic,\n        it: Italian,\n        ja: Japanese,\n        ka: Georgian,\n        ko: Korean,\n        km: Khmer,\n        kz: Kazakh,\n        lt: Lithuanian,\n        lv: Latvian,\n        mk: Macedonian,\n        mn: Mongolian,\n        ms: Malaysian,\n        my: Burmese,\n        nl: Dutch,\n        nn: NorwegianNynorsk,\n        no: Norwegian,\n        pa: Punjabi,\n        pl: Polish,\n        pt: Portuguese,\n        ro: Romanian,\n        ru: Russian,\n        si: Sinhala,\n        sk: Slovak,\n        sl: Slovenian,\n        sq: Albanian,\n        sr: Serbian,\n        sv: Swedish,\n        th: Thai,\n        tr: Turkish,\n        uk: Ukrainian,\n        vn: Vietnamese,\n        zh: Mandarin,\n        zh_tw: MandarinTraditional,\n        uz: Uzbek,\n        uz_latn: UzbekLatin,\n    };\n\n    exports.default = l10n;\n\n    Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.is = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Icelandic = {\n      weekdays: {\n          shorthand: [\"Sun\", \"Mán\", \"Þri\", \"Mið\", \"Fim\", \"Fös\", \"Lau\"],\n          longhand: [\n              \"Sunnudagur\",\n              \"Mánudagur\",\n              \"Þriðjudagur\",\n              \"Miðvikudagur\",\n              \"Fimmtudagur\",\n              \"Föstudagur\",\n              \"Laugardagur\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Maí\",\n              \"Jún\",\n              \"Júl\",\n              \"Ágú\",\n              \"Sep\",\n              \"Okt\",\n              \"Nóv\",\n              \"Des\",\n          ],\n          longhand: [\n              \"Janúar\",\n              \"Febrúar\",\n              \"Mars\",\n              \"Apríl\",\n              \"Maí\",\n              \"Júní\",\n              \"Júlí\",\n              \"Ágúst\",\n              \"September\",\n              \"Október\",\n              \"Nóvember\",\n              \"Desember\",\n          ],\n      },\n      ordinal: function () {\n          return \".\";\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" til \",\n      weekAbbreviation: \"vika\",\n      yearAriaLabel: \"Ár\",\n      time_24hr: true,\n  };\n  fp.l10ns.is = Icelandic;\n  var is = fp.l10ns;\n\n  exports.Icelandic = Icelandic;\n  exports.default = is;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.it = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Italian = {\n      weekdays: {\n          shorthand: [\"Dom\", \"Lun\", \"Mar\", \"Mer\", \"Gio\", \"Ven\", \"Sab\"],\n          longhand: [\n              \"Domenica\",\n              \"Lunedì\",\n              \"Martedì\",\n              \"Mercoledì\",\n              \"Giovedì\",\n              \"Venerdì\",\n              \"Sabato\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Gen\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Mag\",\n              \"Giu\",\n              \"Lug\",\n              \"Ago\",\n              \"Set\",\n              \"Ott\",\n              \"Nov\",\n              \"Dic\",\n          ],\n          longhand: [\n              \"Gennaio\",\n              \"Febbraio\",\n              \"Marzo\",\n              \"Aprile\",\n              \"Maggio\",\n              \"Giugno\",\n              \"Luglio\",\n              \"Agosto\",\n              \"Settembre\",\n              \"Ottobre\",\n              \"Novembre\",\n              \"Dicembre\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () { return \"°\"; },\n      rangeSeparator: \" al \",\n      weekAbbreviation: \"Se\",\n      scrollTitle: \"Scrolla per aumentare\",\n      toggleTitle: \"Clicca per cambiare\",\n      time_24hr: true,\n  };\n  fp.l10ns.it = Italian;\n  var it = fp.l10ns;\n\n  exports.Italian = Italian;\n  exports.default = it;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ja = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Japanese = {\n      weekdays: {\n          shorthand: [\"日\", \"月\", \"火\", \"水\", \"木\", \"金\", \"土\"],\n          longhand: [\n              \"日曜日\",\n              \"月曜日\",\n              \"火曜日\",\n              \"水曜日\",\n              \"木曜日\",\n              \"金曜日\",\n              \"土曜日\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"1月\",\n              \"2月\",\n              \"3月\",\n              \"4月\",\n              \"5月\",\n              \"6月\",\n              \"7月\",\n              \"8月\",\n              \"9月\",\n              \"10月\",\n              \"11月\",\n              \"12月\",\n          ],\n          longhand: [\n              \"1月\",\n              \"2月\",\n              \"3月\",\n              \"4月\",\n              \"5月\",\n              \"6月\",\n              \"7月\",\n              \"8月\",\n              \"9月\",\n              \"10月\",\n              \"11月\",\n              \"12月\",\n          ],\n      },\n      time_24hr: true,\n      rangeSeparator: \" から \",\n      monthAriaLabel: \"月\",\n      amPM: [\"午前\", \"午後\"],\n      yearAriaLabel: \"年\",\n      hourAriaLabel: \"時間\",\n      minuteAriaLabel: \"分\",\n  };\n  fp.l10ns.ja = Japanese;\n  var ja = fp.l10ns;\n\n  exports.Japanese = Japanese;\n  exports.default = ja;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ka = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Georgian = {\n      weekdays: {\n          shorthand: [\"კვ\", \"ორ\", \"სა\", \"ოთ\", \"ხუ\", \"პა\", \"შა\"],\n          longhand: [\n              \"კვირა\",\n              \"ორშაბათი\",\n              \"სამშაბათი\",\n              \"ოთხშაბათი\",\n              \"ხუთშაბათი\",\n              \"პარასკევი\",\n              \"შაბათი\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"იან\",\n              \"თებ\",\n              \"მარ\",\n              \"აპრ\",\n              \"მაი\",\n              \"ივნ\",\n              \"ივლ\",\n              \"აგვ\",\n              \"სექ\",\n              \"ოქტ\",\n              \"ნოე\",\n              \"დეკ\",\n          ],\n          longhand: [\n              \"იანვარი\",\n              \"თებერვალი\",\n              \"მარტი\",\n              \"აპრილი\",\n              \"მაისი\",\n              \"ივნისი\",\n              \"ივლისი\",\n              \"აგვისტო\",\n              \"სექტემბერი\",\n              \"ოქტომბერი\",\n              \"ნოემბერი\",\n              \"დეკემბერი\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      rangeSeparator: \" — \",\n      weekAbbreviation: \"კვ.\",\n      scrollTitle: \"დასქროლეთ გასადიდებლად\",\n      toggleTitle: \"დააკლიკეთ გადართვისთვის\",\n      amPM: [\"AM\", \"PM\"],\n      yearAriaLabel: \"წელი\",\n      time_24hr: true,\n  };\n  fp.l10ns.ka = Georgian;\n  var ka = fp.l10ns;\n\n  exports.Georgian = Georgian;\n  exports.default = ka;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.km = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Khmer = {\n      weekdays: {\n          shorthand: [\"អាទិត្យ\", \"ចន្ទ\", \"អង្គារ\", \"ពុធ\", \"ព្រហស.\", \"សុក្រ\", \"សៅរ៍\"],\n          longhand: [\n              \"អាទិត្យ\",\n              \"ចន្ទ\",\n              \"អង្គារ\",\n              \"ពុធ\",\n              \"ព្រហស្បតិ៍\",\n              \"សុក្រ\",\n              \"សៅរ៍\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"មករា\",\n              \"កុម្ភះ\",\n              \"មីនា\",\n              \"មេសា\",\n              \"ឧសភា\",\n              \"មិថុនា\",\n              \"កក្កដា\",\n              \"សីហា\",\n              \"កញ្ញា\",\n              \"តុលា\",\n              \"វិច្ឆិកា\",\n              \"ធ្នូ\",\n          ],\n          longhand: [\n              \"មករា\",\n              \"កុម្ភះ\",\n              \"មីនា\",\n              \"មេសា\",\n              \"ឧសភា\",\n              \"មិថុនា\",\n              \"កក្កដា\",\n              \"សីហា\",\n              \"កញ្ញា\",\n              \"តុលា\",\n              \"វិច្ឆិកា\",\n              \"ធ្នូ\",\n          ],\n      },\n      ordinal: function () {\n          return \"\";\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" ដល់ \",\n      weekAbbreviation: \"សប្តាហ៍\",\n      scrollTitle: \"រំកិលដើម្បីបង្កើន\",\n      toggleTitle: \"ចុចដើម្បីផ្លាស់ប្ដូរ\",\n      yearAriaLabel: \"ឆ្នាំ\",\n      time_24hr: true,\n  };\n  fp.l10ns.km = Khmer;\n  var km = fp.l10ns;\n\n  exports.Khmer = Khmer;\n  exports.default = km;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ko = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Korean = {\n      weekdays: {\n          shorthand: [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\"],\n          longhand: [\n              \"일요일\",\n              \"월요일\",\n              \"화요일\",\n              \"수요일\",\n              \"목요일\",\n              \"금요일\",\n              \"토요일\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"1월\",\n              \"2월\",\n              \"3월\",\n              \"4월\",\n              \"5월\",\n              \"6월\",\n              \"7월\",\n              \"8월\",\n              \"9월\",\n              \"10월\",\n              \"11월\",\n              \"12월\",\n          ],\n          longhand: [\n              \"1월\",\n              \"2월\",\n              \"3월\",\n              \"4월\",\n              \"5월\",\n              \"6월\",\n              \"7월\",\n              \"8월\",\n              \"9월\",\n              \"10월\",\n              \"11월\",\n              \"12월\",\n          ],\n      },\n      ordinal: function () {\n          return \"일\";\n      },\n      rangeSeparator: \" ~ \",\n      amPM: [\"오전\", \"오후\"],\n  };\n  fp.l10ns.ko = Korean;\n  var ko = fp.l10ns;\n\n  exports.Korean = Korean;\n  exports.default = ko;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.kz = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Kazakh = {\n      weekdays: {\n          shorthand: [\"Жс\", \"Дс\", \"Сc\", \"Ср\", \"Бс\", \"Жм\", \"Сб\"],\n          longhand: [\n              \"Жексенбi\",\n              \"Дүйсенбi\",\n              \"Сейсенбi\",\n              \"Сәрсенбi\",\n              \"Бейсенбi\",\n              \"Жұма\",\n              \"Сенбi\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Қаң\",\n              \"Ақп\",\n              \"Нау\",\n              \"Сәу\",\n              \"Мам\",\n              \"Мау\",\n              \"Шiл\",\n              \"Там\",\n              \"Қыр\",\n              \"Қаз\",\n              \"Қар\",\n              \"Жел\",\n          ],\n          longhand: [\n              \"Қаңтар\",\n              \"Ақпан\",\n              \"Наурыз\",\n              \"Сәуiр\",\n              \"Мамыр\",\n              \"Маусым\",\n              \"Шiлде\",\n              \"Тамыз\",\n              \"Қыркүйек\",\n              \"Қазан\",\n              \"Қараша\",\n              \"Желтоқсан\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      rangeSeparator: \" — \",\n      weekAbbreviation: \"Апта\",\n      scrollTitle: \"Үлкейту үшін айналдырыңыз\",\n      toggleTitle: \"Ауыстыру үшін басыңыз\",\n      amPM: [\"ТД\", \"ТК\"],\n      yearAriaLabel: \"Жыл\",\n  };\n  fp.l10ns.kz = Kazakh;\n  var kz = fp.l10ns;\n\n  exports.Kazakh = Kazakh;\n  exports.default = kz;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.lt = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Lithuanian = {\n      weekdays: {\n          shorthand: [\"S\", \"Pr\", \"A\", \"T\", \"K\", \"Pn\", \"Š\"],\n          longhand: [\n              \"Sekmadienis\",\n              \"Pirmadienis\",\n              \"Antradienis\",\n              \"Trečiadienis\",\n              \"Ketvirtadienis\",\n              \"Penktadienis\",\n              \"Šeštadienis\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Sau\",\n              \"Vas\",\n              \"Kov\",\n              \"Bal\",\n              \"Geg\",\n              \"Bir\",\n              \"Lie\",\n              \"Rgp\",\n              \"Rgs\",\n              \"Spl\",\n              \"Lap\",\n              \"Grd\",\n          ],\n          longhand: [\n              \"Sausis\",\n              \"Vasaris\",\n              \"Kovas\",\n              \"Balandis\",\n              \"Gegužė\",\n              \"Birželis\",\n              \"Liepa\",\n              \"Rugpjūtis\",\n              \"Rugsėjis\",\n              \"Spalis\",\n              \"Lapkritis\",\n              \"Gruodis\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"-a\";\n      },\n      rangeSeparator: \" iki \",\n      weekAbbreviation: \"Sav\",\n      scrollTitle: \"Keisti laiką pelės rateliu\",\n      toggleTitle: \"Perjungti laiko formatą\",\n      time_24hr: true,\n  };\n  fp.l10ns.lt = Lithuanian;\n  var lt = fp.l10ns;\n\n  exports.Lithuanian = Lithuanian;\n  exports.default = lt;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.lv = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Latvian = {\n      firstDayOfWeek: 1,\n      weekdays: {\n          shorthand: [\"Sv\", \"Pr\", \"Ot\", \"Tr\", \"Ce\", \"Pk\", \"Se\"],\n          longhand: [\n              \"Svētdiena\",\n              \"Pirmdiena\",\n              \"Otrdiena\",\n              \"Trešdiena\",\n              \"Ceturtdiena\",\n              \"Piektdiena\",\n              \"Sestdiena\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Mai\",\n              \"Jūn\",\n              \"Jūl\",\n              \"Aug\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dec\",\n          ],\n          longhand: [\n              \"Janvāris\",\n              \"Februāris\",\n              \"Marts\",\n              \"Aprīlis\",\n              \"Maijs\",\n              \"Jūnijs\",\n              \"Jūlijs\",\n              \"Augusts\",\n              \"Septembris\",\n              \"Oktobris\",\n              \"Novembris\",\n              \"Decembris\",\n          ],\n      },\n      rangeSeparator: \" līdz \",\n      time_24hr: true,\n  };\n  fp.l10ns.lv = Latvian;\n  var lv = fp.l10ns;\n\n  exports.Latvian = Latvian;\n  exports.default = lv;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.mk = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Macedonian = {\n      weekdays: {\n          shorthand: [\"Не\", \"По\", \"Вт\", \"Ср\", \"Че\", \"Пе\", \"Са\"],\n          longhand: [\n              \"Недела\",\n              \"Понеделник\",\n              \"Вторник\",\n              \"Среда\",\n              \"Четврток\",\n              \"Петок\",\n              \"Сабота\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Јан\",\n              \"Фев\",\n              \"Мар\",\n              \"Апр\",\n              \"Мај\",\n              \"Јун\",\n              \"Јул\",\n              \"Авг\",\n              \"Сеп\",\n              \"Окт\",\n              \"Ное\",\n              \"Дек\",\n          ],\n          longhand: [\n              \"Јануари\",\n              \"Февруари\",\n              \"Март\",\n              \"Април\",\n              \"Мај\",\n              \"Јуни\",\n              \"Јули\",\n              \"Август\",\n              \"Септември\",\n              \"Октомври\",\n              \"Ноември\",\n              \"Декември\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      weekAbbreviation: \"Нед.\",\n      rangeSeparator: \" до \",\n      time_24hr: true,\n  };\n  fp.l10ns.mk = Macedonian;\n  var mk = fp.l10ns;\n\n  exports.Macedonian = Macedonian;\n  exports.default = mk;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.mn = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Mongolian = {\n      firstDayOfWeek: 1,\n      weekdays: {\n          shorthand: [\"Да\", \"Мя\", \"Лх\", \"Пү\", \"Ба\", \"Бя\", \"Ня\"],\n          longhand: [\"Даваа\", \"Мягмар\", \"Лхагва\", \"Пүрэв\", \"Баасан\", \"Бямба\", \"Ням\"],\n      },\n      months: {\n          shorthand: [\n              \"1-р сар\",\n              \"2-р сар\",\n              \"3-р сар\",\n              \"4-р сар\",\n              \"5-р сар\",\n              \"6-р сар\",\n              \"7-р сар\",\n              \"8-р сар\",\n              \"9-р сар\",\n              \"10-р сар\",\n              \"11-р сар\",\n              \"12-р сар\",\n          ],\n          longhand: [\n              \"Нэгдүгээр сар\",\n              \"Хоёрдугаар сар\",\n              \"Гуравдугаар сар\",\n              \"Дөрөвдүгээр сар\",\n              \"Тавдугаар сар\",\n              \"Зургаадугаар сар\",\n              \"Долдугаар сар\",\n              \"Наймдугаар сар\",\n              \"Есдүгээр сар\",\n              \"Аравдугаар сар\",\n              \"Арваннэгдүгээр сар\",\n              \"Арванхоёрдугаар сар\",\n          ],\n      },\n      rangeSeparator: \"-с \",\n      time_24hr: true,\n  };\n  fp.l10ns.mn = Mongolian;\n  var mn = fp.l10ns;\n\n  exports.Mongolian = Mongolian;\n  exports.default = mn;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ms = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Malaysian = {\n      weekdays: {\n          shorthand: [\"Aha\", \"Isn\", \"Sel\", \"Rab\", \"Kha\", \"Jum\", \"Sab\"],\n          longhand: [\n              \"Ahad\",\n              \"Isnin\",\n              \"Selasa\",\n              \"Rabu\",\n              \"Khamis\",\n              \"Jumaat\",\n              \"Sabtu\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mac\",\n              \"Apr\",\n              \"Mei\",\n              \"Jun\",\n              \"Jul\",\n              \"Ogo\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dis\",\n          ],\n          longhand: [\n              \"Januari\",\n              \"Februari\",\n              \"Mac\",\n              \"April\",\n              \"Mei\",\n              \"Jun\",\n              \"Julai\",\n              \"Ogos\",\n              \"September\",\n              \"Oktober\",\n              \"November\",\n              \"Disember\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n  };\n  var ms = fp.l10ns;\n\n  exports.Malaysian = Malaysian;\n  exports.default = ms;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.my = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Burmese = {\n      weekdays: {\n          shorthand: [\"နွေ\", \"လာ\", \"ဂါ\", \"ဟူး\", \"ကြာ\", \"သော\", \"နေ\"],\n          longhand: [\n              \"တနင်္ဂနွေ\",\n              \"တနင်္လာ\",\n              \"အင်္ဂါ\",\n              \"ဗုဒ္ဓဟူး\",\n              \"ကြာသပတေး\",\n              \"သောကြာ\",\n              \"စနေ\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"ဇန်\",\n              \"ဖေ\",\n              \"မတ်\",\n              \"ပြီ\",\n              \"မေ\",\n              \"ဇွန်\",\n              \"လိုင်\",\n              \"သြ\",\n              \"စက်\",\n              \"အောက်\",\n              \"နို\",\n              \"ဒီ\",\n          ],\n          longhand: [\n              \"ဇန်နဝါရီ\",\n              \"ဖေဖော်ဝါရီ\",\n              \"မတ်\",\n              \"ဧပြီ\",\n              \"မေ\",\n              \"ဇွန်\",\n              \"ဇူလိုင်\",\n              \"သြဂုတ်\",\n              \"စက်တင်ဘာ\",\n              \"အောက်တိုဘာ\",\n              \"နိုဝင်ဘာ\",\n              \"ဒီဇင်ဘာ\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.my = Burmese;\n  var my = fp.l10ns;\n\n  exports.Burmese = Burmese;\n  exports.default = my;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.nl = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Dutch = {\n      weekdays: {\n          shorthand: [\"zo\", \"ma\", \"di\", \"wo\", \"do\", \"vr\", \"za\"],\n          longhand: [\n              \"zondag\",\n              \"maandag\",\n              \"dinsdag\",\n              \"woensdag\",\n              \"donderdag\",\n              \"vrijdag\",\n              \"zaterdag\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"jan\",\n              \"feb\",\n              \"mrt\",\n              \"apr\",\n              \"mei\",\n              \"jun\",\n              \"jul\",\n              \"aug\",\n              \"sept\",\n              \"okt\",\n              \"nov\",\n              \"dec\",\n          ],\n          longhand: [\n              \"januari\",\n              \"februari\",\n              \"maart\",\n              \"april\",\n              \"mei\",\n              \"juni\",\n              \"juli\",\n              \"augustus\",\n              \"september\",\n              \"oktober\",\n              \"november\",\n              \"december\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      weekAbbreviation: \"wk\",\n      rangeSeparator: \" t/m \",\n      scrollTitle: \"Scroll voor volgende / vorige\",\n      toggleTitle: \"Klik om te wisselen\",\n      time_24hr: true,\n      ordinal: function (nth) {\n          if (nth === 1 || nth === 8 || nth >= 20)\n              return \"ste\";\n          return \"de\";\n      },\n  };\n  fp.l10ns.nl = Dutch;\n  var nl = fp.l10ns;\n\n  exports.Dutch = Dutch;\n  exports.default = nl;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.nn = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== 'undefined' && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var NorwegianNynorsk = {\n      weekdays: {\n          shorthand: ['Sø.', 'Må.', 'Ty.', 'On.', 'To.', 'Fr.', 'La.'],\n          longhand: [\n              'Søndag',\n              'Måndag',\n              'Tysdag',\n              'Onsdag',\n              'Torsdag',\n              'Fredag',\n              'Laurdag',\n          ],\n      },\n      months: {\n          shorthand: [\n              'Jan',\n              'Feb',\n              'Mars',\n              'Apr',\n              'Mai',\n              'Juni',\n              'Juli',\n              'Aug',\n              'Sep',\n              'Okt',\n              'Nov',\n              'Des',\n          ],\n          longhand: [\n              'Januar',\n              'Februar',\n              'Mars',\n              'April',\n              'Mai',\n              'Juni',\n              'Juli',\n              'August',\n              'September',\n              'Oktober',\n              'November',\n              'Desember',\n          ],\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: ' til ',\n      weekAbbreviation: 'Veke',\n      scrollTitle: 'Scroll for å endre',\n      toggleTitle: 'Klikk for å veksle',\n      time_24hr: true,\n      ordinal: function () {\n          return '.';\n      },\n  };\n  fp.l10ns.nn = NorwegianNynorsk;\n  var nn = fp.l10ns;\n\n  exports.NorwegianNynorsk = NorwegianNynorsk;\n  exports.default = nn;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.no = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Norwegian = {\n      weekdays: {\n          shorthand: [\"Søn\", \"Man\", \"Tir\", \"Ons\", \"Tor\", \"Fre\", \"Lør\"],\n          longhand: [\n              \"Søndag\",\n              \"Mandag\",\n              \"Tirsdag\",\n              \"Onsdag\",\n              \"Torsdag\",\n              \"Fredag\",\n              \"Lørdag\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Mai\",\n              \"Jun\",\n              \"Jul\",\n              \"Aug\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Des\",\n          ],\n          longhand: [\n              \"Januar\",\n              \"Februar\",\n              \"Mars\",\n              \"April\",\n              \"Mai\",\n              \"Juni\",\n              \"Juli\",\n              \"August\",\n              \"September\",\n              \"Oktober\",\n              \"November\",\n              \"Desember\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" til \",\n      weekAbbreviation: \"Uke\",\n      scrollTitle: \"Scroll for å endre\",\n      toggleTitle: \"Klikk for å veksle\",\n      time_24hr: true,\n      ordinal: function () {\n          return \".\";\n      },\n  };\n  fp.l10ns.no = Norwegian;\n  var no = fp.l10ns;\n\n  exports.Norwegian = Norwegian;\n  exports.default = no;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pa = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Punjabi = {\n      weekdays: {\n          shorthand: [\"ਐਤ\", \"ਸੋਮ\", \"ਮੰਗਲ\", \"ਬੁੱਧ\", \"ਵੀਰ\", \"ਸ਼ੁੱਕਰ\", \"ਸ਼ਨਿੱਚਰ\"],\n          longhand: [\n              \"ਐਤਵਾਰ\",\n              \"ਸੋਮਵਾਰ\",\n              \"ਮੰਗਲਵਾਰ\",\n              \"ਬੁੱਧਵਾਰ\",\n              \"ਵੀਰਵਾਰ\",\n              \"ਸ਼ੁੱਕਰਵਾਰ\",\n              \"ਸ਼ਨਿੱਚਰਵਾਰ\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"ਜਨ\",\n              \"ਫ਼ਰ\",\n              \"ਮਾਰ\",\n              \"ਅਪ੍ਰੈ\",\n              \"ਮਈ\",\n              \"ਜੂਨ\",\n              \"ਜੁਲਾ\",\n              \"ਅਗ\",\n              \"ਸਤੰ\",\n              \"ਅਕ\",\n              \"ਨਵੰ\",\n              \"ਦਸੰ\",\n          ],\n          longhand: [\n              \"ਜਨਵਰੀ\",\n              \"ਫ਼ਰਵਰੀ\",\n              \"ਮਾਰਚ\",\n              \"ਅਪ੍ਰੈਲ\",\n              \"ਮਈ\",\n              \"ਜੂਨ\",\n              \"ਜੁਲਾਈ\",\n              \"ਅਗਸਤ\",\n              \"ਸਤੰਬਰ\",\n              \"ਅਕਤੂਬਰ\",\n              \"ਨਵੰਬਰ\",\n              \"ਦਸੰਬਰ\",\n          ],\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.pa = Punjabi;\n  var pa = fp.l10ns;\n\n  exports.Punjabi = Punjabi;\n  exports.default = pa;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pl = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Polish = {\n      weekdays: {\n          shorthand: [\"Nd\", \"Pn\", \"Wt\", \"Śr\", \"Cz\", \"Pt\", \"So\"],\n          longhand: [\n              \"Niedziela\",\n              \"Poniedziałek\",\n              \"Wtorek\",\n              \"Środa\",\n              \"Czwartek\",\n              \"Piątek\",\n              \"Sobota\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Sty\",\n              \"Lut\",\n              \"Mar\",\n              \"Kwi\",\n              \"Maj\",\n              \"Cze\",\n              \"Lip\",\n              \"Sie\",\n              \"Wrz\",\n              \"Paź\",\n              \"Lis\",\n              \"Gru\",\n          ],\n          longhand: [\n              \"Styczeń\",\n              \"Luty\",\n              \"Marzec\",\n              \"Kwiecień\",\n              \"Maj\",\n              \"Czerwiec\",\n              \"Lipiec\",\n              \"Sierpień\",\n              \"Wrzesień\",\n              \"Październik\",\n              \"Listopad\",\n              \"Grudzień\",\n          ],\n      },\n      rangeSeparator: \" do \",\n      weekAbbreviation: \"tydz.\",\n      scrollTitle: \"Przewiń, aby zwiększyć\",\n      toggleTitle: \"Kliknij, aby przełączyć\",\n      firstDayOfWeek: 1,\n      time_24hr: true,\n      ordinal: function () {\n          return \".\";\n      },\n  };\n  fp.l10ns.pl = Polish;\n  var pl = fp.l10ns;\n\n  exports.Polish = Polish;\n  exports.default = pl;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pt = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Portuguese = {\n      weekdays: {\n          shorthand: [\"Dom\", \"Seg\", \"Ter\", \"Qua\", \"Qui\", \"Sex\", \"Sáb\"],\n          longhand: [\n              \"Domingo\",\n              \"Segunda-feira\",\n              \"Terça-feira\",\n              \"Quarta-feira\",\n              \"Quinta-feira\",\n              \"Sexta-feira\",\n              \"Sábado\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Fev\",\n              \"Mar\",\n              \"Abr\",\n              \"Mai\",\n              \"Jun\",\n              \"Jul\",\n              \"Ago\",\n              \"Set\",\n              \"Out\",\n              \"Nov\",\n              \"Dez\",\n          ],\n          longhand: [\n              \"Janeiro\",\n              \"Fevereiro\",\n              \"Março\",\n              \"Abril\",\n              \"Maio\",\n              \"Junho\",\n              \"Julho\",\n              \"Agosto\",\n              \"Setembro\",\n              \"Outubro\",\n              \"Novembro\",\n              \"Dezembro\",\n          ],\n      },\n      rangeSeparator: \" até \",\n      time_24hr: true,\n  };\n  fp.l10ns.pt = Portuguese;\n  var pt = fp.l10ns;\n\n  exports.Portuguese = Portuguese;\n  exports.default = pt;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ro = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Romanian = {\n      weekdays: {\n          shorthand: [\"Dum\", \"Lun\", \"Mar\", \"Mie\", \"Joi\", \"Vin\", \"Sâm\"],\n          longhand: [\n              \"Duminică\",\n              \"Luni\",\n              \"Marți\",\n              \"Miercuri\",\n              \"Joi\",\n              \"Vineri\",\n              \"Sâmbătă\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Ian\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Mai\",\n              \"Iun\",\n              \"Iul\",\n              \"Aug\",\n              \"Sep\",\n              \"Oct\",\n              \"Noi\",\n              \"Dec\",\n          ],\n          longhand: [\n              \"Ianuarie\",\n              \"Februarie\",\n              \"Martie\",\n              \"Aprilie\",\n              \"Mai\",\n              \"Iunie\",\n              \"Iulie\",\n              \"August\",\n              \"Septembrie\",\n              \"Octombrie\",\n              \"Noiembrie\",\n              \"Decembrie\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      time_24hr: true,\n      ordinal: function () {\n          return \"\";\n      },\n  };\n  fp.l10ns.ro = Romanian;\n  var ro = fp.l10ns;\n\n  exports.Romanian = Romanian;\n  exports.default = ro;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ru = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Russian = {\n      weekdays: {\n          shorthand: [\"Вс\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\"],\n          longhand: [\n              \"Воскресенье\",\n              \"Понедельник\",\n              \"Вторник\",\n              \"Среда\",\n              \"Четверг\",\n              \"Пятница\",\n              \"Суббота\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Янв\",\n              \"Фев\",\n              \"Март\",\n              \"Апр\",\n              \"Май\",\n              \"Июнь\",\n              \"Июль\",\n              \"Авг\",\n              \"Сен\",\n              \"Окт\",\n              \"Ноя\",\n              \"Дек\",\n          ],\n          longhand: [\n              \"Январь\",\n              \"Февраль\",\n              \"Март\",\n              \"Апрель\",\n              \"Май\",\n              \"Июнь\",\n              \"Июль\",\n              \"Август\",\n              \"Сентябрь\",\n              \"Октябрь\",\n              \"Ноябрь\",\n              \"Декабрь\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      rangeSeparator: \" — \",\n      weekAbbreviation: \"Нед.\",\n      scrollTitle: \"Прокрутите для увеличения\",\n      toggleTitle: \"Нажмите для переключения\",\n      amPM: [\"ДП\", \"ПП\"],\n      yearAriaLabel: \"Год\",\n      time_24hr: true,\n  };\n  fp.l10ns.ru = Russian;\n  var ru = fp.l10ns;\n\n  exports.Russian = Russian;\n  exports.default = ru;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.si = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Sinhala = {\n      weekdays: {\n          shorthand: [\"ඉ\", \"ස\", \"අ\", \"බ\", \"බ්‍ර\", \"සි\", \"සෙ\"],\n          longhand: [\n              \"ඉරිදා\",\n              \"සඳුදා\",\n              \"අඟහරුවාදා\",\n              \"බදාදා\",\n              \"බ්‍රහස්පතින්දා\",\n              \"සිකුරාදා\",\n              \"සෙනසුරාදා\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"ජන\",\n              \"පෙබ\",\n              \"මාර්\",\n              \"අප්‍රේ\",\n              \"මැයි\",\n              \"ජුනි\",\n              \"ජූලි\",\n              \"අගෝ\",\n              \"සැප්\",\n              \"ඔක්\",\n              \"නොවැ\",\n              \"දෙසැ\",\n          ],\n          longhand: [\n              \"ජනවාරි\",\n              \"පෙබරවාරි\",\n              \"මාර්තු\",\n              \"අප්‍රේල්\",\n              \"මැයි\",\n              \"ජුනි\",\n              \"ජූලි\",\n              \"අගෝස්තු\",\n              \"සැප්තැම්බර්\",\n              \"ඔක්තෝබර්\",\n              \"නොවැම්බර්\",\n              \"දෙසැම්බර්\",\n          ],\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.si = Sinhala;\n  var si = fp.l10ns;\n\n  exports.Sinhala = Sinhala;\n  exports.default = si;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.sk = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Slovak = {\n      weekdays: {\n          shorthand: [\"Ned\", \"Pon\", \"Ut\", \"Str\", \"Štv\", \"Pia\", \"Sob\"],\n          longhand: [\n              \"Nedeľa\",\n              \"Pondelok\",\n              \"Utorok\",\n              \"Streda\",\n              \"Štvrtok\",\n              \"Piatok\",\n              \"Sobota\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Máj\",\n              \"Jún\",\n              \"Júl\",\n              \"Aug\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dec\",\n          ],\n          longhand: [\n              \"Január\",\n              \"Február\",\n              \"Marec\",\n              \"Apríl\",\n              \"Máj\",\n              \"Jún\",\n              \"Júl\",\n              \"August\",\n              \"September\",\n              \"Október\",\n              \"November\",\n              \"December\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" do \",\n      time_24hr: true,\n      ordinal: function () {\n          return \".\";\n      },\n  };\n  fp.l10ns.sk = Slovak;\n  var sk = fp.l10ns;\n\n  exports.Slovak = Slovak;\n  exports.default = sk;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.sl = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Slovenian = {\n      weekdays: {\n          shorthand: [\"Ned\", \"Pon\", \"Tor\", \"Sre\", \"Čet\", \"Pet\", \"Sob\"],\n          longhand: [\n              \"Nedelja\",\n              \"Ponedeljek\",\n              \"Torek\",\n              \"Sreda\",\n              \"Četrtek\",\n              \"Petek\",\n              \"Sobota\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Maj\",\n              \"Jun\",\n              \"Jul\",\n              \"Avg\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dec\",\n          ],\n          longhand: [\n              \"Januar\",\n              \"Februar\",\n              \"Marec\",\n              \"April\",\n              \"Maj\",\n              \"Junij\",\n              \"Julij\",\n              \"Avgust\",\n              \"September\",\n              \"Oktober\",\n              \"November\",\n              \"December\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" do \",\n      time_24hr: true,\n      ordinal: function () {\n          return \".\";\n      },\n  };\n  fp.l10ns.sl = Slovenian;\n  var sl = fp.l10ns;\n\n  exports.Slovenian = Slovenian;\n  exports.default = sl;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.sq = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Albanian = {\n      weekdays: {\n          shorthand: [\"Di\", \"Hë\", \"Ma\", \"Më\", \"En\", \"Pr\", \"Sh\"],\n          longhand: [\n              \"E Diel\",\n              \"E Hënë\",\n              \"E Martë\",\n              \"E Mërkurë\",\n              \"E Enjte\",\n              \"E Premte\",\n              \"E Shtunë\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Shk\",\n              \"Mar\",\n              \"Pri\",\n              \"Maj\",\n              \"Qer\",\n              \"Kor\",\n              \"Gus\",\n              \"Sht\",\n              \"Tet\",\n              \"Nën\",\n              \"Dhj\",\n          ],\n          longhand: [\n              \"Janar\",\n              \"Shkurt\",\n              \"Mars\",\n              \"Prill\",\n              \"Maj\",\n              \"Qershor\",\n              \"Korrik\",\n              \"Gusht\",\n              \"Shtator\",\n              \"Tetor\",\n              \"Nëntor\",\n              \"Dhjetor\",\n          ],\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.sq = Albanian;\n  var sq = fp.l10ns;\n\n  exports.Albanian = Albanian;\n  exports.default = sq;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['sr-cyr'] = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var SerbianCyrillic = {\n      weekdays: {\n          shorthand: [\"Нед\", \"Пон\", \"Уто\", \"Сре\", \"Чет\", \"Пет\", \"Суб\"],\n          longhand: [\n              \"Недеља\",\n              \"Понедељак\",\n              \"Уторак\",\n              \"Среда\",\n              \"Четвртак\",\n              \"Петак\",\n              \"Субота\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Јан\",\n              \"Феб\",\n              \"Мар\",\n              \"Апр\",\n              \"Мај\",\n              \"Јун\",\n              \"Јул\",\n              \"Авг\",\n              \"Сеп\",\n              \"Окт\",\n              \"Нов\",\n              \"Дец\",\n          ],\n          longhand: [\n              \"Јануар\",\n              \"Фебруар\",\n              \"Март\",\n              \"Април\",\n              \"Мај\",\n              \"Јун\",\n              \"Јул\",\n              \"Август\",\n              \"Септембар\",\n              \"Октобар\",\n              \"Новембар\",\n              \"Децембар\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      weekAbbreviation: \"Нед.\",\n      rangeSeparator: \" до \",\n  };\n  fp.l10ns.sr = SerbianCyrillic;\n  var srCyr = fp.l10ns;\n\n  exports.SerbianCyrillic = SerbianCyrillic;\n  exports.default = srCyr;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.sr = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Serbian = {\n      weekdays: {\n          shorthand: [\"Ned\", \"Pon\", \"Uto\", \"Sre\", \"Čet\", \"Pet\", \"Sub\"],\n          longhand: [\n              \"Nedelja\",\n              \"Ponedeljak\",\n              \"Utorak\",\n              \"Sreda\",\n              \"Četvrtak\",\n              \"Petak\",\n              \"Subota\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Jan\",\n              \"Feb\",\n              \"Mar\",\n              \"Apr\",\n              \"Maj\",\n              \"Jun\",\n              \"Jul\",\n              \"Avg\",\n              \"Sep\",\n              \"Okt\",\n              \"Nov\",\n              \"Dec\",\n          ],\n          longhand: [\n              \"Januar\",\n              \"Februar\",\n              \"Mart\",\n              \"April\",\n              \"Maj\",\n              \"Jun\",\n              \"Jul\",\n              \"Avgust\",\n              \"Septembar\",\n              \"Oktobar\",\n              \"Novembar\",\n              \"Decembar\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      weekAbbreviation: \"Ned.\",\n      rangeSeparator: \" do \",\n      time_24hr: true,\n  };\n  fp.l10ns.sr = Serbian;\n  var sr = fp.l10ns;\n\n  exports.Serbian = Serbian;\n  exports.default = sr;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.sv = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Swedish = {\n      firstDayOfWeek: 1,\n      weekAbbreviation: \"v\",\n      weekdays: {\n          shorthand: [\"sön\", \"mån\", \"tis\", \"ons\", \"tor\", \"fre\", \"lör\"],\n          longhand: [\n              \"söndag\",\n              \"måndag\",\n              \"tisdag\",\n              \"onsdag\",\n              \"torsdag\",\n              \"fredag\",\n              \"lördag\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"jan\",\n              \"feb\",\n              \"mar\",\n              \"apr\",\n              \"maj\",\n              \"jun\",\n              \"jul\",\n              \"aug\",\n              \"sep\",\n              \"okt\",\n              \"nov\",\n              \"dec\",\n          ],\n          longhand: [\n              \"januari\",\n              \"februari\",\n              \"mars\",\n              \"april\",\n              \"maj\",\n              \"juni\",\n              \"juli\",\n              \"augusti\",\n              \"september\",\n              \"oktober\",\n              \"november\",\n              \"december\",\n          ],\n      },\n      rangeSeparator: ' till ',\n      time_24hr: true,\n      ordinal: function () {\n          return \".\";\n      },\n  };\n  fp.l10ns.sv = Swedish;\n  var sv = fp.l10ns;\n\n  exports.Swedish = Swedish;\n  exports.default = sv;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.th = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Thai = {\n      weekdays: {\n          shorthand: [\"อา\", \"จ\", \"อ\", \"พ\", \"พฤ\", \"ศ\", \"ส\"],\n          longhand: [\n              \"อาทิตย์\",\n              \"จันทร์\",\n              \"อังคาร\",\n              \"พุธ\",\n              \"พฤหัสบดี\",\n              \"ศุกร์\",\n              \"เสาร์\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"ม.ค.\",\n              \"ก.พ.\",\n              \"มี.ค.\",\n              \"เม.ย.\",\n              \"พ.ค.\",\n              \"มิ.ย.\",\n              \"ก.ค.\",\n              \"ส.ค.\",\n              \"ก.ย.\",\n              \"ต.ค.\",\n              \"พ.ย.\",\n              \"ธ.ค.\",\n          ],\n          longhand: [\n              \"มกราคม\",\n              \"กุมภาพันธ์\",\n              \"มีนาคม\",\n              \"เมษายน\",\n              \"พฤษภาคม\",\n              \"มิถุนายน\",\n              \"กรกฎาคม\",\n              \"สิงหาคม\",\n              \"กันยายน\",\n              \"ตุลาคม\",\n              \"พฤศจิกายน\",\n              \"ธันวาคม\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" ถึง \",\n      scrollTitle: \"เลื่อนเพื่อเพิ่มหรือลด\",\n      toggleTitle: \"คลิกเพื่อเปลี่ยน\",\n      time_24hr: true,\n      ordinal: function () {\n          return \"\";\n      },\n  };\n  fp.l10ns.th = Thai;\n  var th = fp.l10ns;\n\n  exports.Thai = Thai;\n  exports.default = th;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.tr = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Turkish = {\n      weekdays: {\n          shorthand: [\"Paz\", \"Pzt\", \"Sal\", \"Çar\", \"Per\", \"Cum\", \"Cmt\"],\n          longhand: [\n              \"Pazar\",\n              \"Pazartesi\",\n              \"Salı\",\n              \"Çarşamba\",\n              \"Perşembe\",\n              \"Cuma\",\n              \"Cumartesi\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Oca\",\n              \"Şub\",\n              \"Mar\",\n              \"Nis\",\n              \"May\",\n              \"Haz\",\n              \"Tem\",\n              \"Ağu\",\n              \"Eyl\",\n              \"Eki\",\n              \"Kas\",\n              \"Ara\",\n          ],\n          longhand: [\n              \"Ocak\",\n              \"Şubat\",\n              \"Mart\",\n              \"Nisan\",\n              \"Mayıs\",\n              \"Haziran\",\n              \"Temmuz\",\n              \"Ağustos\",\n              \"Eylül\",\n              \"Ekim\",\n              \"Kasım\",\n              \"Aralık\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \".\";\n      },\n      rangeSeparator: \" - \",\n      weekAbbreviation: \"Hf\",\n      scrollTitle: \"Artırmak için kaydırın\",\n      toggleTitle: \"Aç/Kapa\",\n      amPM: [\"ÖÖ\", \"ÖS\"],\n      time_24hr: true,\n  };\n  fp.l10ns.tr = Turkish;\n  var tr = fp.l10ns;\n\n  exports.Turkish = Turkish;\n  exports.default = tr;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.uk = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Ukrainian = {\n      firstDayOfWeek: 1,\n      weekdays: {\n          shorthand: [\"Нд\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\"],\n          longhand: [\n              \"Неділя\",\n              \"Понеділок\",\n              \"Вівторок\",\n              \"Середа\",\n              \"Четвер\",\n              \"П'ятниця\",\n              \"Субота\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Січ\",\n              \"Лют\",\n              \"Бер\",\n              \"Кві\",\n              \"Тра\",\n              \"Чер\",\n              \"Лип\",\n              \"Сер\",\n              \"Вер\",\n              \"Жов\",\n              \"Лис\",\n              \"Гру\",\n          ],\n          longhand: [\n              \"Січень\",\n              \"Лютий\",\n              \"Березень\",\n              \"Квітень\",\n              \"Травень\",\n              \"Червень\",\n              \"Липень\",\n              \"Серпень\",\n              \"Вересень\",\n              \"Жовтень\",\n              \"Листопад\",\n              \"Грудень\",\n          ],\n      },\n      time_24hr: true,\n  };\n  fp.l10ns.uk = Ukrainian;\n  var uk = fp.l10ns;\n\n  exports.Ukrainian = Ukrainian;\n  exports.default = uk;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.uz = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Uzbek = {\n      weekdays: {\n          shorthand: [\"Якш\", \"Душ\", \"Сеш\", \"Чор\", \"Пай\", \"Жум\", \"Шан\"],\n          longhand: [\n              \"Якшанба\",\n              \"Душанба\",\n              \"Сешанба\",\n              \"Чоршанба\",\n              \"Пайшанба\",\n              \"Жума\",\n              \"Шанба\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Янв\",\n              \"Фев\",\n              \"Мар\",\n              \"Апр\",\n              \"Май\",\n              \"Июн\",\n              \"Июл\",\n              \"Авг\",\n              \"Сен\",\n              \"Окт\",\n              \"Ноя\",\n              \"Дек\",\n          ],\n          longhand: [\n              \"Январ\",\n              \"Феврал\",\n              \"Март\",\n              \"Апрел\",\n              \"Май\",\n              \"Июн\",\n              \"Июл\",\n              \"Август\",\n              \"Сентябр\",\n              \"Октябр\",\n              \"Ноябр\",\n              \"Декабр\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      rangeSeparator: \" — \",\n      weekAbbreviation: \"Ҳафта\",\n      scrollTitle: \"Катталаштириш учун айлантиринг\",\n      toggleTitle: \"Ўтиш учун босинг\",\n      amPM: [\"AM\", \"PM\"],\n      yearAriaLabel: \"Йил\",\n      time_24hr: true,\n  };\n  fp.l10ns.uz = Uzbek;\n  var uz = fp.l10ns;\n\n  exports.Uzbek = Uzbek;\n  exports.default = uz;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.uz_latn = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var UzbekLatin = {\n      weekdays: {\n          shorthand: [\"Ya\", \"Du\", \"Se\", \"Cho\", \"Pa\", \"Ju\", \"Sha\"],\n          longhand: [\n              \"Yakshanba\",\n              \"Dushanba\",\n              \"Seshanba\",\n              \"Chorshanba\",\n              \"Payshanba\",\n              \"Juma\",\n              \"Shanba\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Yan\",\n              \"Fev\",\n              \"Mar\",\n              \"Apr\",\n              \"May\",\n              \"Iyun\",\n              \"Iyul\",\n              \"Avg\",\n              \"Sen\",\n              \"Okt\",\n              \"Noy\",\n              \"Dek\",\n          ],\n          longhand: [\n              \"Yanvar\",\n              \"Fevral\",\n              \"Mart\",\n              \"Aprel\",\n              \"May\",\n              \"Iyun\",\n              \"Iyul\",\n              \"Avgust\",\n              \"Sentabr\",\n              \"Oktabr\",\n              \"Noyabr\",\n              \"Dekabr\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      ordinal: function () {\n          return \"\";\n      },\n      rangeSeparator: \" — \",\n      weekAbbreviation: \"Hafta\",\n      scrollTitle: \"Kattalashtirish uchun aylantiring\",\n      toggleTitle: \"O‘tish uchun bosing\",\n      amPM: [\"AM\", \"PM\"],\n      yearAriaLabel: \"Yil\",\n      time_24hr: true,\n  };\n  fp.l10ns[\"uz_latn\"] = UzbekLatin;\n  var uz_latn = fp.l10ns;\n\n  exports.UzbekLatin = UzbekLatin;\n  exports.default = uz_latn;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vn = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Vietnamese = {\n      weekdays: {\n          shorthand: [\"CN\", \"T2\", \"T3\", \"T4\", \"T5\", \"T6\", \"T7\"],\n          longhand: [\n              \"Chủ nhật\",\n              \"Thứ hai\",\n              \"Thứ ba\",\n              \"Thứ tư\",\n              \"Thứ năm\",\n              \"Thứ sáu\",\n              \"Thứ bảy\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"Th1\",\n              \"Th2\",\n              \"Th3\",\n              \"Th4\",\n              \"Th5\",\n              \"Th6\",\n              \"Th7\",\n              \"Th8\",\n              \"Th9\",\n              \"Th10\",\n              \"Th11\",\n              \"Th12\",\n          ],\n          longhand: [\n              \"Tháng một\",\n              \"Tháng hai\",\n              \"Tháng ba\",\n              \"Tháng tư\",\n              \"Tháng năm\",\n              \"Tháng sáu\",\n              \"Tháng bảy\",\n              \"Tháng tám\",\n              \"Tháng chín\",\n              \"Tháng mười\",\n              \"Tháng mười một\",\n              \"Tháng mười hai\",\n          ],\n      },\n      firstDayOfWeek: 1,\n      rangeSeparator: \" đến \",\n  };\n  fp.l10ns.vn = Vietnamese;\n  var vn = fp.l10ns;\n\n  exports.Vietnamese = Vietnamese;\n  exports.default = vn;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['zh-tw'] = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var MandarinTraditional = {\n      weekdays: {\n          shorthand: [\"週日\", \"週一\", \"週二\", \"週三\", \"週四\", \"週五\", \"週六\"],\n          longhand: [\n              \"星期日\",\n              \"星期一\",\n              \"星期二\",\n              \"星期三\",\n              \"星期四\",\n              \"星期五\",\n              \"星期六\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"一月\",\n              \"二月\",\n              \"三月\",\n              \"四月\",\n              \"五月\",\n              \"六月\",\n              \"七月\",\n              \"八月\",\n              \"九月\",\n              \"十月\",\n              \"十一月\",\n              \"十二月\",\n          ],\n          longhand: [\n              \"一月\",\n              \"二月\",\n              \"三月\",\n              \"四月\",\n              \"五月\",\n              \"六月\",\n              \"七月\",\n              \"八月\",\n              \"九月\",\n              \"十月\",\n              \"十一月\",\n              \"十二月\",\n          ],\n      },\n      rangeSeparator: \" 至 \",\n      weekAbbreviation: \"週\",\n      scrollTitle: \"滾動切換\",\n      toggleTitle: \"點擊切換 12/24 小時時制\",\n  };\n  fp.l10ns.zh_tw = MandarinTraditional;\n  var zhTw = fp.l10ns;\n\n  exports.MandarinTraditional = MandarinTraditional;\n  exports.default = zhTw;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.zh = {}));\n}(this, (function (exports) { 'use strict';\n\n  var fp = typeof window !== \"undefined\" && window.flatpickr !== undefined\n      ? window.flatpickr\n      : {\n          l10ns: {},\n      };\n  var Mandarin = {\n      weekdays: {\n          shorthand: [\"周日\", \"周一\", \"周二\", \"周三\", \"周四\", \"周五\", \"周六\"],\n          longhand: [\n              \"星期日\",\n              \"星期一\",\n              \"星期二\",\n              \"星期三\",\n              \"星期四\",\n              \"星期五\",\n              \"星期六\",\n          ],\n      },\n      months: {\n          shorthand: [\n              \"一月\",\n              \"二月\",\n              \"三月\",\n              \"四月\",\n              \"五月\",\n              \"六月\",\n              \"七月\",\n              \"八月\",\n              \"九月\",\n              \"十月\",\n              \"十一月\",\n              \"十二月\",\n          ],\n          longhand: [\n              \"一月\",\n              \"二月\",\n              \"三月\",\n              \"四月\",\n              \"五月\",\n              \"六月\",\n              \"七月\",\n              \"八月\",\n              \"九月\",\n              \"十月\",\n              \"十一月\",\n              \"十二月\",\n          ],\n      },\n      rangeSeparator: \" 至 \",\n      weekAbbreviation: \"周\",\n      scrollTitle: \"滚动切换\",\n      toggleTitle: \"点击切换 12/24 小时时制\",\n  };\n  fp.l10ns.zh = Mandarin;\n  var zh = fp.l10ns;\n\n  exports.Mandarin = Mandarin;\n  exports.default = zh;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/data.js",
    "content": "//= require rails_admin/jquery-ui/version\n\n/*!\n * jQuery UI :data 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: :data Selector\n//>>group: Core\n//>>description: Selects elements which have data stored under the specified key.\n//>>docs: http://api.jqueryui.com/data-selector/\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\", \"./version\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n} ( function( $ ) {\nreturn $.extend( $.expr[ \":\" ], {\n\tdata: $.expr.createPseudo ?\n\t\t$.expr.createPseudo( function( dataName ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn !!$.data( elem, dataName );\n\t\t\t};\n\t\t} ) :\n\n\t\t// Support: jQuery <1.8\n\t\tfunction( elem, i, match ) {\n\t\t\treturn !!$.data( elem, match[ 3 ] );\n\t\t}\n} );\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/effect.js",
    "content": "//= require rails_admin/jquery-ui/version\n\n/*!\n * jQuery UI Effects 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Effects Core\n//>>group: Effects\n// jscs:disable maximumLineLength\n//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.\n// jscs:enable maximumLineLength\n//>>docs: http://api.jqueryui.com/category/effects-core/\n//>>demos: http://jqueryui.com/effect/\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\", \"./version\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}( function( $ ) {\n\nvar dataSpace = \"ui-effects-\",\n\tdataSpaceStyle = \"ui-effects-style\",\n\tdataSpaceAnimated = \"ui-effects-animated\",\n\n\t// Create a local jQuery because jQuery Color relies on it and the\n\t// global may not exist with AMD and a custom build (#10199)\n\tjQuery = $;\n\n$.effects = {\n\teffect: {}\n};\n\n/*!\n * jQuery Color Animations v2.1.2\n * https://github.com/jquery/jquery-color\n *\n * Copyright 2014 jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * Date: Wed Jan 16 08:47:09 2013 -0600\n */\n( function( jQuery, undefined ) {\n\n\tvar stepHooks = \"backgroundColor borderBottomColor borderLeftColor borderRightColor \" +\n\t\t\"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor\",\n\n\t// Plusequals test for += 100 -= 100\n\trplusequals = /^([\\-+])=\\s*(\\d+\\.?\\d*)/,\n\n\t// A set of RE's that can match strings and generate color tuples.\n\tstringParsers = [ {\n\t\t\tre: /rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ],\n\t\t\t\t\texecResult[ 3 ],\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /rgba?\\(\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ] * 2.55,\n\t\t\t\t\texecResult[ 2 ] * 2.55,\n\t\t\t\t\texecResult[ 3 ] * 2.55,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\n\t\t\t// This regex ignores A-F because it's compared against an already lowercased string\n\t\t\tre: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\n\t\t\t// This regex ignores A-F because it's compared against an already lowercased string\n\t\t\tre: /#([a-f0-9])([a-f0-9])([a-f0-9])/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ] + execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /hsla?\\(\\s*(\\d+(?:\\.\\d+)?)\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tspace: \"hsla\",\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ] / 100,\n\t\t\t\t\texecResult[ 3 ] / 100,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t} ],\n\n\t// JQuery.Color( )\n\tcolor = jQuery.Color = function( color, green, blue, alpha ) {\n\t\treturn new jQuery.Color.fn.parse( color, green, blue, alpha );\n\t},\n\tspaces = {\n\t\trgba: {\n\t\t\tprops: {\n\t\t\t\tred: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tgreen: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tblue: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\thsla: {\n\t\t\tprops: {\n\t\t\t\thue: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"degrees\"\n\t\t\t\t},\n\t\t\t\tsaturation: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t},\n\t\t\t\tlightness: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tpropTypes = {\n\t\t\"byte\": {\n\t\t\tfloor: true,\n\t\t\tmax: 255\n\t\t},\n\t\t\"percent\": {\n\t\t\tmax: 1\n\t\t},\n\t\t\"degrees\": {\n\t\t\tmod: 360,\n\t\t\tfloor: true\n\t\t}\n\t},\n\tsupport = color.support = {},\n\n\t// Element for support tests\n\tsupportElem = jQuery( \"<p>\" )[ 0 ],\n\n\t// Colors = jQuery.Color.names\n\tcolors,\n\n\t// Local aliases of functions called often\n\teach = jQuery.each;\n\n// Determine rgba support immediately\nsupportElem.style.cssText = \"background-color:rgba(1,1,1,.5)\";\nsupport.rgba = supportElem.style.backgroundColor.indexOf( \"rgba\" ) > -1;\n\n// Define cache name and alpha properties\n// for rgba and hsla spaces\neach( spaces, function( spaceName, space ) {\n\tspace.cache = \"_\" + spaceName;\n\tspace.props.alpha = {\n\t\tidx: 3,\n\t\ttype: \"percent\",\n\t\tdef: 1\n\t};\n} );\n\nfunction clamp( value, prop, allowEmpty ) {\n\tvar type = propTypes[ prop.type ] || {};\n\n\tif ( value == null ) {\n\t\treturn ( allowEmpty || !prop.def ) ? null : prop.def;\n\t}\n\n\t// ~~ is an short way of doing floor for positive numbers\n\tvalue = type.floor ? ~~value : parseFloat( value );\n\n\t// IE will pass in empty strings as value for alpha,\n\t// which will hit this case\n\tif ( isNaN( value ) ) {\n\t\treturn prop.def;\n\t}\n\n\tif ( type.mod ) {\n\n\t\t// We add mod before modding to make sure that negatives values\n\t\t// get converted properly: -10 -> 350\n\t\treturn ( value + type.mod ) % type.mod;\n\t}\n\n\t// For now all property types without mod have min and max\n\treturn 0 > value ? 0 : type.max < value ? type.max : value;\n}\n\nfunction stringParse( string ) {\n\tvar inst = color(),\n\t\trgba = inst._rgba = [];\n\n\tstring = string.toLowerCase();\n\n\teach( stringParsers, function( i, parser ) {\n\t\tvar parsed,\n\t\t\tmatch = parser.re.exec( string ),\n\t\t\tvalues = match && parser.parse( match ),\n\t\t\tspaceName = parser.space || \"rgba\";\n\n\t\tif ( values ) {\n\t\t\tparsed = inst[ spaceName ]( values );\n\n\t\t\t// If this was an rgba parse the assignment might happen twice\n\t\t\t// oh well....\n\t\t\tinst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];\n\t\t\trgba = inst._rgba = parsed._rgba;\n\n\t\t\t// Exit each( stringParsers ) here because we matched\n\t\t\treturn false;\n\t\t}\n\t} );\n\n\t// Found a stringParser that handled it\n\tif ( rgba.length ) {\n\n\t\t// If this came from a parsed string, force \"transparent\" when alpha is 0\n\t\t// chrome, (and maybe others) return \"transparent\" as rgba(0,0,0,0)\n\t\tif ( rgba.join() === \"0,0,0,0\" ) {\n\t\t\tjQuery.extend( rgba, colors.transparent );\n\t\t}\n\t\treturn inst;\n\t}\n\n\t// Named colors\n\treturn colors[ string ];\n}\n\ncolor.fn = jQuery.extend( color.prototype, {\n\tparse: function( red, green, blue, alpha ) {\n\t\tif ( red === undefined ) {\n\t\t\tthis._rgba = [ null, null, null, null ];\n\t\t\treturn this;\n\t\t}\n\t\tif ( red.jquery || red.nodeType ) {\n\t\t\tred = jQuery( red ).css( green );\n\t\t\tgreen = undefined;\n\t\t}\n\n\t\tvar inst = this,\n\t\t\ttype = jQuery.type( red ),\n\t\t\trgba = this._rgba = [];\n\n\t\t// More than 1 argument specified - assume ( red, green, blue, alpha )\n\t\tif ( green !== undefined ) {\n\t\t\tred = [ red, green, blue, alpha ];\n\t\t\ttype = \"array\";\n\t\t}\n\n\t\tif ( type === \"string\" ) {\n\t\t\treturn this.parse( stringParse( red ) || colors._default );\n\t\t}\n\n\t\tif ( type === \"array\" ) {\n\t\t\teach( spaces.rgba.props, function( key, prop ) {\n\t\t\t\trgba[ prop.idx ] = clamp( red[ prop.idx ], prop );\n\t\t\t} );\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( type === \"object\" ) {\n\t\t\tif ( red instanceof color ) {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tif ( red[ space.cache ] ) {\n\t\t\t\t\t\tinst[ space.cache ] = red[ space.cache ].slice();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tvar cache = space.cache;\n\t\t\t\t\teach( space.props, function( key, prop ) {\n\n\t\t\t\t\t\t// If the cache doesn't exist, and we know how to convert\n\t\t\t\t\t\tif ( !inst[ cache ] && space.to ) {\n\n\t\t\t\t\t\t\t// If the value was null, we don't need to copy it\n\t\t\t\t\t\t\t// if the key was alpha, we don't need to copy it either\n\t\t\t\t\t\t\tif ( key === \"alpha\" || red[ key ] == null ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinst[ cache ] = space.to( inst._rgba );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// This is the only case where we allow nulls for ALL properties.\n\t\t\t\t\t\t// call clamp with alwaysAllowEmpty\n\t\t\t\t\t\tinst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Everything defined but alpha?\n\t\t\t\t\tif ( inst[ cache ] &&\n\t\t\t\t\t\t\tjQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {\n\n\t\t\t\t\t\t// Use the default of 1\n\t\t\t\t\t\tinst[ cache ][ 3 ] = 1;\n\t\t\t\t\t\tif ( space.from ) {\n\t\t\t\t\t\t\tinst._rgba = space.from( inst[ cache ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t},\n\tis: function( compare ) {\n\t\tvar is = color( compare ),\n\t\t\tsame = true,\n\t\t\tinst = this;\n\n\t\teach( spaces, function( _, space ) {\n\t\t\tvar localCache,\n\t\t\t\tisCache = is[ space.cache ];\n\t\t\tif ( isCache ) {\n\t\t\t\tlocalCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];\n\t\t\t\teach( space.props, function( _, prop ) {\n\t\t\t\t\tif ( isCache[ prop.idx ] != null ) {\n\t\t\t\t\t\tsame = ( isCache[ prop.idx ] === localCache[ prop.idx ] );\n\t\t\t\t\t\treturn same;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\treturn same;\n\t\t} );\n\t\treturn same;\n\t},\n\t_space: function() {\n\t\tvar used = [],\n\t\t\tinst = this;\n\t\teach( spaces, function( spaceName, space ) {\n\t\t\tif ( inst[ space.cache ] ) {\n\t\t\t\tused.push( spaceName );\n\t\t\t}\n\t\t} );\n\t\treturn used.pop();\n\t},\n\ttransition: function( other, distance ) {\n\t\tvar end = color( other ),\n\t\t\tspaceName = end._space(),\n\t\t\tspace = spaces[ spaceName ],\n\t\t\tstartColor = this.alpha() === 0 ? color( \"transparent\" ) : this,\n\t\t\tstart = startColor[ space.cache ] || space.to( startColor._rgba ),\n\t\t\tresult = start.slice();\n\n\t\tend = end[ space.cache ];\n\t\teach( space.props, function( key, prop ) {\n\t\t\tvar index = prop.idx,\n\t\t\t\tstartValue = start[ index ],\n\t\t\t\tendValue = end[ index ],\n\t\t\t\ttype = propTypes[ prop.type ] || {};\n\n\t\t\t// If null, don't override start value\n\t\t\tif ( endValue === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If null - use end\n\t\t\tif ( startValue === null ) {\n\t\t\t\tresult[ index ] = endValue;\n\t\t\t} else {\n\t\t\t\tif ( type.mod ) {\n\t\t\t\t\tif ( endValue - startValue > type.mod / 2 ) {\n\t\t\t\t\t\tstartValue += type.mod;\n\t\t\t\t\t} else if ( startValue - endValue > type.mod / 2 ) {\n\t\t\t\t\t\tstartValue -= type.mod;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresult[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );\n\t\t\t}\n\t\t} );\n\t\treturn this[ spaceName ]( result );\n\t},\n\tblend: function( opaque ) {\n\n\t\t// If we are already opaque - return ourself\n\t\tif ( this._rgba[ 3 ] === 1 ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tvar rgb = this._rgba.slice(),\n\t\t\ta = rgb.pop(),\n\t\t\tblend = color( opaque )._rgba;\n\n\t\treturn color( jQuery.map( rgb, function( v, i ) {\n\t\t\treturn ( 1 - a ) * blend[ i ] + a * v;\n\t\t} ) );\n\t},\n\ttoRgbaString: function() {\n\t\tvar prefix = \"rgba(\",\n\t\t\trgba = jQuery.map( this._rgba, function( v, i ) {\n\t\t\t\treturn v == null ? ( i > 2 ? 1 : 0 ) : v;\n\t\t\t} );\n\n\t\tif ( rgba[ 3 ] === 1 ) {\n\t\t\trgba.pop();\n\t\t\tprefix = \"rgb(\";\n\t\t}\n\n\t\treturn prefix + rgba.join() + \")\";\n\t},\n\ttoHslaString: function() {\n\t\tvar prefix = \"hsla(\",\n\t\t\thsla = jQuery.map( this.hsla(), function( v, i ) {\n\t\t\t\tif ( v == null ) {\n\t\t\t\t\tv = i > 2 ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\t// Catch 1 and 2\n\t\t\t\tif ( i && i < 3 ) {\n\t\t\t\t\tv = Math.round( v * 100 ) + \"%\";\n\t\t\t\t}\n\t\t\t\treturn v;\n\t\t\t} );\n\n\t\tif ( hsla[ 3 ] === 1 ) {\n\t\t\thsla.pop();\n\t\t\tprefix = \"hsl(\";\n\t\t}\n\t\treturn prefix + hsla.join() + \")\";\n\t},\n\ttoHexString: function( includeAlpha ) {\n\t\tvar rgba = this._rgba.slice(),\n\t\t\talpha = rgba.pop();\n\n\t\tif ( includeAlpha ) {\n\t\t\trgba.push( ~~( alpha * 255 ) );\n\t\t}\n\n\t\treturn \"#\" + jQuery.map( rgba, function( v ) {\n\n\t\t\t// Default to 0 when nulls exist\n\t\t\tv = ( v || 0 ).toString( 16 );\n\t\t\treturn v.length === 1 ? \"0\" + v : v;\n\t\t} ).join( \"\" );\n\t},\n\ttoString: function() {\n\t\treturn this._rgba[ 3 ] === 0 ? \"transparent\" : this.toRgbaString();\n\t}\n} );\ncolor.fn.parse.prototype = color.fn;\n\n// Hsla conversions adapted from:\n// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021\n\nfunction hue2rgb( p, q, h ) {\n\th = ( h + 1 ) % 1;\n\tif ( h * 6 < 1 ) {\n\t\treturn p + ( q - p ) * h * 6;\n\t}\n\tif ( h * 2 < 1 ) {\n\t\treturn q;\n\t}\n\tif ( h * 3 < 2 ) {\n\t\treturn p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;\n\t}\n\treturn p;\n}\n\nspaces.hsla.to = function( rgba ) {\n\tif ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {\n\t\treturn [ null, null, null, rgba[ 3 ] ];\n\t}\n\tvar r = rgba[ 0 ] / 255,\n\t\tg = rgba[ 1 ] / 255,\n\t\tb = rgba[ 2 ] / 255,\n\t\ta = rgba[ 3 ],\n\t\tmax = Math.max( r, g, b ),\n\t\tmin = Math.min( r, g, b ),\n\t\tdiff = max - min,\n\t\tadd = max + min,\n\t\tl = add * 0.5,\n\t\th, s;\n\n\tif ( min === max ) {\n\t\th = 0;\n\t} else if ( r === max ) {\n\t\th = ( 60 * ( g - b ) / diff ) + 360;\n\t} else if ( g === max ) {\n\t\th = ( 60 * ( b - r ) / diff ) + 120;\n\t} else {\n\t\th = ( 60 * ( r - g ) / diff ) + 240;\n\t}\n\n\t// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%\n\t// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)\n\tif ( diff === 0 ) {\n\t\ts = 0;\n\t} else if ( l <= 0.5 ) {\n\t\ts = diff / add;\n\t} else {\n\t\ts = diff / ( 2 - add );\n\t}\n\treturn [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];\n};\n\nspaces.hsla.from = function( hsla ) {\n\tif ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {\n\t\treturn [ null, null, null, hsla[ 3 ] ];\n\t}\n\tvar h = hsla[ 0 ] / 360,\n\t\ts = hsla[ 1 ],\n\t\tl = hsla[ 2 ],\n\t\ta = hsla[ 3 ],\n\t\tq = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,\n\t\tp = 2 * l - q;\n\n\treturn [\n\t\tMath.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),\n\t\ta\n\t];\n};\n\neach( spaces, function( spaceName, space ) {\n\tvar props = space.props,\n\t\tcache = space.cache,\n\t\tto = space.to,\n\t\tfrom = space.from;\n\n\t// Makes rgba() and hsla()\n\tcolor.fn[ spaceName ] = function( value ) {\n\n\t\t// Generate a cache for this space if it doesn't exist\n\t\tif ( to && !this[ cache ] ) {\n\t\t\tthis[ cache ] = to( this._rgba );\n\t\t}\n\t\tif ( value === undefined ) {\n\t\t\treturn this[ cache ].slice();\n\t\t}\n\n\t\tvar ret,\n\t\t\ttype = jQuery.type( value ),\n\t\t\tarr = ( type === \"array\" || type === \"object\" ) ? value : arguments,\n\t\t\tlocal = this[ cache ].slice();\n\n\t\teach( props, function( key, prop ) {\n\t\t\tvar val = arr[ type === \"object\" ? key : prop.idx ];\n\t\t\tif ( val == null ) {\n\t\t\t\tval = local[ prop.idx ];\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = clamp( val, prop );\n\t\t} );\n\n\t\tif ( from ) {\n\t\t\tret = color( from( local ) );\n\t\t\tret[ cache ] = local;\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn color( local );\n\t\t}\n\t};\n\n\t// Makes red() green() blue() alpha() hue() saturation() lightness()\n\teach( props, function( key, prop ) {\n\n\t\t// Alpha is included in more than one space\n\t\tif ( color.fn[ key ] ) {\n\t\t\treturn;\n\t\t}\n\t\tcolor.fn[ key ] = function( value ) {\n\t\t\tvar vtype = jQuery.type( value ),\n\t\t\t\tfn = ( key === \"alpha\" ? ( this._hsla ? \"hsla\" : \"rgba\" ) : spaceName ),\n\t\t\t\tlocal = this[ fn ](),\n\t\t\t\tcur = local[ prop.idx ],\n\t\t\t\tmatch;\n\n\t\t\tif ( vtype === \"undefined\" ) {\n\t\t\t\treturn cur;\n\t\t\t}\n\n\t\t\tif ( vtype === \"function\" ) {\n\t\t\t\tvalue = value.call( this, cur );\n\t\t\t\tvtype = jQuery.type( value );\n\t\t\t}\n\t\t\tif ( value == null && prop.empty ) {\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tif ( vtype === \"string\" ) {\n\t\t\t\tmatch = rplusequals.exec( value );\n\t\t\t\tif ( match ) {\n\t\t\t\t\tvalue = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === \"+\" ? 1 : -1 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = value;\n\t\t\treturn this[ fn ]( local );\n\t\t};\n\t} );\n} );\n\n// Add cssHook and .fx.step function for each named hook.\n// accept a space separated string of properties\ncolor.hook = function( hook ) {\n\tvar hooks = hook.split( \" \" );\n\teach( hooks, function( i, hook ) {\n\t\tjQuery.cssHooks[ hook ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar parsed, curElem,\n\t\t\t\t\tbackgroundColor = \"\";\n\n\t\t\t\tif ( value !== \"transparent\" && ( jQuery.type( value ) !== \"string\" ||\n\t\t\t\t\t\t( parsed = stringParse( value ) ) ) ) {\n\t\t\t\t\tvalue = color( parsed || value );\n\t\t\t\t\tif ( !support.rgba && value._rgba[ 3 ] !== 1 ) {\n\t\t\t\t\t\tcurElem = hook === \"backgroundColor\" ? elem.parentNode : elem;\n\t\t\t\t\t\twhile (\n\t\t\t\t\t\t\t( backgroundColor === \"\" || backgroundColor === \"transparent\" ) &&\n\t\t\t\t\t\t\tcurElem && curElem.style\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tbackgroundColor = jQuery.css( curElem, \"backgroundColor\" );\n\t\t\t\t\t\t\t\tcurElem = curElem.parentNode;\n\t\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvalue = value.blend( backgroundColor && backgroundColor !== \"transparent\" ?\n\t\t\t\t\t\t\tbackgroundColor :\n\t\t\t\t\t\t\t\"_default\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tvalue = value.toRgbaString();\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\telem.style[ hook ] = value;\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// Wrapped to prevent IE from throwing errors on \"invalid\" values like\n\t\t\t\t\t// 'auto' or 'inherit'\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tjQuery.fx.step[ hook ] = function( fx ) {\n\t\t\tif ( !fx.colorInit ) {\n\t\t\t\tfx.start = color( fx.elem, hook );\n\t\t\t\tfx.end = color( fx.end );\n\t\t\t\tfx.colorInit = true;\n\t\t\t}\n\t\t\tjQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );\n\t\t};\n\t} );\n\n};\n\ncolor.hook( stepHooks );\n\njQuery.cssHooks.borderColor = {\n\texpand: function( value ) {\n\t\tvar expanded = {};\n\n\t\teach( [ \"Top\", \"Right\", \"Bottom\", \"Left\" ], function( i, part ) {\n\t\t\texpanded[ \"border\" + part + \"Color\" ] = value;\n\t\t} );\n\t\treturn expanded;\n\t}\n};\n\n// Basic color names only.\n// Usage of any of the other color names requires adding yourself or including\n// jquery.color.svg-names.js.\ncolors = jQuery.Color.names = {\n\n\t// 4.1. Basic color keywords\n\taqua: \"#00ffff\",\n\tblack: \"#000000\",\n\tblue: \"#0000ff\",\n\tfuchsia: \"#ff00ff\",\n\tgray: \"#808080\",\n\tgreen: \"#008000\",\n\tlime: \"#00ff00\",\n\tmaroon: \"#800000\",\n\tnavy: \"#000080\",\n\tolive: \"#808000\",\n\tpurple: \"#800080\",\n\tred: \"#ff0000\",\n\tsilver: \"#c0c0c0\",\n\tteal: \"#008080\",\n\twhite: \"#ffffff\",\n\tyellow: \"#ffff00\",\n\n\t// 4.2.3. \"transparent\" color keyword\n\ttransparent: [ null, null, null, 0 ],\n\n\t_default: \"#ffffff\"\n};\n\n} )( jQuery );\n\n/******************************************************************************/\n/****************************** CLASS ANIMATIONS ******************************/\n/******************************************************************************/\n( function() {\n\nvar classAnimationActions = [ \"add\", \"remove\", \"toggle\" ],\n\tshorthandStyles = {\n\t\tborder: 1,\n\t\tborderBottom: 1,\n\t\tborderColor: 1,\n\t\tborderLeft: 1,\n\t\tborderRight: 1,\n\t\tborderTop: 1,\n\t\tborderWidth: 1,\n\t\tmargin: 1,\n\t\tpadding: 1\n\t};\n\n$.each(\n\t[ \"borderLeftStyle\", \"borderRightStyle\", \"borderBottomStyle\", \"borderTopStyle\" ],\n\tfunction( _, prop ) {\n\t\t$.fx.step[ prop ] = function( fx ) {\n\t\t\tif ( fx.end !== \"none\" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {\n\t\t\t\tjQuery.style( fx.elem, prop, fx.end );\n\t\t\t\tfx.setAttr = true;\n\t\t\t}\n\t\t};\n\t}\n);\n\nfunction getElementStyles( elem ) {\n\tvar key, len,\n\t\tstyle = elem.ownerDocument.defaultView ?\n\t\t\telem.ownerDocument.defaultView.getComputedStyle( elem, null ) :\n\t\t\telem.currentStyle,\n\t\tstyles = {};\n\n\tif ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {\n\t\tlen = style.length;\n\t\twhile ( len-- ) {\n\t\t\tkey = style[ len ];\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ $.camelCase( key ) ] = style[ key ];\n\t\t\t}\n\t\t}\n\n\t// Support: Opera, IE <9\n\t} else {\n\t\tfor ( key in style ) {\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ key ] = style[ key ];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn styles;\n}\n\nfunction styleDifference( oldStyle, newStyle ) {\n\tvar diff = {},\n\t\tname, value;\n\n\tfor ( name in newStyle ) {\n\t\tvalue = newStyle[ name ];\n\t\tif ( oldStyle[ name ] !== value ) {\n\t\t\tif ( !shorthandStyles[ name ] ) {\n\t\t\t\tif ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {\n\t\t\t\t\tdiff[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn diff;\n}\n\n// Support: jQuery <1.8\nif ( !$.fn.addBack ) {\n\t$.fn.addBack = function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t};\n}\n\n$.effects.animateClass = function( value, duration, easing, callback ) {\n\tvar o = $.speed( duration, easing, callback );\n\n\treturn this.queue( function() {\n\t\tvar animated = $( this ),\n\t\t\tbaseClass = animated.attr( \"class\" ) || \"\",\n\t\t\tapplyClassChange,\n\t\t\tallAnimations = o.children ? animated.find( \"*\" ).addBack() : animated;\n\n\t\t// Map the animated objects to store the original styles.\n\t\tallAnimations = allAnimations.map( function() {\n\t\t\tvar el = $( this );\n\t\t\treturn {\n\t\t\t\tel: el,\n\t\t\t\tstart: getElementStyles( this )\n\t\t\t};\n\t\t} );\n\n\t\t// Apply class change\n\t\tapplyClassChange = function() {\n\t\t\t$.each( classAnimationActions, function( i, action ) {\n\t\t\t\tif ( value[ action ] ) {\n\t\t\t\t\tanimated[ action + \"Class\" ]( value[ action ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\t\tapplyClassChange();\n\n\t\t// Map all animated objects again - calculate new styles and diff\n\t\tallAnimations = allAnimations.map( function() {\n\t\t\tthis.end = getElementStyles( this.el[ 0 ] );\n\t\t\tthis.diff = styleDifference( this.start, this.end );\n\t\t\treturn this;\n\t\t} );\n\n\t\t// Apply original class\n\t\tanimated.attr( \"class\", baseClass );\n\n\t\t// Map all animated objects again - this time collecting a promise\n\t\tallAnimations = allAnimations.map( function() {\n\t\t\tvar styleInfo = this,\n\t\t\t\tdfd = $.Deferred(),\n\t\t\t\topts = $.extend( {}, o, {\n\t\t\t\t\tqueue: false,\n\t\t\t\t\tcomplete: function() {\n\t\t\t\t\t\tdfd.resolve( styleInfo );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\tthis.el.animate( this.diff, opts );\n\t\t\treturn dfd.promise();\n\t\t} );\n\n\t\t// Once all animations have completed:\n\t\t$.when.apply( $, allAnimations.get() ).done( function() {\n\n\t\t\t// Set the final class\n\t\t\tapplyClassChange();\n\n\t\t\t// For each animated element,\n\t\t\t// clear all css properties that were animated\n\t\t\t$.each( arguments, function() {\n\t\t\t\tvar el = this.el;\n\t\t\t\t$.each( this.diff, function( key ) {\n\t\t\t\t\tel.css( key, \"\" );\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\t// This is guarnteed to be there if you use jQuery.speed()\n\t\t\t// it also handles dequeuing the next anim...\n\t\t\to.complete.call( animated[ 0 ] );\n\t\t} );\n\t} );\n};\n\n$.fn.extend( {\n\taddClass: ( function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn speed ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ add: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t} )( $.fn.addClass ),\n\n\tremoveClass: ( function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn arguments.length > 1 ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ remove: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t} )( $.fn.removeClass ),\n\n\ttoggleClass: ( function( orig ) {\n\t\treturn function( classNames, force, speed, easing, callback ) {\n\t\t\tif ( typeof force === \"boolean\" || force === undefined ) {\n\t\t\t\tif ( !speed ) {\n\n\t\t\t\t\t// Without speed parameter\n\t\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t\t} else {\n\t\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t\t( force ? { add: classNames } : { remove: classNames } ),\n\t\t\t\t\t\tspeed, easing, callback );\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Without force parameter\n\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t{ toggle: classNames }, force, speed, easing );\n\t\t\t}\n\t\t};\n\t} )( $.fn.toggleClass ),\n\n\tswitchClass: function( remove, add, speed, easing, callback ) {\n\t\treturn $.effects.animateClass.call( this, {\n\t\t\tadd: add,\n\t\t\tremove: remove\n\t\t}, speed, easing, callback );\n\t}\n} );\n\n} )();\n\n/******************************************************************************/\n/*********************************** EFFECTS **********************************/\n/******************************************************************************/\n\n( function() {\n\nif ( $.expr && $.expr.filters && $.expr.filters.animated ) {\n\t$.expr.filters.animated = ( function( orig ) {\n\t\treturn function( elem ) {\n\t\t\treturn !!$( elem ).data( dataSpaceAnimated ) || orig( elem );\n\t\t};\n\t} )( $.expr.filters.animated );\n}\n\nif ( $.uiBackCompat !== false ) {\n\t$.extend( $.effects, {\n\n\t\t// Saves a set of properties in a data storage\n\t\tsave: function( element, set ) {\n\t\t\tvar i = 0, length = set.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\t\telement.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Restores a set of previously saved properties from a data storage\n\t\trestore: function( element, set ) {\n\t\t\tvar val, i = 0, length = set.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\t\tval = element.data( dataSpace + set[ i ] );\n\t\t\t\t\telement.css( set[ i ], val );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tsetMode: function( el, mode ) {\n\t\t\tif ( mode === \"toggle\" ) {\n\t\t\t\tmode = el.is( \":hidden\" ) ? \"show\" : \"hide\";\n\t\t\t}\n\t\t\treturn mode;\n\t\t},\n\n\t\t// Wraps the element around a wrapper that copies position properties\n\t\tcreateWrapper: function( element ) {\n\n\t\t\t// If the element is already wrapped, return it\n\t\t\tif ( element.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t\t\treturn element.parent();\n\t\t\t}\n\n\t\t\t// Wrap the element\n\t\t\tvar props = {\n\t\t\t\t\twidth: element.outerWidth( true ),\n\t\t\t\t\theight: element.outerHeight( true ),\n\t\t\t\t\t\"float\": element.css( \"float\" )\n\t\t\t\t},\n\t\t\t\twrapper = $( \"<div></div>\" )\n\t\t\t\t\t.addClass( \"ui-effects-wrapper\" )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\tfontSize: \"100%\",\n\t\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\t\tborder: \"none\",\n\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\tpadding: 0\n\t\t\t\t\t} ),\n\n\t\t\t\t// Store the size in case width/height are defined in % - Fixes #5245\n\t\t\t\tsize = {\n\t\t\t\t\twidth: element.width(),\n\t\t\t\t\theight: element.height()\n\t\t\t\t},\n\t\t\t\tactive = document.activeElement;\n\n\t\t\t// Support: Firefox\n\t\t\t// Firefox incorrectly exposes anonymous content\n\t\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=561664\n\t\t\ttry {\n\t\t\t\tactive.id;\n\t\t\t} catch ( e ) {\n\t\t\t\tactive = document.body;\n\t\t\t}\n\n\t\t\telement.wrap( wrapper );\n\n\t\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t\t$( active ).trigger( \"focus\" );\n\t\t\t}\n\n\t\t\t// Hotfix for jQuery 1.4 since some change in wrap() seems to actually\n\t\t\t// lose the reference to the wrapped element\n\t\t\twrapper = element.parent();\n\n\t\t\t// Transfer positioning properties to the wrapper\n\t\t\tif ( element.css( \"position\" ) === \"static\" ) {\n\t\t\t\twrapper.css( { position: \"relative\" } );\n\t\t\t\telement.css( { position: \"relative\" } );\n\t\t\t} else {\n\t\t\t\t$.extend( props, {\n\t\t\t\t\tposition: element.css( \"position\" ),\n\t\t\t\t\tzIndex: element.css( \"z-index\" )\n\t\t\t\t} );\n\t\t\t\t$.each( [ \"top\", \"left\", \"bottom\", \"right\" ], function( i, pos ) {\n\t\t\t\t\tprops[ pos ] = element.css( pos );\n\t\t\t\t\tif ( isNaN( parseInt( props[ pos ], 10 ) ) ) {\n\t\t\t\t\t\tprops[ pos ] = \"auto\";\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\telement.css( {\n\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tright: \"auto\",\n\t\t\t\t\tbottom: \"auto\"\n\t\t\t\t} );\n\t\t\t}\n\t\t\telement.css( size );\n\n\t\t\treturn wrapper.css( props ).show();\n\t\t},\n\n\t\tremoveWrapper: function( element ) {\n\t\t\tvar active = document.activeElement;\n\n\t\t\tif ( element.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t\t\telement.parent().replaceWith( element );\n\n\t\t\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\t\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t\t\t$( active ).trigger( \"focus\" );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn element;\n\t\t}\n\t} );\n}\n\n$.extend( $.effects, {\n\tversion: \"1.12.1\",\n\n\tdefine: function( name, mode, effect ) {\n\t\tif ( !effect ) {\n\t\t\teffect = mode;\n\t\t\tmode = \"effect\";\n\t\t}\n\n\t\t$.effects.effect[ name ] = effect;\n\t\t$.effects.effect[ name ].mode = mode;\n\n\t\treturn effect;\n\t},\n\n\tscaledDimensions: function( element, percent, direction ) {\n\t\tif ( percent === 0 ) {\n\t\t\treturn {\n\t\t\t\theight: 0,\n\t\t\t\twidth: 0,\n\t\t\t\touterHeight: 0,\n\t\t\t\touterWidth: 0\n\t\t\t};\n\t\t}\n\n\t\tvar x = direction !== \"horizontal\" ? ( ( percent || 100 ) / 100 ) : 1,\n\t\t\ty = direction !== \"vertical\" ? ( ( percent || 100 ) / 100 ) : 1;\n\n\t\treturn {\n\t\t\theight: element.height() * y,\n\t\t\twidth: element.width() * x,\n\t\t\touterHeight: element.outerHeight() * y,\n\t\t\touterWidth: element.outerWidth() * x\n\t\t};\n\n\t},\n\n\tclipToBox: function( animation ) {\n\t\treturn {\n\t\t\twidth: animation.clip.right - animation.clip.left,\n\t\t\theight: animation.clip.bottom - animation.clip.top,\n\t\t\tleft: animation.clip.left,\n\t\t\ttop: animation.clip.top\n\t\t};\n\t},\n\n\t// Injects recently queued functions to be first in line (after \"inprogress\")\n\tunshift: function( element, queueLength, count ) {\n\t\tvar queue = element.queue();\n\n\t\tif ( queueLength > 1 ) {\n\t\t\tqueue.splice.apply( queue,\n\t\t\t\t[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );\n\t\t}\n\t\telement.dequeue();\n\t},\n\n\tsaveStyle: function( element ) {\n\t\telement.data( dataSpaceStyle, element[ 0 ].style.cssText );\n\t},\n\n\trestoreStyle: function( element ) {\n\t\telement[ 0 ].style.cssText = element.data( dataSpaceStyle ) || \"\";\n\t\telement.removeData( dataSpaceStyle );\n\t},\n\n\tmode: function( element, mode ) {\n\t\tvar hidden = element.is( \":hidden\" );\n\n\t\tif ( mode === \"toggle\" ) {\n\t\t\tmode = hidden ? \"show\" : \"hide\";\n\t\t}\n\t\tif ( hidden ? mode === \"hide\" : mode === \"show\" ) {\n\t\t\tmode = \"none\";\n\t\t}\n\t\treturn mode;\n\t},\n\n\t// Translates a [top,left] array into a baseline value\n\tgetBaseline: function( origin, original ) {\n\t\tvar y, x;\n\n\t\tswitch ( origin[ 0 ] ) {\n\t\tcase \"top\":\n\t\t\ty = 0;\n\t\t\tbreak;\n\t\tcase \"middle\":\n\t\t\ty = 0.5;\n\t\t\tbreak;\n\t\tcase \"bottom\":\n\t\t\ty = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ty = origin[ 0 ] / original.height;\n\t\t}\n\n\t\tswitch ( origin[ 1 ] ) {\n\t\tcase \"left\":\n\t\t\tx = 0;\n\t\t\tbreak;\n\t\tcase \"center\":\n\t\t\tx = 0.5;\n\t\t\tbreak;\n\t\tcase \"right\":\n\t\t\tx = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tx = origin[ 1 ] / original.width;\n\t\t}\n\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t},\n\n\t// Creates a placeholder element so that the original element can be made absolute\n\tcreatePlaceholder: function( element ) {\n\t\tvar placeholder,\n\t\t\tcssPosition = element.css( \"position\" ),\n\t\t\tposition = element.position();\n\n\t\t// Lock in margins first to account for form elements, which\n\t\t// will change margin if you explicitly set height\n\t\t// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380\n\t\t// Support: Safari\n\t\telement.css( {\n\t\t\tmarginTop: element.css( \"marginTop\" ),\n\t\t\tmarginBottom: element.css( \"marginBottom\" ),\n\t\t\tmarginLeft: element.css( \"marginLeft\" ),\n\t\t\tmarginRight: element.css( \"marginRight\" )\n\t\t} )\n\t\t.outerWidth( element.outerWidth() )\n\t\t.outerHeight( element.outerHeight() );\n\n\t\tif ( /^(static|relative)/.test( cssPosition ) ) {\n\t\t\tcssPosition = \"absolute\";\n\n\t\t\tplaceholder = $( \"<\" + element[ 0 ].nodeName + \">\" ).insertAfter( element ).css( {\n\n\t\t\t\t// Convert inline to inline block to account for inline elements\n\t\t\t\t// that turn to inline block based on content (like img)\n\t\t\t\tdisplay: /^(inline|ruby)/.test( element.css( \"display\" ) ) ?\n\t\t\t\t\t\"inline-block\" :\n\t\t\t\t\t\"block\",\n\t\t\t\tvisibility: \"hidden\",\n\n\t\t\t\t// Margins need to be set to account for margin collapse\n\t\t\t\tmarginTop: element.css( \"marginTop\" ),\n\t\t\t\tmarginBottom: element.css( \"marginBottom\" ),\n\t\t\t\tmarginLeft: element.css( \"marginLeft\" ),\n\t\t\t\tmarginRight: element.css( \"marginRight\" ),\n\t\t\t\t\"float\": element.css( \"float\" )\n\t\t\t} )\n\t\t\t.outerWidth( element.outerWidth() )\n\t\t\t.outerHeight( element.outerHeight() )\n\t\t\t.addClass( \"ui-effects-placeholder\" );\n\n\t\t\telement.data( dataSpace + \"placeholder\", placeholder );\n\t\t}\n\n\t\telement.css( {\n\t\t\tposition: cssPosition,\n\t\t\tleft: position.left,\n\t\t\ttop: position.top\n\t\t} );\n\n\t\treturn placeholder;\n\t},\n\n\tremovePlaceholder: function( element ) {\n\t\tvar dataKey = dataSpace + \"placeholder\",\n\t\t\t\tplaceholder = element.data( dataKey );\n\n\t\tif ( placeholder ) {\n\t\t\tplaceholder.remove();\n\t\t\telement.removeData( dataKey );\n\t\t}\n\t},\n\n\t// Removes a placeholder if it exists and restores\n\t// properties that were modified during placeholder creation\n\tcleanUp: function( element ) {\n\t\t$.effects.restoreStyle( element );\n\t\t$.effects.removePlaceholder( element );\n\t},\n\n\tsetTransition: function( element, list, factor, value ) {\n\t\tvalue = value || {};\n\t\t$.each( list, function( i, x ) {\n\t\t\tvar unit = element.cssUnit( x );\n\t\t\tif ( unit[ 0 ] > 0 ) {\n\t\t\t\tvalue[ x ] = unit[ 0 ] * factor + unit[ 1 ];\n\t\t\t}\n\t\t} );\n\t\treturn value;\n\t}\n} );\n\n// Return an effect options object for the given parameters:\nfunction _normalizeArguments( effect, options, speed, callback ) {\n\n\t// Allow passing all options as the first parameter\n\tif ( $.isPlainObject( effect ) ) {\n\t\toptions = effect;\n\t\teffect = effect.effect;\n\t}\n\n\t// Convert to an object\n\teffect = { effect: effect };\n\n\t// Catch (effect, null, ...)\n\tif ( options == null ) {\n\t\toptions = {};\n\t}\n\n\t// Catch (effect, callback)\n\tif ( $.isFunction( options ) ) {\n\t\tcallback = options;\n\t\tspeed = null;\n\t\toptions = {};\n\t}\n\n\t// Catch (effect, speed, ?)\n\tif ( typeof options === \"number\" || $.fx.speeds[ options ] ) {\n\t\tcallback = speed;\n\t\tspeed = options;\n\t\toptions = {};\n\t}\n\n\t// Catch (effect, options, callback)\n\tif ( $.isFunction( speed ) ) {\n\t\tcallback = speed;\n\t\tspeed = null;\n\t}\n\n\t// Add options to effect\n\tif ( options ) {\n\t\t$.extend( effect, options );\n\t}\n\n\tspeed = speed || options.duration;\n\teffect.duration = $.fx.off ? 0 :\n\t\ttypeof speed === \"number\" ? speed :\n\t\tspeed in $.fx.speeds ? $.fx.speeds[ speed ] :\n\t\t$.fx.speeds._default;\n\n\teffect.complete = callback || options.complete;\n\n\treturn effect;\n}\n\nfunction standardAnimationOption( option ) {\n\n\t// Valid standard speeds (nothing, number, named speed)\n\tif ( !option || typeof option === \"number\" || $.fx.speeds[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Invalid strings - treat as \"normal\" speed\n\tif ( typeof option === \"string\" && !$.effects.effect[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Complete callback\n\tif ( $.isFunction( option ) ) {\n\t\treturn true;\n\t}\n\n\t// Options hash (but not naming an effect)\n\tif ( typeof option === \"object\" && !option.effect ) {\n\t\treturn true;\n\t}\n\n\t// Didn't match any standard API\n\treturn false;\n}\n\n$.fn.extend( {\n\teffect: function( /* effect, options, speed, callback */ ) {\n\t\tvar args = _normalizeArguments.apply( this, arguments ),\n\t\t\teffectMethod = $.effects.effect[ args.effect ],\n\t\t\tdefaultMode = effectMethod.mode,\n\t\t\tqueue = args.queue,\n\t\t\tqueueName = queue || \"fx\",\n\t\t\tcomplete = args.complete,\n\t\t\tmode = args.mode,\n\t\t\tmodes = [],\n\t\t\tprefilter = function( next ) {\n\t\t\t\tvar el = $( this ),\n\t\t\t\t\tnormalizedMode = $.effects.mode( el, mode ) || defaultMode;\n\n\t\t\t\t// Sentinel for duck-punching the :animated psuedo-selector\n\t\t\t\tel.data( dataSpaceAnimated, true );\n\n\t\t\t\t// Save effect mode for later use,\n\t\t\t\t// we can't just call $.effects.mode again later,\n\t\t\t\t// as the .show() below destroys the initial state\n\t\t\t\tmodes.push( normalizedMode );\n\n\t\t\t\t// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13\n\t\t\t\tif ( defaultMode && ( normalizedMode === \"show\" ||\n\t\t\t\t\t\t( normalizedMode === defaultMode && normalizedMode === \"hide\" ) ) ) {\n\t\t\t\t\tel.show();\n\t\t\t\t}\n\n\t\t\t\tif ( !defaultMode || normalizedMode !== \"none\" ) {\n\t\t\t\t\t$.effects.saveStyle( el );\n\t\t\t\t}\n\n\t\t\t\tif ( $.isFunction( next ) ) {\n\t\t\t\t\tnext();\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( $.fx.off || !effectMethod ) {\n\n\t\t\t// Delegate to the original method (e.g., .show()) if possible\n\t\t\tif ( mode ) {\n\t\t\t\treturn this[ mode ]( args.duration, complete );\n\t\t\t} else {\n\t\t\t\treturn this.each( function() {\n\t\t\t\t\tif ( complete ) {\n\t\t\t\t\t\tcomplete.call( this );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t\tfunction run( next ) {\n\t\t\tvar elem = $( this );\n\n\t\t\tfunction cleanup() {\n\t\t\t\telem.removeData( dataSpaceAnimated );\n\n\t\t\t\t$.effects.cleanUp( elem );\n\n\t\t\t\tif ( args.mode === \"hide\" ) {\n\t\t\t\t\telem.hide();\n\t\t\t\t}\n\n\t\t\t\tdone();\n\t\t\t}\n\n\t\t\tfunction done() {\n\t\t\t\tif ( $.isFunction( complete ) ) {\n\t\t\t\t\tcomplete.call( elem[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\tif ( $.isFunction( next ) ) {\n\t\t\t\t\tnext();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override mode option on a per element basis,\n\t\t\t// as toggle can be either show or hide depending on element state\n\t\t\targs.mode = modes.shift();\n\n\t\t\tif ( $.uiBackCompat !== false && !defaultMode ) {\n\t\t\t\tif ( elem.is( \":hidden\" ) ? mode === \"hide\" : mode === \"show\" ) {\n\n\t\t\t\t\t// Call the core method to track \"olddisplay\" properly\n\t\t\t\t\telem[ mode ]();\n\t\t\t\t\tdone();\n\t\t\t\t} else {\n\t\t\t\t\teffectMethod.call( elem[ 0 ], args, done );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( args.mode === \"none\" ) {\n\n\t\t\t\t\t// Call the core method to track \"olddisplay\" properly\n\t\t\t\t\telem[ mode ]();\n\t\t\t\t\tdone();\n\t\t\t\t} else {\n\t\t\t\t\teffectMethod.call( elem[ 0 ], args, cleanup );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Run prefilter on all elements first to ensure that\n\t\t// any showing or hiding happens before placeholder creation,\n\t\t// which ensures that any layout changes are correctly captured.\n\t\treturn queue === false ?\n\t\t\tthis.each( prefilter ).each( run ) :\n\t\t\tthis.queue( queueName, prefilter ).queue( queueName, run );\n\t},\n\n\tshow: ( function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"show\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t} )( $.fn.show ),\n\n\thide: ( function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"hide\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t} )( $.fn.hide ),\n\n\ttoggle: ( function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) || typeof option === \"boolean\" ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"toggle\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t} )( $.fn.toggle ),\n\n\tcssUnit: function( key ) {\n\t\tvar style = this.css( key ),\n\t\t\tval = [];\n\n\t\t$.each( [ \"em\", \"px\", \"%\", \"pt\" ], function( i, unit ) {\n\t\t\tif ( style.indexOf( unit ) > 0 ) {\n\t\t\t\tval = [ parseFloat( style ), unit ];\n\t\t\t}\n\t\t} );\n\t\treturn val;\n\t},\n\n\tcssClip: function( clipObj ) {\n\t\tif ( clipObj ) {\n\t\t\treturn this.css( \"clip\", \"rect(\" + clipObj.top + \"px \" + clipObj.right + \"px \" +\n\t\t\t\tclipObj.bottom + \"px \" + clipObj.left + \"px)\" );\n\t\t}\n\t\treturn parseClip( this.css( \"clip\" ), this );\n\t},\n\n\ttransfer: function( options, done ) {\n\t\tvar element = $( this ),\n\t\t\ttarget = $( options.to ),\n\t\t\ttargetFixed = target.css( \"position\" ) === \"fixed\",\n\t\t\tbody = $( \"body\" ),\n\t\t\tfixTop = targetFixed ? body.scrollTop() : 0,\n\t\t\tfixLeft = targetFixed ? body.scrollLeft() : 0,\n\t\t\tendPosition = target.offset(),\n\t\t\tanimation = {\n\t\t\t\ttop: endPosition.top - fixTop,\n\t\t\t\tleft: endPosition.left - fixLeft,\n\t\t\t\theight: target.innerHeight(),\n\t\t\t\twidth: target.innerWidth()\n\t\t\t},\n\t\t\tstartPosition = element.offset(),\n\t\t\ttransfer = $( \"<div class='ui-effects-transfer'></div>\" )\n\t\t\t\t.appendTo( \"body\" )\n\t\t\t\t.addClass( options.className )\n\t\t\t\t.css( {\n\t\t\t\t\ttop: startPosition.top - fixTop,\n\t\t\t\t\tleft: startPosition.left - fixLeft,\n\t\t\t\t\theight: element.innerHeight(),\n\t\t\t\t\twidth: element.innerWidth(),\n\t\t\t\t\tposition: targetFixed ? \"fixed\" : \"absolute\"\n\t\t\t\t} )\n\t\t\t\t.animate( animation, options.duration, options.easing, function() {\n\t\t\t\t\ttransfer.remove();\n\t\t\t\t\tif ( $.isFunction( done ) ) {\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t}\n} );\n\nfunction parseClip( str, element ) {\n\t\tvar outerWidth = element.outerWidth(),\n\t\t\touterHeight = element.outerHeight(),\n\t\t\tclipRegex = /^rect\\((-?\\d*\\.?\\d*px|-?\\d+%|auto),?\\s*(-?\\d*\\.?\\d*px|-?\\d+%|auto),?\\s*(-?\\d*\\.?\\d*px|-?\\d+%|auto),?\\s*(-?\\d*\\.?\\d*px|-?\\d+%|auto)\\)$/,\n\t\t\tvalues = clipRegex.exec( str ) || [ \"\", 0, outerWidth, outerHeight, 0 ];\n\n\t\treturn {\n\t\t\ttop: parseFloat( values[ 1 ] ) || 0,\n\t\t\tright: values[ 2 ] === \"auto\" ? outerWidth : parseFloat( values[ 2 ] ),\n\t\t\tbottom: values[ 3 ] === \"auto\" ? outerHeight : parseFloat( values[ 3 ] ),\n\t\t\tleft: parseFloat( values[ 4 ] ) || 0\n\t\t};\n}\n\n$.fx.step.clip = function( fx ) {\n\tif ( !fx.clipInit ) {\n\t\tfx.start = $( fx.elem ).cssClip();\n\t\tif ( typeof fx.end === \"string\" ) {\n\t\t\tfx.end = parseClip( fx.end, fx.elem );\n\t\t}\n\t\tfx.clipInit = true;\n\t}\n\n\t$( fx.elem ).cssClip( {\n\t\ttop: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,\n\t\tright: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,\n\t\tbottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,\n\t\tleft: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left\n\t} );\n};\n\n} )();\n\n/******************************************************************************/\n/*********************************** EASING ***********************************/\n/******************************************************************************/\n\n( function() {\n\n// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)\n\nvar baseEasings = {};\n\n$.each( [ \"Quad\", \"Cubic\", \"Quart\", \"Quint\", \"Expo\" ], function( i, name ) {\n\tbaseEasings[ name ] = function( p ) {\n\t\treturn Math.pow( p, i + 2 );\n\t};\n} );\n\n$.extend( baseEasings, {\n\tSine: function( p ) {\n\t\treturn 1 - Math.cos( p * Math.PI / 2 );\n\t},\n\tCirc: function( p ) {\n\t\treturn 1 - Math.sqrt( 1 - p * p );\n\t},\n\tElastic: function( p ) {\n\t\treturn p === 0 || p === 1 ? p :\n\t\t\t-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );\n\t},\n\tBack: function( p ) {\n\t\treturn p * p * ( 3 * p - 2 );\n\t},\n\tBounce: function( p ) {\n\t\tvar pow2,\n\t\t\tbounce = 4;\n\n\t\twhile ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}\n\t\treturn 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );\n\t}\n} );\n\n$.each( baseEasings, function( name, easeIn ) {\n\t$.easing[ \"easeIn\" + name ] = easeIn;\n\t$.easing[ \"easeOut\" + name ] = function( p ) {\n\t\treturn 1 - easeIn( 1 - p );\n\t};\n\t$.easing[ \"easeInOut\" + name ] = function( p ) {\n\t\treturn p < 0.5 ?\n\t\t\teaseIn( p * 2 ) / 2 :\n\t\t\t1 - easeIn( p * -2 + 2 ) / 2;\n\t};\n} );\n\n} )();\n\nreturn $.effects;\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/ie.js",
    "content": "//= require rails_admin/jquery-ui/version\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\", \"./version\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n} ( function( $ ) {\n\n// This file is deprecated\nreturn $.ui.ie = !!/msie [\\w.]+/.exec( navigator.userAgent.toLowerCase() );\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/keycode.js",
    "content": "//= require rails_admin/jquery-ui/version\n\n/*!\n * jQuery UI Keycode 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Keycode\n//>>group: Core\n//>>description: Provide keycodes as keynames\n//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\", \"./version\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n} ( function( $ ) {\nreturn $.ui.keyCode = {\n\tBACKSPACE: 8,\n\tCOMMA: 188,\n\tDELETE: 46,\n\tDOWN: 40,\n\tEND: 35,\n\tENTER: 13,\n\tESCAPE: 27,\n\tHOME: 36,\n\tLEFT: 37,\n\tPAGE_DOWN: 34,\n\tPAGE_UP: 33,\n\tPERIOD: 190,\n\tRIGHT: 39,\n\tSPACE: 32,\n\tTAB: 9,\n\tUP: 38\n};\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/position.js",
    "content": "//= require rails_admin/jquery-ui/version\n\n/*!\n * jQuery UI Position 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/position/\n */\n\n//>>label: Position\n//>>group: Core\n//>>description: Positions elements relative to other elements.\n//>>docs: http://api.jqueryui.com/position/\n//>>demos: http://jqueryui.com/position/\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\", \"./version\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}( function( $ ) {\n( function() {\nvar cachedScrollbarWidth,\n\tmax = Math.max,\n\tabs = Math.abs,\n\trhorizontal = /left|center|right/,\n\trvertical = /top|center|bottom/,\n\troffset = /[\\+\\-]\\d+(\\.[\\d]+)?%?/,\n\trposition = /^\\w+/,\n\trpercent = /%$/,\n\t_position = $.fn.position;\n\nfunction getOffsets( offsets, width, height ) {\n\treturn [\n\t\tparseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),\n\t\tparseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )\n\t];\n}\n\nfunction parseCss( element, property ) {\n\treturn parseInt( $.css( element, property ), 10 ) || 0;\n}\n\nfunction getDimensions( elem ) {\n\tvar raw = elem[ 0 ];\n\tif ( raw.nodeType === 9 ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: 0, left: 0 }\n\t\t};\n\t}\n\tif ( $.isWindow( raw ) ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: elem.scrollTop(), left: elem.scrollLeft() }\n\t\t};\n\t}\n\tif ( raw.preventDefault ) {\n\t\treturn {\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\toffset: { top: raw.pageY, left: raw.pageX }\n\t\t};\n\t}\n\treturn {\n\t\twidth: elem.outerWidth(),\n\t\theight: elem.outerHeight(),\n\t\toffset: elem.offset()\n\t};\n}\n\n$.position = {\n\tscrollbarWidth: function() {\n\t\tif ( cachedScrollbarWidth !== undefined ) {\n\t\t\treturn cachedScrollbarWidth;\n\t\t}\n\t\tvar w1, w2,\n\t\t\tdiv = $( \"<div \" +\n\t\t\t\t\"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>\" +\n\t\t\t\t\"<div style='height:100px;width:auto;'></div></div>\" ),\n\t\t\tinnerDiv = div.children()[ 0 ];\n\n\t\t$( \"body\" ).append( div );\n\t\tw1 = innerDiv.offsetWidth;\n\t\tdiv.css( \"overflow\", \"scroll\" );\n\n\t\tw2 = innerDiv.offsetWidth;\n\n\t\tif ( w1 === w2 ) {\n\t\t\tw2 = div[ 0 ].clientWidth;\n\t\t}\n\n\t\tdiv.remove();\n\n\t\treturn ( cachedScrollbarWidth = w1 - w2 );\n\t},\n\tgetScrollInfo: function( within ) {\n\t\tvar overflowX = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-x\" ),\n\t\t\toverflowY = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-y\" ),\n\t\t\thasOverflowX = overflowX === \"scroll\" ||\n\t\t\t\t( overflowX === \"auto\" && within.width < within.element[ 0 ].scrollWidth ),\n\t\t\thasOverflowY = overflowY === \"scroll\" ||\n\t\t\t\t( overflowY === \"auto\" && within.height < within.element[ 0 ].scrollHeight );\n\t\treturn {\n\t\t\twidth: hasOverflowY ? $.position.scrollbarWidth() : 0,\n\t\t\theight: hasOverflowX ? $.position.scrollbarWidth() : 0\n\t\t};\n\t},\n\tgetWithinInfo: function( element ) {\n\t\tvar withinElement = $( element || window ),\n\t\t\tisWindow = $.isWindow( withinElement[ 0 ] ),\n\t\t\tisDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,\n\t\t\thasOffset = !isWindow && !isDocument;\n\t\treturn {\n\t\t\telement: withinElement,\n\t\t\tisWindow: isWindow,\n\t\t\tisDocument: isDocument,\n\t\t\toffset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },\n\t\t\tscrollLeft: withinElement.scrollLeft(),\n\t\t\tscrollTop: withinElement.scrollTop(),\n\t\t\twidth: withinElement.outerWidth(),\n\t\t\theight: withinElement.outerHeight()\n\t\t};\n\t}\n};\n\n$.fn.position = function( options ) {\n\tif ( !options || !options.of ) {\n\t\treturn _position.apply( this, arguments );\n\t}\n\n\t// Make a copy, we don't want to modify arguments\n\toptions = $.extend( {}, options );\n\n\tvar atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,\n\t\ttarget = $( options.of ),\n\t\twithin = $.position.getWithinInfo( options.within ),\n\t\tscrollInfo = $.position.getScrollInfo( within ),\n\t\tcollision = ( options.collision || \"flip\" ).split( \" \" ),\n\t\toffsets = {};\n\n\tdimensions = getDimensions( target );\n\tif ( target[ 0 ].preventDefault ) {\n\n\t\t// Force left top to allow flipping\n\t\toptions.at = \"left top\";\n\t}\n\ttargetWidth = dimensions.width;\n\ttargetHeight = dimensions.height;\n\ttargetOffset = dimensions.offset;\n\n\t// Clone to reuse original targetOffset later\n\tbasePosition = $.extend( {}, targetOffset );\n\n\t// Force my and at to have valid horizontal and vertical positions\n\t// if a value is missing or invalid, it will be converted to center\n\t$.each( [ \"my\", \"at\" ], function() {\n\t\tvar pos = ( options[ this ] || \"\" ).split( \" \" ),\n\t\t\thorizontalOffset,\n\t\t\tverticalOffset;\n\n\t\tif ( pos.length === 1 ) {\n\t\t\tpos = rhorizontal.test( pos[ 0 ] ) ?\n\t\t\t\tpos.concat( [ \"center\" ] ) :\n\t\t\t\trvertical.test( pos[ 0 ] ) ?\n\t\t\t\t\t[ \"center\" ].concat( pos ) :\n\t\t\t\t\t[ \"center\", \"center\" ];\n\t\t}\n\t\tpos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : \"center\";\n\t\tpos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : \"center\";\n\n\t\t// Calculate offsets\n\t\thorizontalOffset = roffset.exec( pos[ 0 ] );\n\t\tverticalOffset = roffset.exec( pos[ 1 ] );\n\t\toffsets[ this ] = [\n\t\t\thorizontalOffset ? horizontalOffset[ 0 ] : 0,\n\t\t\tverticalOffset ? verticalOffset[ 0 ] : 0\n\t\t];\n\n\t\t// Reduce to just the positions without the offsets\n\t\toptions[ this ] = [\n\t\t\trposition.exec( pos[ 0 ] )[ 0 ],\n\t\t\trposition.exec( pos[ 1 ] )[ 0 ]\n\t\t];\n\t} );\n\n\t// Normalize collision option\n\tif ( collision.length === 1 ) {\n\t\tcollision[ 1 ] = collision[ 0 ];\n\t}\n\n\tif ( options.at[ 0 ] === \"right\" ) {\n\t\tbasePosition.left += targetWidth;\n\t} else if ( options.at[ 0 ] === \"center\" ) {\n\t\tbasePosition.left += targetWidth / 2;\n\t}\n\n\tif ( options.at[ 1 ] === \"bottom\" ) {\n\t\tbasePosition.top += targetHeight;\n\t} else if ( options.at[ 1 ] === \"center\" ) {\n\t\tbasePosition.top += targetHeight / 2;\n\t}\n\n\tatOffset = getOffsets( offsets.at, targetWidth, targetHeight );\n\tbasePosition.left += atOffset[ 0 ];\n\tbasePosition.top += atOffset[ 1 ];\n\n\treturn this.each( function() {\n\t\tvar collisionPosition, using,\n\t\t\telem = $( this ),\n\t\t\telemWidth = elem.outerWidth(),\n\t\t\telemHeight = elem.outerHeight(),\n\t\t\tmarginLeft = parseCss( this, \"marginLeft\" ),\n\t\t\tmarginTop = parseCss( this, \"marginTop\" ),\n\t\t\tcollisionWidth = elemWidth + marginLeft + parseCss( this, \"marginRight\" ) +\n\t\t\t\tscrollInfo.width,\n\t\t\tcollisionHeight = elemHeight + marginTop + parseCss( this, \"marginBottom\" ) +\n\t\t\t\tscrollInfo.height,\n\t\t\tposition = $.extend( {}, basePosition ),\n\t\t\tmyOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );\n\n\t\tif ( options.my[ 0 ] === \"right\" ) {\n\t\t\tposition.left -= elemWidth;\n\t\t} else if ( options.my[ 0 ] === \"center\" ) {\n\t\t\tposition.left -= elemWidth / 2;\n\t\t}\n\n\t\tif ( options.my[ 1 ] === \"bottom\" ) {\n\t\t\tposition.top -= elemHeight;\n\t\t} else if ( options.my[ 1 ] === \"center\" ) {\n\t\t\tposition.top -= elemHeight / 2;\n\t\t}\n\n\t\tposition.left += myOffset[ 0 ];\n\t\tposition.top += myOffset[ 1 ];\n\n\t\tcollisionPosition = {\n\t\t\tmarginLeft: marginLeft,\n\t\t\tmarginTop: marginTop\n\t\t};\n\n\t\t$.each( [ \"left\", \"top\" ], function( i, dir ) {\n\t\t\tif ( $.ui.position[ collision[ i ] ] ) {\n\t\t\t\t$.ui.position[ collision[ i ] ][ dir ]( position, {\n\t\t\t\t\ttargetWidth: targetWidth,\n\t\t\t\t\ttargetHeight: targetHeight,\n\t\t\t\t\telemWidth: elemWidth,\n\t\t\t\t\telemHeight: elemHeight,\n\t\t\t\t\tcollisionPosition: collisionPosition,\n\t\t\t\t\tcollisionWidth: collisionWidth,\n\t\t\t\t\tcollisionHeight: collisionHeight,\n\t\t\t\t\toffset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],\n\t\t\t\t\tmy: options.my,\n\t\t\t\t\tat: options.at,\n\t\t\t\t\twithin: within,\n\t\t\t\t\telem: elem\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\tif ( options.using ) {\n\n\t\t\t// Adds feedback as second argument to using callback, if present\n\t\t\tusing = function( props ) {\n\t\t\t\tvar left = targetOffset.left - position.left,\n\t\t\t\t\tright = left + targetWidth - elemWidth,\n\t\t\t\t\ttop = targetOffset.top - position.top,\n\t\t\t\t\tbottom = top + targetHeight - elemHeight,\n\t\t\t\t\tfeedback = {\n\t\t\t\t\t\ttarget: {\n\t\t\t\t\t\t\telement: target,\n\t\t\t\t\t\t\tleft: targetOffset.left,\n\t\t\t\t\t\t\ttop: targetOffset.top,\n\t\t\t\t\t\t\twidth: targetWidth,\n\t\t\t\t\t\t\theight: targetHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\telement: {\n\t\t\t\t\t\t\telement: elem,\n\t\t\t\t\t\t\tleft: position.left,\n\t\t\t\t\t\t\ttop: position.top,\n\t\t\t\t\t\t\twidth: elemWidth,\n\t\t\t\t\t\t\theight: elemHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\thorizontal: right < 0 ? \"left\" : left > 0 ? \"right\" : \"center\",\n\t\t\t\t\t\tvertical: bottom < 0 ? \"top\" : top > 0 ? \"bottom\" : \"middle\"\n\t\t\t\t\t};\n\t\t\t\tif ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {\n\t\t\t\t\tfeedback.horizontal = \"center\";\n\t\t\t\t}\n\t\t\t\tif ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {\n\t\t\t\t\tfeedback.vertical = \"middle\";\n\t\t\t\t}\n\t\t\t\tif ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {\n\t\t\t\t\tfeedback.important = \"horizontal\";\n\t\t\t\t} else {\n\t\t\t\t\tfeedback.important = \"vertical\";\n\t\t\t\t}\n\t\t\t\toptions.using.call( this, props, feedback );\n\t\t\t};\n\t\t}\n\n\t\telem.offset( $.extend( position, { using: using } ) );\n\t} );\n};\n\n$.ui.position = {\n\tfit: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\touterWidth = within.width,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = withinOffset - collisionPosLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,\n\t\t\t\tnewOverRight;\n\n\t\t\t// Element is wider than within\n\t\t\tif ( data.collisionWidth > outerWidth ) {\n\n\t\t\t\t// Element is initially over the left side of within\n\t\t\t\tif ( overLeft > 0 && overRight <= 0 ) {\n\t\t\t\t\tnewOverRight = position.left + overLeft + data.collisionWidth - outerWidth -\n\t\t\t\t\t\twithinOffset;\n\t\t\t\t\tposition.left += overLeft - newOverRight;\n\n\t\t\t\t// Element is initially over right side of within\n\t\t\t\t} else if ( overRight > 0 && overLeft <= 0 ) {\n\t\t\t\t\tposition.left = withinOffset;\n\n\t\t\t\t// Element is initially over both left and right sides of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overLeft > overRight ) {\n\t\t\t\t\t\tposition.left = withinOffset + outerWidth - data.collisionWidth;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Too far left -> align with left edge\n\t\t\t} else if ( overLeft > 0 ) {\n\t\t\t\tposition.left += overLeft;\n\n\t\t\t// Too far right -> align with right edge\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tposition.left -= overRight;\n\n\t\t\t// Adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.left = max( position.left - collisionPosLeft, position.left );\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\touterHeight = data.within.height,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = withinOffset - collisionPosTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,\n\t\t\t\tnewOverBottom;\n\n\t\t\t// Element is taller than within\n\t\t\tif ( data.collisionHeight > outerHeight ) {\n\n\t\t\t\t// Element is initially over the top of within\n\t\t\t\tif ( overTop > 0 && overBottom <= 0 ) {\n\t\t\t\t\tnewOverBottom = position.top + overTop + data.collisionHeight - outerHeight -\n\t\t\t\t\t\twithinOffset;\n\t\t\t\t\tposition.top += overTop - newOverBottom;\n\n\t\t\t\t// Element is initially over bottom of within\n\t\t\t\t} else if ( overBottom > 0 && overTop <= 0 ) {\n\t\t\t\t\tposition.top = withinOffset;\n\n\t\t\t\t// Element is initially over both top and bottom of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overTop > overBottom ) {\n\t\t\t\t\t\tposition.top = withinOffset + outerHeight - data.collisionHeight;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Too far up -> align with top\n\t\t\t} else if ( overTop > 0 ) {\n\t\t\t\tposition.top += overTop;\n\n\t\t\t// Too far down -> align with bottom edge\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tposition.top -= overBottom;\n\n\t\t\t// Adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.top = max( position.top - collisionPosTop, position.top );\n\t\t\t}\n\t\t}\n\t},\n\tflip: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.left + within.scrollLeft,\n\t\t\t\touterWidth = within.width,\n\t\t\t\toffsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = collisionPosLeft - offsetLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,\n\t\t\t\tmyOffset = data.my[ 0 ] === \"left\" ?\n\t\t\t\t\t-data.elemWidth :\n\t\t\t\t\tdata.my[ 0 ] === \"right\" ?\n\t\t\t\t\t\tdata.elemWidth :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 0 ] === \"left\" ?\n\t\t\t\t\tdata.targetWidth :\n\t\t\t\t\tdata.at[ 0 ] === \"right\" ?\n\t\t\t\t\t\t-data.targetWidth :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 0 ],\n\t\t\t\tnewOverRight,\n\t\t\t\tnewOverLeft;\n\n\t\t\tif ( overLeft < 0 ) {\n\t\t\t\tnewOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -\n\t\t\t\t\touterWidth - withinOffset;\n\t\t\t\tif ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tnewOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +\n\t\t\t\t\tatOffset + offset - offsetLeft;\n\t\t\t\tif ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.top + within.scrollTop,\n\t\t\t\touterHeight = within.height,\n\t\t\t\toffsetTop = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = collisionPosTop - offsetTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,\n\t\t\t\ttop = data.my[ 1 ] === \"top\",\n\t\t\t\tmyOffset = top ?\n\t\t\t\t\t-data.elemHeight :\n\t\t\t\t\tdata.my[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\tdata.elemHeight :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 1 ] === \"top\" ?\n\t\t\t\t\tdata.targetHeight :\n\t\t\t\t\tdata.at[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\t-data.targetHeight :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 1 ],\n\t\t\t\tnewOverTop,\n\t\t\t\tnewOverBottom;\n\t\t\tif ( overTop < 0 ) {\n\t\t\t\tnewOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -\n\t\t\t\t\touterHeight - withinOffset;\n\t\t\t\tif ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tnewOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +\n\t\t\t\t\toffset - offsetTop;\n\t\t\t\tif ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tflipfit: {\n\t\tleft: function() {\n\t\t\t$.ui.position.flip.left.apply( this, arguments );\n\t\t\t$.ui.position.fit.left.apply( this, arguments );\n\t\t},\n\t\ttop: function() {\n\t\t\t$.ui.position.flip.top.apply( this, arguments );\n\t\t\t$.ui.position.fit.top.apply( this, arguments );\n\t\t}\n\t}\n};\n\n} )();\n\nreturn $.ui.position;\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/safe-active-element.js",
    "content": "//= require rails_admin/jquery-ui/version\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\", \"./version\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n} ( function( $ ) {\nreturn $.ui.safeActiveElement = function( document ) {\n\tvar activeElement;\n\n\t// Support: IE 9 only\n\t// IE9 throws an \"Unspecified error\" accessing document.activeElement from an <iframe>\n\ttry {\n\t\tactiveElement = document.activeElement;\n\t} catch ( error ) {\n\t\tactiveElement = document.body;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE may return null instead of an element\n\t// Interestingly, this only seems to occur when NOT in an iframe\n\tif ( !activeElement ) {\n\t\tactiveElement = document.body;\n\t}\n\n\t// Support: IE 11 only\n\t// IE11 returns a seemingly empty object in some cases when accessing\n\t// document.activeElement from an <iframe>\n\tif ( !activeElement.nodeName ) {\n\t\tactiveElement = document.body;\n\t}\n\n\treturn activeElement;\n};\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/scroll-parent.js",
    "content": "//= require rails_admin/jquery-ui/version\n\n/*!\n * jQuery UI Scroll Parent 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: scrollParent\n//>>group: Core\n//>>description: Get the closest ancestor element that is scrollable.\n//>>docs: http://api.jqueryui.com/scrollParent/\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\", \"./version\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n} ( function( $ ) {\n\nreturn $.fn.scrollParent = function( includeHidden ) {\n\tvar position = this.css( \"position\" ),\n\t\texcludeStaticParent = position === \"absolute\",\n\t\toverflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,\n\t\tscrollParent = this.parents().filter( function() {\n\t\t\tvar parent = $( this );\n\t\t\tif ( excludeStaticParent && parent.css( \"position\" ) === \"static\" ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn overflowRegex.test( parent.css( \"overflow\" ) + parent.css( \"overflow-y\" ) +\n\t\t\t\tparent.css( \"overflow-x\" ) );\n\t\t} ).eq( 0 );\n\n\treturn position === \"fixed\" || !scrollParent.length ?\n\t\t$( this[ 0 ].ownerDocument || document ) :\n\t\tscrollParent;\n};\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/unique-id.js",
    "content": "//= require rails_admin/jquery-ui/version\n\n/*!\n * jQuery UI Unique ID 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: uniqueId\n//>>group: Core\n//>>description: Functions to generate and remove uniqueId's\n//>>docs: http://api.jqueryui.com/uniqueId/\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\", \"./version\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n} ( function( $ ) {\n\nreturn $.fn.extend( {\n\tuniqueId: ( function() {\n\t\tvar uuid = 0;\n\n\t\treturn function() {\n\t\t\treturn this.each( function() {\n\t\t\t\tif ( !this.id ) {\n\t\t\t\t\tthis.id = \"ui-id-\" + ( ++uuid );\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\t} )(),\n\n\tremoveUniqueId: function() {\n\t\treturn this.each( function() {\n\t\t\tif ( /^ui-id-\\d+$/.test( this.id ) ) {\n\t\t\t\t$( this ).removeAttr( \"id\" );\n\t\t\t}\n\t\t} );\n\t}\n} );\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/version.js",
    "content": "( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n} ( function( $ ) {\n\n$.ui = $.ui || {};\n\nreturn $.ui.version = \"1.12.1\";\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/widget.js",
    "content": "//= require rails_admin/jquery-ui/version\n\n/*!\n * jQuery UI Widget 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Widget\n//>>group: Core\n//>>description: Provides a factory for creating stateful widgets with a common API.\n//>>docs: http://api.jqueryui.com/jQuery.widget/\n//>>demos: http://jqueryui.com/widget/\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\", \"./version\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}( function( $ ) {\n\nvar widgetUuid = 0;\nvar widgetSlice = Array.prototype.slice;\n\n$.cleanData = ( function( orig ) {\n\treturn function( elems ) {\n\t\tvar events, elem, i;\n\t\tfor ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\ttry {\n\n\t\t\t\t// Only trigger remove when necessary to save time\n\t\t\t\tevents = $._data( elem, \"events\" );\n\t\t\t\tif ( events && events.remove ) {\n\t\t\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t\t\t}\n\n\t\t\t// Http://bugs.jquery.com/ticket/8235\n\t\t\t} catch ( e ) {}\n\t\t}\n\t\torig( elems );\n\t};\n} )( $.cleanData );\n\n$.widget = function( name, base, prototype ) {\n\tvar existingConstructor, constructor, basePrototype;\n\n\t// ProxiedPrototype allows the provided prototype to remain unmodified\n\t// so that it can be used as a mixin for multiple widgets (#8876)\n\tvar proxiedPrototype = {};\n\n\tvar namespace = name.split( \".\" )[ 0 ];\n\tname = name.split( \".\" )[ 1 ];\n\tvar fullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\tif ( $.isArray( prototype ) ) {\n\t\tprototype = $.extend.apply( null, [ {} ].concat( prototype ) );\n\t}\n\n\t// Create selector for plugin\n\t$.expr[ \":\" ][ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\n\t\t// Allow instantiation without \"new\" keyword\n\t\tif ( !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// Allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\n\t// Extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\n\t\t// Copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\n\t\t// Track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t} );\n\n\tbasePrototype = new base();\n\n\t// We need to make the options hash a property directly on the new instance\n\t// otherwise we'll modify the options hash on the prototype that we're\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( !$.isFunction( value ) ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = ( function() {\n\t\t\tfunction _super() {\n\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t}\n\n\t\t\tfunction _superApply( args ) {\n\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t}\n\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super;\n\t\t\t\tvar __superApply = this._superApply;\n\t\t\t\tvar returnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t} )();\n\t} );\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don't prefix for widgets that aren't DOM-based\n\t\twidgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t} );\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We're essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// Redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor,\n\t\t\t\tchild._proto );\n\t\t} );\n\n\t\t// Remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n\n\treturn constructor;\n};\n\n$.widget.extend = function( target ) {\n\tvar input = widgetSlice.call( arguments, 1 );\n\tvar inputIndex = 0;\n\tvar inputLength = input.length;\n\tvar key;\n\tvar value;\n\n\tfor ( ; inputIndex < inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {\n\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\n\t\t\t\t\t\t// Don't extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\";\n\t\tvar args = widgetSlice.call( arguments, 1 );\n\t\tvar returnValue = this;\n\n\t\tif ( isMethodCall ) {\n\n\t\t\t// If this is an empty collection, we need to have the instance method\n\t\t\t// return undefined instead of the jQuery instance\n\t\t\tif ( !this.length && options === \"instance\" ) {\n\t\t\t\treturnValue = undefined;\n\t\t\t} else {\n\t\t\t\tthis.each( function() {\n\t\t\t\t\tvar methodValue;\n\t\t\t\t\tvar instance = $.data( this, fullName );\n\n\t\t\t\t\tif ( options === \"instance\" ) {\n\t\t\t\t\t\treturnValue = instance;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !instance ) {\n\t\t\t\t\t\treturn $.error( \"cannot call methods on \" + name +\n\t\t\t\t\t\t\t\" prior to initialization; \" +\n\t\t\t\t\t\t\t\"attempted to call method '\" + options + \"'\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\t\treturn $.error( \"no such method '\" + options + \"' for \" + name +\n\t\t\t\t\t\t\t\" widget instance\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\n\t\t\t\t\tif ( methodValue !== instance && methodValue !== undefined ) {\n\t\t\t\t\t\treturnValue = methodValue && methodValue.jquery ?\n\t\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\t\tmethodValue;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// Allow multiple hashes to be passed on init\n\t\t\tif ( args.length ) {\n\t\t\t\toptions = $.widget.extend.apply( null, [ options ].concat( args ) );\n\t\t\t}\n\n\t\t\tthis.each( function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} );\n\t\t\t\t\tif ( instance._init ) {\n\t\t\t\t\t\tinstance._init();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"<div>\",\n\n\toptions: {\n\t\tclasses: {},\n\t\tdisabled: false,\n\n\t\t// Callbacks\n\t\tcreate: null\n\t},\n\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = widgetUuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\t\tthis.classesElementLookup = {};\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t\tthis.document = $( element.style ?\n\n\t\t\t\t// Element within the document\n\t\t\t\telement.ownerDocument :\n\n\t\t\t\t// Element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );\n\t\t}\n\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis._create();\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis._setOptionDisabled( this.options.disabled );\n\t\t}\n\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\n\t_getCreateOptions: function() {\n\t\treturn {};\n\t},\n\n\t_getCreateEventData: $.noop,\n\n\t_create: $.noop,\n\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tvar that = this;\n\n\t\tthis._destroy();\n\t\t$.each( this.classesElementLookup, function( key, value ) {\n\t\t\tthat._removeClass( value, key );\n\t\t} );\n\n\t\t// We can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.off( this.eventNamespace )\n\t\t\t.removeData( this.widgetFullName );\n\t\tthis.widget()\n\t\t\t.off( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" );\n\n\t\t// Clean up events and states\n\t\tthis.bindings.off( this.eventNamespace );\n\t},\n\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key;\n\t\tvar parts;\n\t\tvar curOption;\n\t\tvar i;\n\n\t\tif ( arguments.length === 0 ) {\n\n\t\t\t// Don't return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\n\t\t\t// Handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i < parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"classes\" ) {\n\t\t\tthis._setOptionClasses( value );\n\t\t}\n\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis._setOptionDisabled( value );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOptionClasses: function( value ) {\n\t\tvar classKey, elements, currentElements;\n\n\t\tfor ( classKey in value ) {\n\t\t\tcurrentElements = this.classesElementLookup[ classKey ];\n\t\t\tif ( value[ classKey ] === this.options.classes[ classKey ] ||\n\t\t\t\t\t!currentElements ||\n\t\t\t\t\t!currentElements.length ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// We are doing this to create a new jQuery object because the _removeClass() call\n\t\t\t// on the next line is going to destroy the reference to the current elements being\n\t\t\t// tracked. We need to save a copy of this collection so that we can add the new classes\n\t\t\t// below.\n\t\t\telements = $( currentElements.get() );\n\t\t\tthis._removeClass( currentElements, classKey );\n\n\t\t\t// We don't use _addClass() here, because that uses this.options.classes\n\t\t\t// for generating the string of classes. We want to use the value passed in from\n\t\t\t// _setOption(), this is the new value of the classes option which was passed to\n\t\t\t// _setOption(). We pass this value directly to _classes().\n\t\t\telements.addClass( this._classes( {\n\t\t\t\telement: elements,\n\t\t\t\tkeys: classKey,\n\t\t\t\tclasses: value,\n\t\t\t\tadd: true\n\t\t\t} ) );\n\t\t}\n\t},\n\n\t_setOptionDisabled: function( value ) {\n\t\tthis._toggleClass( this.widget(), this.widgetFullName + \"-disabled\", null, !!value );\n\n\t\t// If the widget is becoming disabled, then nothing is interactive\n\t\tif ( value ) {\n\t\t\tthis._removeClass( this.hoverable, null, \"ui-state-hover\" );\n\t\t\tthis._removeClass( this.focusable, null, \"ui-state-focus\" );\n\t\t}\n\t},\n\n\tenable: function() {\n\t\treturn this._setOptions( { disabled: false } );\n\t},\n\n\tdisable: function() {\n\t\treturn this._setOptions( { disabled: true } );\n\t},\n\n\t_classes: function( options ) {\n\t\tvar full = [];\n\t\tvar that = this;\n\n\t\toptions = $.extend( {\n\t\t\telement: this.element,\n\t\t\tclasses: this.options.classes || {}\n\t\t}, options );\n\n\t\tfunction processClassString( classes, checkOption ) {\n\t\t\tvar current, i;\n\t\t\tfor ( i = 0; i < classes.length; i++ ) {\n\t\t\t\tcurrent = that.classesElementLookup[ classes[ i ] ] || $();\n\t\t\t\tif ( options.add ) {\n\t\t\t\t\tcurrent = $( $.unique( current.get().concat( options.element.get() ) ) );\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = $( current.not( options.element ).get() );\n\t\t\t\t}\n\t\t\t\tthat.classesElementLookup[ classes[ i ] ] = current;\n\t\t\t\tfull.push( classes[ i ] );\n\t\t\t\tif ( checkOption && options.classes[ classes[ i ] ] ) {\n\t\t\t\t\tfull.push( options.classes[ classes[ i ] ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._on( options.element, {\n\t\t\t\"remove\": \"_untrackClassesElement\"\n\t\t} );\n\n\t\tif ( options.keys ) {\n\t\t\tprocessClassString( options.keys.match( /\\S+/g ) || [], true );\n\t\t}\n\t\tif ( options.extra ) {\n\t\t\tprocessClassString( options.extra.match( /\\S+/g ) || [] );\n\t\t}\n\n\t\treturn full.join( \" \" );\n\t},\n\n\t_untrackClassesElement: function( event ) {\n\t\tvar that = this;\n\t\t$.each( that.classesElementLookup, function( key, value ) {\n\t\t\tif ( $.inArray( event.target, value ) !== -1 ) {\n\t\t\t\tthat.classesElementLookup[ key ] = $( value.not( event.target ).get() );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_removeClass: function( element, keys, extra ) {\n\t\treturn this._toggleClass( element, keys, extra, false );\n\t},\n\n\t_addClass: function( element, keys, extra ) {\n\t\treturn this._toggleClass( element, keys, extra, true );\n\t},\n\n\t_toggleClass: function( element, keys, extra, add ) {\n\t\tadd = ( typeof add === \"boolean\" ) ? add : extra;\n\t\tvar shift = ( typeof element === \"string\" || element === null ),\n\t\t\toptions = {\n\t\t\t\textra: shift ? keys : extra,\n\t\t\t\tkeys: shift ? element : keys,\n\t\t\t\telement: shift ? this.element : element,\n\t\t\t\tadd: add\n\t\t\t};\n\t\toptions.element.toggleClass( this._classes( options ), add );\n\t\treturn this;\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement;\n\t\tvar instance = this;\n\n\t\t// No suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// No element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\n\t\t\t\t// Allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck &&\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// Copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^([\\w:-]*)\\s*(.*)$/ );\n\t\t\tvar eventName = match[ 1 ] + instance.eventNamespace;\n\t\t\tvar selector = match[ 2 ];\n\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.on( eventName, selector, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.on( eventName, handlerProxy );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = ( eventName || \"\" ).split( \" \" ).join( this.eventNamespace + \" \" ) +\n\t\t\tthis.eventNamespace;\n\t\telement.off( eventName ).off( eventName );\n\n\t\t// Clear the stack to avoid memory leaks (#10056)\n\t\tthis.bindings = $( this.bindings.not( element ).get() );\n\t\tthis.focusable = $( this.focusable.not( element ).get() );\n\t\tthis.hoverable = $( this.hoverable.not( element ).get() );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\tthis._addClass( $( event.currentTarget ), null, \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\tthis._removeClass( $( event.currentTarget ), null, \"ui-state-hover\" );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\tthis._addClass( $( event.currentTarget ), null, \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\tthis._removeClass( $( event.currentTarget ), null, \"ui-state-focus\" );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig;\n\t\tvar callback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\n\t\t// The original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// Copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( $.isFunction( callback ) &&\n\t\t\tcallback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\n\t\tvar hasOptions;\n\t\tvar effectName = !options ?\n\t\t\tmethod :\n\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\tdefaultEffect :\n\t\t\t\toptions.effect || defaultEffect;\n\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t}\n\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\n\t\tif ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method && element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue( function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t} );\n\t\t}\n\t};\n} );\n\nreturn $.widget;\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/widgets/autocomplete.js",
    "content": "//= require rails_admin/jquery-ui/widgets/menu\n//= require rails_admin/jquery-ui/keycode\n//= require rails_admin/jquery-ui/position\n//= require rails_admin/jquery-ui/safe-active-element\n//= require rails_admin/jquery-ui/version\n//= require rails_admin/jquery-ui/widget\n\n/*!\n * jQuery UI Autocomplete 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Autocomplete\n//>>group: Widgets\n//>>description: Lists suggested words as the user is typing.\n//>>docs: http://api.jqueryui.com/autocomplete/\n//>>demos: http://jqueryui.com/autocomplete/\n//>>css.structure: ../../themes/base/core.css\n//>>css.structure: ../../themes/base/autocomplete.css\n//>>css.theme: ../../themes/base/theme.css\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [\n\t\t\t\"jquery\",\n\t\t\t\"./menu\",\n\t\t\t\"../keycode\",\n\t\t\t\"../position\",\n\t\t\t\"../safe-active-element\",\n\t\t\t\"../version\",\n\t\t\t\"../widget\"\n\t\t], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}( function( $ ) {\n\n$.widget( \"ui.autocomplete\", {\n\tversion: \"1.12.1\",\n\tdefaultElement: \"<input>\",\n\toptions: {\n\t\tappendTo: null,\n\t\tautoFocus: false,\n\t\tdelay: 300,\n\t\tminLength: 1,\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"none\"\n\t\t},\n\t\tsource: null,\n\n\t\t// Callbacks\n\t\tchange: null,\n\t\tclose: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tresponse: null,\n\t\tsearch: null,\n\t\tselect: null\n\t},\n\n\trequestIndex: 0,\n\tpending: 0,\n\n\t_create: function() {\n\n\t\t// Some browsers only repeat keydown events, not keypress events,\n\t\t// so we use the suppressKeyPress flag to determine if we've already\n\t\t// handled the keydown event. #7269\n\t\t// Unfortunately the code for & in keypress is the same as the up arrow,\n\t\t// so we use the suppressKeyPressRepeat flag to avoid handling keypress\n\t\t// events when we know the keydown event was used to modify the\n\t\t// search term. #7799\n\t\tvar suppressKeyPress, suppressKeyPressRepeat, suppressInput,\n\t\t\tnodeName = this.element[ 0 ].nodeName.toLowerCase(),\n\t\t\tisTextarea = nodeName === \"textarea\",\n\t\t\tisInput = nodeName === \"input\";\n\n\t\t// Textareas are always multi-line\n\t\t// Inputs are always single-line, even if inside a contentEditable element\n\t\t// IE also treats inputs as contentEditable\n\t\t// All other element types are determined by whether or not they're contentEditable\n\t\tthis.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );\n\n\t\tthis.valueMethod = this.element[ isTextarea || isInput ? \"val\" : \"text\" ];\n\t\tthis.isNewMenu = true;\n\n\t\tthis._addClass( \"ui-autocomplete-input\" );\n\t\tthis.element.attr( \"autocomplete\", \"off\" );\n\n\t\tthis._on( this.element, {\n\t\t\tkeydown: function( event ) {\n\t\t\t\tif ( this.element.prop( \"readOnly\" ) ) {\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tsuppressInput = true;\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsuppressKeyPress = false;\n\t\t\t\tsuppressInput = false;\n\t\t\t\tsuppressKeyPressRepeat = false;\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ENTER:\n\n\t\t\t\t\t// when menu is open and has focus\n\t\t\t\t\tif ( this.menu.active ) {\n\n\t\t\t\t\t\t// #6055 - Opera still allows the keypress to occur\n\t\t\t\t\t\t// which causes forms to submit\n\t\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.TAB:\n\t\t\t\t\tif ( this.menu.active ) {\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ESCAPE:\n\t\t\t\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\t\t\t\tif ( !this.isMultiLine ) {\n\t\t\t\t\t\t\tthis._value( this.term );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.close( event );\n\n\t\t\t\t\t\t// Different browsers have different default behavior for escape\n\t\t\t\t\t\t// Single press can mean undo or clear\n\t\t\t\t\t\t// Double press in IE means clear the whole form\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\n\t\t\t\t\t// search timeout should be triggered before the input value is changed\n\t\t\t\t\tthis._searchTimeout( event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tkeypress: function( event ) {\n\t\t\t\tif ( suppressKeyPress ) {\n\t\t\t\t\tsuppressKeyPress = false;\n\t\t\t\t\tif ( !this.isMultiLine || this.menu.element.is( \":visible\" ) ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( suppressKeyPressRepeat ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Replicate some key handlers to allow them to repeat in Firefox and Opera\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tinput: function( event ) {\n\t\t\t\tif ( suppressInput ) {\n\t\t\t\t\tsuppressInput = false;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._searchTimeout( event );\n\t\t\t},\n\t\t\tfocus: function() {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.previous = this._value();\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tif ( this.cancelBlur ) {\n\t\t\t\t\tdelete this.cancelBlur;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tclearTimeout( this.searching );\n\t\t\t\tthis.close( event );\n\t\t\t\tthis._change( event );\n\t\t\t}\n\t\t} );\n\n\t\tthis._initSource();\n\t\tthis.menu = $( \"<ul>\" )\n\t\t\t.appendTo( this._appendTo() )\n\t\t\t.menu( {\n\n\t\t\t\t// disable ARIA support, the live region takes care of that\n\t\t\t\trole: null\n\t\t\t} )\n\t\t\t.hide()\n\t\t\t.menu( \"instance\" );\n\n\t\tthis._addClass( this.menu.element, \"ui-autocomplete\", \"ui-front\" );\n\t\tthis._on( this.menu.element, {\n\t\t\tmousedown: function( event ) {\n\n\t\t\t\t// prevent moving focus out of the text field\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\t// IE doesn't prevent moving focus even with event.preventDefault()\n\t\t\t\t// so we set a flag to know when we should ignore the blur event\n\t\t\t\tthis.cancelBlur = true;\n\t\t\t\tthis._delay( function() {\n\t\t\t\t\tdelete this.cancelBlur;\n\n\t\t\t\t\t// Support: IE 8 only\n\t\t\t\t\t// Right clicking a menu item or selecting text from the menu items will\n\t\t\t\t\t// result in focus moving out of the input. However, we've already received\n\t\t\t\t\t// and ignored the blur event because of the cancelBlur flag set above. So\n\t\t\t\t\t// we restore focus to ensure that the menu closes properly based on the user's\n\t\t\t\t\t// next actions.\n\t\t\t\t\tif ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {\n\t\t\t\t\t\tthis.element.trigger( \"focus\" );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t},\n\t\t\tmenufocus: function( event, ui ) {\n\t\t\t\tvar label, item;\n\n\t\t\t\t// support: Firefox\n\t\t\t\t// Prevent accidental activation of menu items in Firefox (#7024 #9118)\n\t\t\t\tif ( this.isNewMenu ) {\n\t\t\t\t\tthis.isNewMenu = false;\n\t\t\t\t\tif ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis.menu.blur();\n\n\t\t\t\t\t\tthis.document.one( \"mousemove\", function() {\n\t\t\t\t\t\t\t$( event.target ).trigger( event.originalEvent );\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\titem = ui.item.data( \"ui-autocomplete-item\" );\n\t\t\t\tif ( false !== this._trigger( \"focus\", event, { item: item } ) ) {\n\n\t\t\t\t\t// use value to match what will end up in the input, if it was a key event\n\t\t\t\t\tif ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis._value( item.value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Announce the value in the liveRegion\n\t\t\t\tlabel = ui.item.attr( \"aria-label\" ) || item.value;\n\t\t\t\tif ( label && $.trim( label ).length ) {\n\t\t\t\t\tthis.liveRegion.children().hide();\n\t\t\t\t\t$( \"<div>\" ).text( label ).appendTo( this.liveRegion );\n\t\t\t\t}\n\t\t\t},\n\t\t\tmenuselect: function( event, ui ) {\n\t\t\t\tvar item = ui.item.data( \"ui-autocomplete-item\" ),\n\t\t\t\t\tprevious = this.previous;\n\n\t\t\t\t// Only trigger when focus was lost (click on menu)\n\t\t\t\tif ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {\n\t\t\t\t\tthis.element.trigger( \"focus\" );\n\t\t\t\t\tthis.previous = previous;\n\n\t\t\t\t\t// #6109 - IE triggers two focus events and the second\n\t\t\t\t\t// is asynchronous, so we need to reset the previous\n\t\t\t\t\t// term synchronously and asynchronously :-(\n\t\t\t\t\tthis._delay( function() {\n\t\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t\tthis.selectedItem = item;\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tif ( false !== this._trigger( \"select\", event, { item: item } ) ) {\n\t\t\t\t\tthis._value( item.value );\n\t\t\t\t}\n\n\t\t\t\t// reset the term after the select event\n\t\t\t\t// this allows custom select handling to work properly\n\t\t\t\tthis.term = this._value();\n\n\t\t\t\tthis.close( event );\n\t\t\t\tthis.selectedItem = item;\n\t\t\t}\n\t\t} );\n\n\t\tthis.liveRegion = $( \"<div>\", {\n\t\t\trole: \"status\",\n\t\t\t\"aria-live\": \"assertive\",\n\t\t\t\"aria-relevant\": \"additions\"\n\t\t} )\n\t\t\t.appendTo( this.document[ 0 ].body );\n\n\t\tthis._addClass( this.liveRegion, null, \"ui-helper-hidden-accessible\" );\n\n\t\t// Turning off autocomplete prevents the browser from remembering the\n\t\t// value when navigating through history, so we re-enable autocomplete\n\t\t// if the page is unloaded before the widget is destroyed. #7790\n\t\tthis._on( this.window, {\n\t\t\tbeforeunload: function() {\n\t\t\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_destroy: function() {\n\t\tclearTimeout( this.searching );\n\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\tthis.menu.element.remove();\n\t\tthis.liveRegion.remove();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"source\" ) {\n\t\t\tthis._initSource();\n\t\t}\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.menu.element.appendTo( this._appendTo() );\n\t\t}\n\t\tif ( key === \"disabled\" && value && this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\t},\n\n\t_isEventTargetInWidget: function( event ) {\n\t\tvar menuElement = this.menu.element[ 0 ];\n\n\t\treturn event.target === this.element[ 0 ] ||\n\t\t\tevent.target === menuElement ||\n\t\t\t$.contains( menuElement, event.target );\n\t},\n\n\t_closeOnClickOutside: function( event ) {\n\t\tif ( !this._isEventTargetInWidget( event ) ) {\n\t\t\tthis.close();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\n\t\tif ( element ) {\n\t\t\telement = element.jquery || element.nodeType ?\n\t\t\t\t$( element ) :\n\t\t\t\tthis.document.find( element ).eq( 0 );\n\t\t}\n\n\t\tif ( !element || !element[ 0 ] ) {\n\t\t\telement = this.element.closest( \".ui-front, dialog\" );\n\t\t}\n\n\t\tif ( !element.length ) {\n\t\t\telement = this.document[ 0 ].body;\n\t\t}\n\n\t\treturn element;\n\t},\n\n\t_initSource: function() {\n\t\tvar array, url,\n\t\t\tthat = this;\n\t\tif ( $.isArray( this.options.source ) ) {\n\t\t\tarray = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tresponse( $.ui.autocomplete.filter( array, request.term ) );\n\t\t\t};\n\t\t} else if ( typeof this.options.source === \"string\" ) {\n\t\t\turl = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tif ( that.xhr ) {\n\t\t\t\t\tthat.xhr.abort();\n\t\t\t\t}\n\t\t\t\tthat.xhr = $.ajax( {\n\t\t\t\t\turl: url,\n\t\t\t\t\tdata: request,\n\t\t\t\t\tdataType: \"json\",\n\t\t\t\t\tsuccess: function( data ) {\n\t\t\t\t\t\tresponse( data );\n\t\t\t\t\t},\n\t\t\t\t\terror: function() {\n\t\t\t\t\t\tresponse( [] );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t};\n\t\t} else {\n\t\t\tthis.source = this.options.source;\n\t\t}\n\t},\n\n\t_searchTimeout: function( event ) {\n\t\tclearTimeout( this.searching );\n\t\tthis.searching = this._delay( function() {\n\n\t\t\t// Search if the value has changed, or if the user retypes the same value (see #7434)\n\t\t\tvar equalValues = this.term === this._value(),\n\t\t\t\tmenuVisible = this.menu.element.is( \":visible\" ),\n\t\t\t\tmodifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n\n\t\t\tif ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.search( null, event );\n\t\t\t}\n\t\t}, this.options.delay );\n\t},\n\n\tsearch: function( value, event ) {\n\t\tvalue = value != null ? value : this._value();\n\n\t\t// Always save the actual value, not the one passed as an argument\n\t\tthis.term = this._value();\n\n\t\tif ( value.length < this.options.minLength ) {\n\t\t\treturn this.close( event );\n\t\t}\n\n\t\tif ( this._trigger( \"search\", event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._search( value );\n\t},\n\n\t_search: function( value ) {\n\t\tthis.pending++;\n\t\tthis._addClass( \"ui-autocomplete-loading\" );\n\t\tthis.cancelSearch = false;\n\n\t\tthis.source( { term: value }, this._response() );\n\t},\n\n\t_response: function() {\n\t\tvar index = ++this.requestIndex;\n\n\t\treturn $.proxy( function( content ) {\n\t\t\tif ( index === this.requestIndex ) {\n\t\t\t\tthis.__response( content );\n\t\t\t}\n\n\t\t\tthis.pending--;\n\t\t\tif ( !this.pending ) {\n\t\t\t\tthis._removeClass( \"ui-autocomplete-loading\" );\n\t\t\t}\n\t\t}, this );\n\t},\n\n\t__response: function( content ) {\n\t\tif ( content ) {\n\t\t\tcontent = this._normalize( content );\n\t\t}\n\t\tthis._trigger( \"response\", null, { content: content } );\n\t\tif ( !this.options.disabled && content && content.length && !this.cancelSearch ) {\n\t\t\tthis._suggest( content );\n\t\t\tthis._trigger( \"open\" );\n\t\t} else {\n\n\t\t\t// use ._close() instead of .close() so we don't cancel future searches\n\t\t\tthis._close();\n\t\t}\n\t},\n\n\tclose: function( event ) {\n\t\tthis.cancelSearch = true;\n\t\tthis._close( event );\n\t},\n\n\t_close: function( event ) {\n\n\t\t// Remove the handler that closes the menu on outside clicks\n\t\tthis._off( this.document, \"mousedown\" );\n\n\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.menu.element.hide();\n\t\t\tthis.menu.blur();\n\t\t\tthis.isNewMenu = true;\n\t\t\tthis._trigger( \"close\", event );\n\t\t}\n\t},\n\n\t_change: function( event ) {\n\t\tif ( this.previous !== this._value() ) {\n\t\t\tthis._trigger( \"change\", event, { item: this.selectedItem } );\n\t\t}\n\t},\n\n\t_normalize: function( items ) {\n\n\t\t// assume all items have the right format when the first item is complete\n\t\tif ( items.length && items[ 0 ].label && items[ 0 ].value ) {\n\t\t\treturn items;\n\t\t}\n\t\treturn $.map( items, function( item ) {\n\t\t\tif ( typeof item === \"string\" ) {\n\t\t\t\treturn {\n\t\t\t\t\tlabel: item,\n\t\t\t\t\tvalue: item\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn $.extend( {}, item, {\n\t\t\t\tlabel: item.label || item.value,\n\t\t\t\tvalue: item.value || item.label\n\t\t\t} );\n\t\t} );\n\t},\n\n\t_suggest: function( items ) {\n\t\tvar ul = this.menu.element.empty();\n\t\tthis._renderMenu( ul, items );\n\t\tthis.isNewMenu = true;\n\t\tthis.menu.refresh();\n\n\t\t// Size and position menu\n\t\tul.show();\n\t\tthis._resizeMenu();\n\t\tul.position( $.extend( {\n\t\t\tof: this.element\n\t\t}, this.options.position ) );\n\n\t\tif ( this.options.autoFocus ) {\n\t\t\tthis.menu.next();\n\t\t}\n\n\t\t// Listen for interactions outside of the widget (#6642)\n\t\tthis._on( this.document, {\n\t\t\tmousedown: \"_closeOnClickOutside\"\n\t\t} );\n\t},\n\n\t_resizeMenu: function() {\n\t\tvar ul = this.menu.element;\n\t\tul.outerWidth( Math.max(\n\n\t\t\t// Firefox wraps long text (possibly a rounding bug)\n\t\t\t// so we add 1px to avoid the wrapping (#7513)\n\t\t\tul.width( \"\" ).outerWidth() + 1,\n\t\t\tthis.element.outerWidth()\n\t\t) );\n\t},\n\n\t_renderMenu: function( ul, items ) {\n\t\tvar that = this;\n\t\t$.each( items, function( index, item ) {\n\t\t\tthat._renderItemData( ul, item );\n\t\t} );\n\t},\n\n\t_renderItemData: function( ul, item ) {\n\t\treturn this._renderItem( ul, item ).data( \"ui-autocomplete-item\", item );\n\t},\n\n\t_renderItem: function( ul, item ) {\n\t\treturn $( \"<li>\" )\n\t\t\t.append( $( \"<div>\" ).text( item.label ) )\n\t\t\t.appendTo( ul );\n\t},\n\n\t_move: function( direction, event ) {\n\t\tif ( !this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.search( null, event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.menu.isFirstItem() && /^previous/.test( direction ) ||\n\t\t\t\tthis.menu.isLastItem() && /^next/.test( direction ) ) {\n\n\t\t\tif ( !this.isMultiLine ) {\n\t\t\t\tthis._value( this.term );\n\t\t\t}\n\n\t\t\tthis.menu.blur();\n\t\t\treturn;\n\t\t}\n\t\tthis.menu[ direction ]( event );\n\t},\n\n\twidget: function() {\n\t\treturn this.menu.element;\n\t},\n\n\t_value: function() {\n\t\treturn this.valueMethod.apply( this.element, arguments );\n\t},\n\n\t_keyEvent: function( keyEvent, event ) {\n\t\tif ( !this.isMultiLine || this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis._move( keyEvent, event );\n\n\t\t\t// Prevents moving cursor to beginning/end of the text field in some browsers\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t// Support: Chrome <=50\n\t// We should be able to just use this.element.prop( \"isContentEditable\" )\n\t// but hidden elements always report false in Chrome.\n\t// https://code.google.com/p/chromium/issues/detail?id=313082\n\t_isContentEditable: function( element ) {\n\t\tif ( !element.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar editable = element.prop( \"contentEditable\" );\n\n\t\tif ( editable === \"inherit\" ) {\n\t\t  return this._isContentEditable( element.parent() );\n\t\t}\n\n\t\treturn editable === \"true\";\n\t}\n} );\n\n$.extend( $.ui.autocomplete, {\n\tescapeRegex: function( value ) {\n\t\treturn value.replace( /[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$&\" );\n\t},\n\tfilter: function( array, term ) {\n\t\tvar matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), \"i\" );\n\t\treturn $.grep( array, function( value ) {\n\t\t\treturn matcher.test( value.label || value.value || value );\n\t\t} );\n\t}\n} );\n\n// Live region extension, adding a `messages` option\n// NOTE: This is an experimental API. We are still investigating\n// a full solution for string manipulation and internationalization.\n$.widget( \"ui.autocomplete\", $.ui.autocomplete, {\n\toptions: {\n\t\tmessages: {\n\t\t\tnoResults: \"No search results.\",\n\t\t\tresults: function( amount ) {\n\t\t\t\treturn amount + ( amount > 1 ? \" results are\" : \" result is\" ) +\n\t\t\t\t\t\" available, use up and down arrow keys to navigate.\";\n\t\t\t}\n\t\t}\n\t},\n\n\t__response: function( content ) {\n\t\tvar message;\n\t\tthis._superApply( arguments );\n\t\tif ( this.options.disabled || this.cancelSearch ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( content && content.length ) {\n\t\t\tmessage = this.options.messages.results( content.length );\n\t\t} else {\n\t\t\tmessage = this.options.messages.noResults;\n\t\t}\n\t\tthis.liveRegion.children().hide();\n\t\t$( \"<div>\" ).text( message ).appendTo( this.liveRegion );\n\t}\n} );\n\nreturn $.ui.autocomplete;\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/widgets/menu.js",
    "content": "//= require rails_admin/jquery-ui/keycode\n//= require rails_admin/jquery-ui/position\n//= require rails_admin/jquery-ui/safe-active-element\n//= require rails_admin/jquery-ui/unique-id\n//= require rails_admin/jquery-ui/version\n//= require rails_admin/jquery-ui/widget\n\n/*!\n * jQuery UI Menu 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Menu\n//>>group: Widgets\n//>>description: Creates nestable menus.\n//>>docs: http://api.jqueryui.com/menu/\n//>>demos: http://jqueryui.com/menu/\n//>>css.structure: ../../themes/base/core.css\n//>>css.structure: ../../themes/base/menu.css\n//>>css.theme: ../../themes/base/theme.css\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [\n\t\t\t\"jquery\",\n\t\t\t\"../keycode\",\n\t\t\t\"../position\",\n\t\t\t\"../safe-active-element\",\n\t\t\t\"../unique-id\",\n\t\t\t\"../version\",\n\t\t\t\"../widget\"\n\t\t], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}( function( $ ) {\n\nreturn $.widget( \"ui.menu\", {\n\tversion: \"1.12.1\",\n\tdefaultElement: \"<ul>\",\n\tdelay: 300,\n\toptions: {\n\t\ticons: {\n\t\t\tsubmenu: \"ui-icon-caret-1-e\"\n\t\t},\n\t\titems: \"> *\",\n\t\tmenus: \"ul\",\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"right top\"\n\t\t},\n\t\trole: \"menu\",\n\n\t\t// Callbacks\n\t\tblur: null,\n\t\tfocus: null,\n\t\tselect: null\n\t},\n\n\t_create: function() {\n\t\tthis.activeMenu = this.element;\n\n\t\t// Flag used to prevent firing of the click handler\n\t\t// as the event bubbles up through nested menus\n\t\tthis.mouseHandled = false;\n\t\tthis.element\n\t\t\t.uniqueId()\n\t\t\t.attr( {\n\t\t\t\trole: this.options.role,\n\t\t\t\ttabIndex: 0\n\t\t\t} );\n\n\t\tthis._addClass( \"ui-menu\", \"ui-widget ui-widget-content\" );\n\t\tthis._on( {\n\n\t\t\t// Prevent focus from sticking to links inside menu after clicking\n\t\t\t// them (focus should always stay on UL during navigation).\n\t\t\t\"mousedown .ui-menu-item\": function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\t\"click .ui-menu-item\": function( event ) {\n\t\t\t\tvar target = $( event.target );\n\t\t\t\tvar active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );\n\t\t\t\tif ( !this.mouseHandled && target.not( \".ui-state-disabled\" ).length ) {\n\t\t\t\t\tthis.select( event );\n\n\t\t\t\t\t// Only set the mouseHandled flag if the event will bubble, see #9469.\n\t\t\t\t\tif ( !event.isPropagationStopped() ) {\n\t\t\t\t\t\tthis.mouseHandled = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Open submenu on click\n\t\t\t\t\tif ( target.has( \".ui-menu\" ).length ) {\n\t\t\t\t\t\tthis.expand( event );\n\t\t\t\t\t} else if ( !this.element.is( \":focus\" ) &&\n\t\t\t\t\t\t\tactive.closest( \".ui-menu\" ).length ) {\n\n\t\t\t\t\t\t// Redirect focus to the menu\n\t\t\t\t\t\tthis.element.trigger( \"focus\", [ true ] );\n\n\t\t\t\t\t\t// If the active item is on the top level, let it stay active.\n\t\t\t\t\t\t// Otherwise, blur the active item since it is no longer visible.\n\t\t\t\t\t\tif ( this.active && this.active.parents( \".ui-menu\" ).length === 1 ) {\n\t\t\t\t\t\t\tclearTimeout( this.timer );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"mouseenter .ui-menu-item\": function( event ) {\n\n\t\t\t\t// Ignore mouse events while typeahead is active, see #10458.\n\t\t\t\t// Prevents focusing the wrong item when typeahead causes a scroll while the mouse\n\t\t\t\t// is over an item in the menu\n\t\t\t\tif ( this.previousFilter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar actualTarget = $( event.target ).closest( \".ui-menu-item\" ),\n\t\t\t\t\ttarget = $( event.currentTarget );\n\n\t\t\t\t// Ignore bubbled events on parent items, see #11641\n\t\t\t\tif ( actualTarget[ 0 ] !== target[ 0 ] ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Remove ui-state-active class from siblings of the newly focused menu item\n\t\t\t\t// to avoid a jump caused by adjacent elements both having a class with a border\n\t\t\t\tthis._removeClass( target.siblings().children( \".ui-state-active\" ),\n\t\t\t\t\tnull, \"ui-state-active\" );\n\t\t\t\tthis.focus( event, target );\n\t\t\t},\n\t\t\tmouseleave: \"collapseAll\",\n\t\t\t\"mouseleave .ui-menu\": \"collapseAll\",\n\t\t\tfocus: function( event, keepActiveItem ) {\n\n\t\t\t\t// If there's already an active item, keep it active\n\t\t\t\t// If not, activate the first item\n\t\t\t\tvar item = this.active || this.element.find( this.options.items ).eq( 0 );\n\n\t\t\t\tif ( !keepActiveItem ) {\n\t\t\t\t\tthis.focus( event, item );\n\t\t\t\t}\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tthis._delay( function() {\n\t\t\t\t\tvar notContained = !$.contains(\n\t\t\t\t\t\tthis.element[ 0 ],\n\t\t\t\t\t\t$.ui.safeActiveElement( this.document[ 0 ] )\n\t\t\t\t\t);\n\t\t\t\t\tif ( notContained ) {\n\t\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t},\n\t\t\tkeydown: \"_keydown\"\n\t\t} );\n\n\t\tthis.refresh();\n\n\t\t// Clicks outside of a menu collapse any open menus\n\t\tthis._on( this.document, {\n\t\t\tclick: function( event ) {\n\t\t\t\tif ( this._closeOnDocumentClick( event ) ) {\n\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t}\n\n\t\t\t\t// Reset the mouseHandled flag\n\t\t\t\tthis.mouseHandled = false;\n\t\t\t}\n\t\t} );\n\t},\n\n\t_destroy: function() {\n\t\tvar items = this.element.find( \".ui-menu-item\" )\n\t\t\t\t.removeAttr( \"role aria-disabled\" ),\n\t\t\tsubmenus = items.children( \".ui-menu-item-wrapper\" )\n\t\t\t\t.removeUniqueId()\n\t\t\t\t.removeAttr( \"tabIndex role aria-haspopup\" );\n\n\t\t// Destroy (sub)menus\n\t\tthis.element\n\t\t\t.removeAttr( \"aria-activedescendant\" )\n\t\t\t.find( \".ui-menu\" ).addBack()\n\t\t\t\t.removeAttr( \"role aria-labelledby aria-expanded aria-hidden aria-disabled \" +\n\t\t\t\t\t\"tabIndex\" )\n\t\t\t\t.removeUniqueId()\n\t\t\t\t.show();\n\n\t\tsubmenus.children().each( function() {\n\t\t\tvar elem = $( this );\n\t\t\tif ( elem.data( \"ui-menu-submenu-caret\" ) ) {\n\t\t\t\telem.remove();\n\t\t\t}\n\t\t} );\n\t},\n\n\t_keydown: function( event ) {\n\t\tvar match, prev, character, skip,\n\t\t\tpreventDefault = true;\n\n\t\tswitch ( event.keyCode ) {\n\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\tthis.previousPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\tthis.nextPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.HOME:\n\t\t\tthis._move( \"first\", \"first\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.END:\n\t\t\tthis._move( \"last\", \"last\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.UP:\n\t\t\tthis.previous( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.DOWN:\n\t\t\tthis.next( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.LEFT:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.RIGHT:\n\t\t\tif ( this.active && !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\t\tthis.expand( event );\n\t\t\t}\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ENTER:\n\t\tcase $.ui.keyCode.SPACE:\n\t\t\tthis._activate( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ESCAPE:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tpreventDefault = false;\n\t\t\tprev = this.previousFilter || \"\";\n\t\t\tskip = false;\n\n\t\t\t// Support number pad values\n\t\t\tcharacter = event.keyCode >= 96 && event.keyCode <= 105 ?\n\t\t\t\t( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );\n\n\t\t\tclearTimeout( this.filterTimer );\n\n\t\t\tif ( character === prev ) {\n\t\t\t\tskip = true;\n\t\t\t} else {\n\t\t\t\tcharacter = prev + character;\n\t\t\t}\n\n\t\t\tmatch = this._filterMenuItems( character );\n\t\t\tmatch = skip && match.index( this.active.next() ) !== -1 ?\n\t\t\t\tthis.active.nextAll( \".ui-menu-item\" ) :\n\t\t\t\tmatch;\n\n\t\t\t// If no matches on the current filter, reset to the last character pressed\n\t\t\t// to move down the menu to the first item that starts with that character\n\t\t\tif ( !match.length ) {\n\t\t\t\tcharacter = String.fromCharCode( event.keyCode );\n\t\t\t\tmatch = this._filterMenuItems( character );\n\t\t\t}\n\n\t\t\tif ( match.length ) {\n\t\t\t\tthis.focus( event, match );\n\t\t\t\tthis.previousFilter = character;\n\t\t\t\tthis.filterTimer = this._delay( function() {\n\t\t\t\t\tdelete this.previousFilter;\n\t\t\t\t}, 1000 );\n\t\t\t} else {\n\t\t\t\tdelete this.previousFilter;\n\t\t\t}\n\t\t}\n\n\t\tif ( preventDefault ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t_activate: function( event ) {\n\t\tif ( this.active && !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\tif ( this.active.children( \"[aria-haspopup='true']\" ).length ) {\n\t\t\t\tthis.expand( event );\n\t\t\t} else {\n\t\t\t\tthis.select( event );\n\t\t\t}\n\t\t}\n\t},\n\n\trefresh: function() {\n\t\tvar menus, items, newSubmenus, newItems, newWrappers,\n\t\t\tthat = this,\n\t\t\ticon = this.options.icons.submenu,\n\t\t\tsubmenus = this.element.find( this.options.menus );\n\n\t\tthis._toggleClass( \"ui-menu-icons\", null, !!this.element.find( \".ui-icon\" ).length );\n\n\t\t// Initialize nested menus\n\t\tnewSubmenus = submenus.filter( \":not(.ui-menu)\" )\n\t\t\t.hide()\n\t\t\t.attr( {\n\t\t\t\trole: this.options.role,\n\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\t\"aria-expanded\": \"false\"\n\t\t\t} )\n\t\t\t.each( function() {\n\t\t\t\tvar menu = $( this ),\n\t\t\t\t\titem = menu.prev(),\n\t\t\t\t\tsubmenuCaret = $( \"<span>\" ).data( \"ui-menu-submenu-caret\", true );\n\n\t\t\t\tthat._addClass( submenuCaret, \"ui-menu-icon\", \"ui-icon \" + icon );\n\t\t\t\titem\n\t\t\t\t\t.attr( \"aria-haspopup\", \"true\" )\n\t\t\t\t\t.prepend( submenuCaret );\n\t\t\t\tmenu.attr( \"aria-labelledby\", item.attr( \"id\" ) );\n\t\t\t} );\n\n\t\tthis._addClass( newSubmenus, \"ui-menu\", \"ui-widget ui-widget-content ui-front\" );\n\n\t\tmenus = submenus.add( this.element );\n\t\titems = menus.find( this.options.items );\n\n\t\t// Initialize menu-items containing spaces and/or dashes only as dividers\n\t\titems.not( \".ui-menu-item\" ).each( function() {\n\t\t\tvar item = $( this );\n\t\t\tif ( that._isDivider( item ) ) {\n\t\t\t\tthat._addClass( item, \"ui-menu-divider\", \"ui-widget-content\" );\n\t\t\t}\n\t\t} );\n\n\t\t// Don't refresh list items that are already adapted\n\t\tnewItems = items.not( \".ui-menu-item, .ui-menu-divider\" );\n\t\tnewWrappers = newItems.children()\n\t\t\t.not( \".ui-menu\" )\n\t\t\t\t.uniqueId()\n\t\t\t\t.attr( {\n\t\t\t\t\ttabIndex: -1,\n\t\t\t\t\trole: this._itemRole()\n\t\t\t\t} );\n\t\tthis._addClass( newItems, \"ui-menu-item\" )\n\t\t\t._addClass( newWrappers, \"ui-menu-item-wrapper\" );\n\n\t\t// Add aria-disabled attribute to any disabled menu item\n\t\titems.filter( \".ui-state-disabled\" ).attr( \"aria-disabled\", \"true\" );\n\n\t\t// If the active item has been removed, blur the menu\n\t\tif ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {\n\t\t\tthis.blur();\n\t\t}\n\t},\n\n\t_itemRole: function() {\n\t\treturn {\n\t\t\tmenu: \"menuitem\",\n\t\t\tlistbox: \"option\"\n\t\t}[ this.options.role ];\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"icons\" ) {\n\t\t\tvar icons = this.element.find( \".ui-menu-icon\" );\n\t\t\tthis._removeClass( icons, null, this.options.icons.submenu )\n\t\t\t\t._addClass( icons, null, value.submenu );\n\t\t}\n\t\tthis._super( key, value );\n\t},\n\n\t_setOptionDisabled: function( value ) {\n\t\tthis._super( value );\n\n\t\tthis.element.attr( \"aria-disabled\", String( value ) );\n\t\tthis._toggleClass( null, \"ui-state-disabled\", !!value );\n\t},\n\n\tfocus: function( event, item ) {\n\t\tvar nested, focused, activeParent;\n\t\tthis.blur( event, event && event.type === \"focus\" );\n\n\t\tthis._scrollIntoView( item );\n\n\t\tthis.active = item.first();\n\n\t\tfocused = this.active.children( \".ui-menu-item-wrapper\" );\n\t\tthis._addClass( focused, null, \"ui-state-active\" );\n\n\t\t// Only update aria-activedescendant if there's a role\n\t\t// otherwise we assume focus is managed elsewhere\n\t\tif ( this.options.role ) {\n\t\t\tthis.element.attr( \"aria-activedescendant\", focused.attr( \"id\" ) );\n\t\t}\n\n\t\t// Highlight active parent menu item, if any\n\t\tactiveParent = this.active\n\t\t\t.parent()\n\t\t\t\t.closest( \".ui-menu-item\" )\n\t\t\t\t\t.children( \".ui-menu-item-wrapper\" );\n\t\tthis._addClass( activeParent, null, \"ui-state-active\" );\n\n\t\tif ( event && event.type === \"keydown\" ) {\n\t\t\tthis._close();\n\t\t} else {\n\t\t\tthis.timer = this._delay( function() {\n\t\t\t\tthis._close();\n\t\t\t}, this.delay );\n\t\t}\n\n\t\tnested = item.children( \".ui-menu\" );\n\t\tif ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {\n\t\t\tthis._startOpening( nested );\n\t\t}\n\t\tthis.activeMenu = item.parent();\n\n\t\tthis._trigger( \"focus\", event, { item: item } );\n\t},\n\n\t_scrollIntoView: function( item ) {\n\t\tvar borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;\n\t\tif ( this._hasScroll() ) {\n\t\t\tborderTop = parseFloat( $.css( this.activeMenu[ 0 ], \"borderTopWidth\" ) ) || 0;\n\t\t\tpaddingTop = parseFloat( $.css( this.activeMenu[ 0 ], \"paddingTop\" ) ) || 0;\n\t\t\toffset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;\n\t\t\tscroll = this.activeMenu.scrollTop();\n\t\t\telementHeight = this.activeMenu.height();\n\t\t\titemHeight = item.outerHeight();\n\n\t\t\tif ( offset < 0 ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset );\n\t\t\t} else if ( offset + itemHeight > elementHeight ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );\n\t\t\t}\n\t\t}\n\t},\n\n\tblur: function( event, fromFocus ) {\n\t\tif ( !fromFocus ) {\n\t\t\tclearTimeout( this.timer );\n\t\t}\n\n\t\tif ( !this.active ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._removeClass( this.active.children( \".ui-menu-item-wrapper\" ),\n\t\t\tnull, \"ui-state-active\" );\n\n\t\tthis._trigger( \"blur\", event, { item: this.active } );\n\t\tthis.active = null;\n\t},\n\n\t_startOpening: function( submenu ) {\n\t\tclearTimeout( this.timer );\n\n\t\t// Don't open if already open fixes a Firefox bug that caused a .5 pixel\n\t\t// shift in the submenu position when mousing over the caret icon\n\t\tif ( submenu.attr( \"aria-hidden\" ) !== \"true\" ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timer = this._delay( function() {\n\t\t\tthis._close();\n\t\t\tthis._open( submenu );\n\t\t}, this.delay );\n\t},\n\n\t_open: function( submenu ) {\n\t\tvar position = $.extend( {\n\t\t\tof: this.active\n\t\t}, this.options.position );\n\n\t\tclearTimeout( this.timer );\n\t\tthis.element.find( \".ui-menu\" ).not( submenu.parents( \".ui-menu\" ) )\n\t\t\t.hide()\n\t\t\t.attr( \"aria-hidden\", \"true\" );\n\n\t\tsubmenu\n\t\t\t.show()\n\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t.attr( \"aria-expanded\", \"true\" )\n\t\t\t.position( position );\n\t},\n\n\tcollapseAll: function( event, all ) {\n\t\tclearTimeout( this.timer );\n\t\tthis.timer = this._delay( function() {\n\n\t\t\t// If we were passed an event, look for the submenu that contains the event\n\t\t\tvar currentMenu = all ? this.element :\n\t\t\t\t$( event && event.target ).closest( this.element.find( \".ui-menu\" ) );\n\n\t\t\t// If we found no valid submenu ancestor, use the main menu to close all\n\t\t\t// sub menus anyway\n\t\t\tif ( !currentMenu.length ) {\n\t\t\t\tcurrentMenu = this.element;\n\t\t\t}\n\n\t\t\tthis._close( currentMenu );\n\n\t\t\tthis.blur( event );\n\n\t\t\t// Work around active item staying active after menu is blurred\n\t\t\tthis._removeClass( currentMenu.find( \".ui-state-active\" ), null, \"ui-state-active\" );\n\n\t\t\tthis.activeMenu = currentMenu;\n\t\t}, this.delay );\n\t},\n\n\t// With no arguments, closes the currently active menu - if nothing is active\n\t// it closes all menus.  If passed an argument, it will search for menus BELOW\n\t_close: function( startMenu ) {\n\t\tif ( !startMenu ) {\n\t\t\tstartMenu = this.active ? this.active.parent() : this.element;\n\t\t}\n\n\t\tstartMenu.find( \".ui-menu\" )\n\t\t\t.hide()\n\t\t\t.attr( \"aria-hidden\", \"true\" )\n\t\t\t.attr( \"aria-expanded\", \"false\" );\n\t},\n\n\t_closeOnDocumentClick: function( event ) {\n\t\treturn !$( event.target ).closest( \".ui-menu\" ).length;\n\t},\n\n\t_isDivider: function( item ) {\n\n\t\t// Match hyphen, em dash, en dash\n\t\treturn !/[^\\-\\u2014\\u2013\\s]/.test( item.text() );\n\t},\n\n\tcollapse: function( event ) {\n\t\tvar newItem = this.active &&\n\t\t\tthis.active.parent().closest( \".ui-menu-item\", this.element );\n\t\tif ( newItem && newItem.length ) {\n\t\t\tthis._close();\n\t\t\tthis.focus( event, newItem );\n\t\t}\n\t},\n\n\texpand: function( event ) {\n\t\tvar newItem = this.active &&\n\t\t\tthis.active\n\t\t\t\t.children( \".ui-menu \" )\n\t\t\t\t\t.find( this.options.items )\n\t\t\t\t\t\t.first();\n\n\t\tif ( newItem && newItem.length ) {\n\t\t\tthis._open( newItem.parent() );\n\n\t\t\t// Delay so Firefox will not hide activedescendant change in expanding submenu from AT\n\t\t\tthis._delay( function() {\n\t\t\t\tthis.focus( event, newItem );\n\t\t\t} );\n\t\t}\n\t},\n\n\tnext: function( event ) {\n\t\tthis._move( \"next\", \"first\", event );\n\t},\n\n\tprevious: function( event ) {\n\t\tthis._move( \"prev\", \"last\", event );\n\t},\n\n\tisFirstItem: function() {\n\t\treturn this.active && !this.active.prevAll( \".ui-menu-item\" ).length;\n\t},\n\n\tisLastItem: function() {\n\t\treturn this.active && !this.active.nextAll( \".ui-menu-item\" ).length;\n\t},\n\n\t_move: function( direction, filter, event ) {\n\t\tvar next;\n\t\tif ( this.active ) {\n\t\t\tif ( direction === \"first\" || direction === \"last\" ) {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction === \"first\" ? \"prevAll\" : \"nextAll\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( -1 );\n\t\t\t} else {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction + \"All\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( 0 );\n\t\t\t}\n\t\t}\n\t\tif ( !next || !next.length || !this.active ) {\n\t\t\tnext = this.activeMenu.find( this.options.items )[ filter ]();\n\t\t}\n\n\t\tthis.focus( event, next );\n\t},\n\n\tnextPage: function( event ) {\n\t\tvar item, base, height;\n\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isLastItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.nextAll( \".ui-menu-item\" ).each( function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base - height < 0;\n\t\t\t} );\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.find( this.options.items )\n\t\t\t\t[ !this.active ? \"first\" : \"last\" ]() );\n\t\t}\n\t},\n\n\tpreviousPage: function( event ) {\n\t\tvar item, base, height;\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isFirstItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.prevAll( \".ui-menu-item\" ).each( function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base + height > 0;\n\t\t\t} );\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.find( this.options.items ).first() );\n\t\t}\n\t},\n\n\t_hasScroll: function() {\n\t\treturn this.element.outerHeight() < this.element.prop( \"scrollHeight\" );\n\t},\n\n\tselect: function( event ) {\n\n\t\t// TODO: It should never be possible to not have an active item at this\n\t\t// point, but the tests don't trigger mouseenter before click.\n\t\tthis.active = this.active || $( event.target ).closest( \".ui-menu-item\" );\n\t\tvar ui = { item: this.active };\n\t\tif ( !this.active.has( \".ui-menu\" ).length ) {\n\t\t\tthis.collapseAll( event, true );\n\t\t}\n\t\tthis._trigger( \"select\", event, ui );\n\t},\n\n\t_filterMenuItems: function( character ) {\n\t\tvar escapedCharacter = character.replace( /[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$&\" ),\n\t\t\tregex = new RegExp( \"^\" + escapedCharacter, \"i\" );\n\n\t\treturn this.activeMenu\n\t\t\t.find( this.options.items )\n\n\t\t\t\t// Only match on items, not dividers or other content (#10571)\n\t\t\t\t.filter( \".ui-menu-item\" )\n\t\t\t\t\t.filter( function() {\n\t\t\t\t\t\treturn regex.test(\n\t\t\t\t\t\t\t$.trim( $( this ).children( \".ui-menu-item-wrapper\" ).text() ) );\n\t\t\t\t\t} );\n\t}\n} );\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/widgets/mouse.js",
    "content": "//= require rails_admin/jquery-ui/ie\n//= require rails_admin/jquery-ui/version\n//= require rails_admin/jquery-ui/widget\n\n/*!\n * jQuery UI Mouse 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Mouse\n//>>group: Widgets\n//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.\n//>>docs: http://api.jqueryui.com/mouse/\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [\n\t\t\t\"jquery\",\n\t\t\t\"../ie\",\n\t\t\t\"../version\",\n\t\t\t\"../widget\"\n\t\t], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}( function( $ ) {\n\nvar mouseHandled = false;\n$( document ).on( \"mouseup\", function() {\n\tmouseHandled = false;\n} );\n\nreturn $.widget( \"ui.mouse\", {\n\tversion: \"1.12.1\",\n\toptions: {\n\t\tcancel: \"input, textarea, button, select, option\",\n\t\tdistance: 1,\n\t\tdelay: 0\n\t},\n\t_mouseInit: function() {\n\t\tvar that = this;\n\n\t\tthis.element\n\t\t\t.on( \"mousedown.\" + this.widgetName, function( event ) {\n\t\t\t\treturn that._mouseDown( event );\n\t\t\t} )\n\t\t\t.on( \"click.\" + this.widgetName, function( event ) {\n\t\t\t\tif ( true === $.data( event.target, that.widgetName + \".preventClickEvent\" ) ) {\n\t\t\t\t\t$.removeData( event.target, that.widgetName + \".preventClickEvent\" );\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} );\n\n\t\tthis.started = false;\n\t},\n\n\t// TODO: make sure destroying one instance of mouse doesn't mess with\n\t// other instances of mouse\n\t_mouseDestroy: function() {\n\t\tthis.element.off( \".\" + this.widgetName );\n\t\tif ( this._mouseMoveDelegate ) {\n\t\t\tthis.document\n\t\t\t\t.off( \"mousemove.\" + this.widgetName, this._mouseMoveDelegate )\n\t\t\t\t.off( \"mouseup.\" + this.widgetName, this._mouseUpDelegate );\n\t\t}\n\t},\n\n\t_mouseDown: function( event ) {\n\n\t\t// don't let more than one widget handle mouseStart\n\t\tif ( mouseHandled ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._mouseMoved = false;\n\n\t\t// We may have missed mouseup (out of window)\n\t\t( this._mouseStarted && this._mouseUp( event ) );\n\n\t\tthis._mouseDownEvent = event;\n\n\t\tvar that = this,\n\t\t\tbtnIsLeft = ( event.which === 1 ),\n\n\t\t\t// event.target.nodeName works around a bug in IE 8 with\n\t\t\t// disabled inputs (#7620)\n\t\t\telIsCancel = ( typeof this.options.cancel === \"string\" && event.target.nodeName ?\n\t\t\t\t$( event.target ).closest( this.options.cancel ).length : false );\n\t\tif ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.mouseDelayMet = !this.options.delay;\n\t\tif ( !this.mouseDelayMet ) {\n\t\t\tthis._mouseDelayTimer = setTimeout( function() {\n\t\t\t\tthat.mouseDelayMet = true;\n\t\t\t}, this.options.delay );\n\t\t}\n\n\t\tif ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {\n\t\t\tthis._mouseStarted = ( this._mouseStart( event ) !== false );\n\t\t\tif ( !this._mouseStarted ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// Click event may never have fired (Gecko & Opera)\n\t\tif ( true === $.data( event.target, this.widgetName + \".preventClickEvent\" ) ) {\n\t\t\t$.removeData( event.target, this.widgetName + \".preventClickEvent\" );\n\t\t}\n\n\t\t// These delegates are required to keep context\n\t\tthis._mouseMoveDelegate = function( event ) {\n\t\t\treturn that._mouseMove( event );\n\t\t};\n\t\tthis._mouseUpDelegate = function( event ) {\n\t\t\treturn that._mouseUp( event );\n\t\t};\n\n\t\tthis.document\n\t\t\t.on( \"mousemove.\" + this.widgetName, this._mouseMoveDelegate )\n\t\t\t.on( \"mouseup.\" + this.widgetName, this._mouseUpDelegate );\n\n\t\tevent.preventDefault();\n\n\t\tmouseHandled = true;\n\t\treturn true;\n\t},\n\n\t_mouseMove: function( event ) {\n\n\t\t// Only check for mouseups outside the document if you've moved inside the document\n\t\t// at least once. This prevents the firing of mouseup in the case of IE<9, which will\n\t\t// fire a mousemove event if content is placed under the cursor. See #7778\n\t\t// Support: IE <9\n\t\tif ( this._mouseMoved ) {\n\n\t\t\t// IE mouseup check - mouseup happened when mouse was out of window\n\t\t\tif ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&\n\t\t\t\t\t!event.button ) {\n\t\t\t\treturn this._mouseUp( event );\n\n\t\t\t// Iframe mouseup check - mouseup occurred in another document\n\t\t\t} else if ( !event.which ) {\n\n\t\t\t\t// Support: Safari <=8 - 9\n\t\t\t\t// Safari sets which to 0 if you press any of the following keys\n\t\t\t\t// during a drag (#14461)\n\t\t\t\tif ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||\n\t\t\t\t\t\tevent.originalEvent.metaKey || event.originalEvent.shiftKey ) {\n\t\t\t\t\tthis.ignoreMissingWhich = true;\n\t\t\t\t} else if ( !this.ignoreMissingWhich ) {\n\t\t\t\t\treturn this._mouseUp( event );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( event.which || event.button ) {\n\t\t\tthis._mouseMoved = true;\n\t\t}\n\n\t\tif ( this._mouseStarted ) {\n\t\t\tthis._mouseDrag( event );\n\t\t\treturn event.preventDefault();\n\t\t}\n\n\t\tif ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {\n\t\t\tthis._mouseStarted =\n\t\t\t\t( this._mouseStart( this._mouseDownEvent, event ) !== false );\n\t\t\t( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );\n\t\t}\n\n\t\treturn !this._mouseStarted;\n\t},\n\n\t_mouseUp: function( event ) {\n\t\tthis.document\n\t\t\t.off( \"mousemove.\" + this.widgetName, this._mouseMoveDelegate )\n\t\t\t.off( \"mouseup.\" + this.widgetName, this._mouseUpDelegate );\n\n\t\tif ( this._mouseStarted ) {\n\t\t\tthis._mouseStarted = false;\n\n\t\t\tif ( event.target === this._mouseDownEvent.target ) {\n\t\t\t\t$.data( event.target, this.widgetName + \".preventClickEvent\", true );\n\t\t\t}\n\n\t\t\tthis._mouseStop( event );\n\t\t}\n\n\t\tif ( this._mouseDelayTimer ) {\n\t\t\tclearTimeout( this._mouseDelayTimer );\n\t\t\tdelete this._mouseDelayTimer;\n\t\t}\n\n\t\tthis.ignoreMissingWhich = false;\n\t\tmouseHandled = false;\n\t\tevent.preventDefault();\n\t},\n\n\t_mouseDistanceMet: function( event ) {\n\t\treturn ( Math.max(\n\t\t\t\tMath.abs( this._mouseDownEvent.pageX - event.pageX ),\n\t\t\t\tMath.abs( this._mouseDownEvent.pageY - event.pageY )\n\t\t\t) >= this.options.distance\n\t\t);\n\t},\n\n\t_mouseDelayMet: function( /* event */ ) {\n\t\treturn this.mouseDelayMet;\n\t},\n\n\t// These are placeholder methods, to be overriden by extending plugin\n\t_mouseStart: function( /* event */ ) {},\n\t_mouseDrag: function( /* event */ ) {},\n\t_mouseStop: function( /* event */ ) {},\n\t_mouseCapture: function( /* event */ ) { return true; }\n} );\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery-ui/widgets/sortable.js",
    "content": "//= require rails_admin/jquery-ui/widgets/mouse\n//= require rails_admin/jquery-ui/data\n//= require rails_admin/jquery-ui/ie\n//= require rails_admin/jquery-ui/scroll-parent\n//= require rails_admin/jquery-ui/version\n//= require rails_admin/jquery-ui/widget\n\n/*!\n * jQuery UI Sortable 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Sortable\n//>>group: Interactions\n//>>description: Enables items in a list to be sorted using the mouse.\n//>>docs: http://api.jqueryui.com/sortable/\n//>>demos: http://jqueryui.com/sortable/\n//>>css.structure: ../../themes/base/sortable.css\n\n( function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [\n\t\t\t\"jquery\",\n\t\t\t\"./mouse\",\n\t\t\t\"../data\",\n\t\t\t\"../ie\",\n\t\t\t\"../scroll-parent\",\n\t\t\t\"../version\",\n\t\t\t\"../widget\"\n\t\t], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}( function( $ ) {\n\nreturn $.widget( \"ui.sortable\", $.ui.mouse, {\n\tversion: \"1.12.1\",\n\twidgetEventPrefix: \"sort\",\n\tready: false,\n\toptions: {\n\t\tappendTo: \"parent\",\n\t\taxis: false,\n\t\tconnectWith: false,\n\t\tcontainment: false,\n\t\tcursor: \"auto\",\n\t\tcursorAt: false,\n\t\tdropOnEmpty: true,\n\t\tforcePlaceholderSize: false,\n\t\tforceHelperSize: false,\n\t\tgrid: false,\n\t\thandle: false,\n\t\thelper: \"original\",\n\t\titems: \"> *\",\n\t\topacity: false,\n\t\tplaceholder: false,\n\t\trevert: false,\n\t\tscroll: true,\n\t\tscrollSensitivity: 20,\n\t\tscrollSpeed: 20,\n\t\tscope: \"default\",\n\t\ttolerance: \"intersect\",\n\t\tzIndex: 1000,\n\n\t\t// Callbacks\n\t\tactivate: null,\n\t\tbeforeStop: null,\n\t\tchange: null,\n\t\tdeactivate: null,\n\t\tout: null,\n\t\tover: null,\n\t\treceive: null,\n\t\tremove: null,\n\t\tsort: null,\n\t\tstart: null,\n\t\tstop: null,\n\t\tupdate: null\n\t},\n\n\t_isOverAxis: function( x, reference, size ) {\n\t\treturn ( x >= reference ) && ( x < ( reference + size ) );\n\t},\n\n\t_isFloating: function( item ) {\n\t\treturn ( /left|right/ ).test( item.css( \"float\" ) ) ||\n\t\t\t( /inline|table-cell/ ).test( item.css( \"display\" ) );\n\t},\n\n\t_create: function() {\n\t\tthis.containerCache = {};\n\t\tthis._addClass( \"ui-sortable\" );\n\n\t\t//Get the items\n\t\tthis.refresh();\n\n\t\t//Let's determine the parent's offset\n\t\tthis.offset = this.element.offset();\n\n\t\t//Initialize mouse events for interaction\n\t\tthis._mouseInit();\n\n\t\tthis._setHandleClassName();\n\n\t\t//We're ready to go\n\t\tthis.ready = true;\n\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"handle\" ) {\n\t\t\tthis._setHandleClassName();\n\t\t}\n\t},\n\n\t_setHandleClassName: function() {\n\t\tvar that = this;\n\t\tthis._removeClass( this.element.find( \".ui-sortable-handle\" ), \"ui-sortable-handle\" );\n\t\t$.each( this.items, function() {\n\t\t\tthat._addClass(\n\t\t\t\tthis.instance.options.handle ?\n\t\t\t\t\tthis.item.find( this.instance.options.handle ) :\n\t\t\t\t\tthis.item,\n\t\t\t\t\"ui-sortable-handle\"\n\t\t\t);\n\t\t} );\n\t},\n\n\t_destroy: function() {\n\t\tthis._mouseDestroy();\n\n\t\tfor ( var i = this.items.length - 1; i >= 0; i-- ) {\n\t\t\tthis.items[ i ].item.removeData( this.widgetName + \"-item\" );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_mouseCapture: function( event, overrideHandle ) {\n\t\tvar currentItem = null,\n\t\t\tvalidHandle = false,\n\t\t\tthat = this;\n\n\t\tif ( this.reverting ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.options.disabled || this.options.type === \"static\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t//We have to refresh the items data once first\n\t\tthis._refreshItems( event );\n\n\t\t//Find out if the clicked node (or one of its parents) is a actual item in this.items\n\t\t$( event.target ).parents().each( function() {\n\t\t\tif ( $.data( this, that.widgetName + \"-item\" ) === that ) {\n\t\t\t\tcurrentItem = $( this );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} );\n\t\tif ( $.data( event.target, that.widgetName + \"-item\" ) === that ) {\n\t\t\tcurrentItem = $( event.target );\n\t\t}\n\n\t\tif ( !currentItem ) {\n\t\t\treturn false;\n\t\t}\n\t\tif ( this.options.handle && !overrideHandle ) {\n\t\t\t$( this.options.handle, currentItem ).find( \"*\" ).addBack().each( function() {\n\t\t\t\tif ( this === event.target ) {\n\t\t\t\t\tvalidHandle = true;\n\t\t\t\t}\n\t\t\t} );\n\t\t\tif ( !validHandle ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.currentItem = currentItem;\n\t\tthis._removeCurrentsFromItems();\n\t\treturn true;\n\n\t},\n\n\t_mouseStart: function( event, overrideHandle, noActivation ) {\n\n\t\tvar i, body,\n\t\t\to = this.options;\n\n\t\tthis.currentContainer = this;\n\n\t\t//We only need to call refreshPositions, because the refreshItems call has been moved to\n\t\t// mouseCapture\n\t\tthis.refreshPositions();\n\n\t\t//Create and append the visible helper\n\t\tthis.helper = this._createHelper( event );\n\n\t\t//Cache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t/*\n\t\t * - Position generation -\n\t\t * This block generates everything position related - it's the core of draggables.\n\t\t */\n\n\t\t//Cache the margins of the original element\n\t\tthis._cacheMargins();\n\n\t\t//Get the next scrolling parent\n\t\tthis.scrollParent = this.helper.scrollParent();\n\n\t\t//The element's absolute position on the page minus margins\n\t\tthis.offset = this.currentItem.offset();\n\t\tthis.offset = {\n\t\t\ttop: this.offset.top - this.margins.top,\n\t\t\tleft: this.offset.left - this.margins.left\n\t\t};\n\n\t\t$.extend( this.offset, {\n\t\t\tclick: { //Where the click happened, relative to the element\n\t\t\t\tleft: event.pageX - this.offset.left,\n\t\t\t\ttop: event.pageY - this.offset.top\n\t\t\t},\n\t\t\tparent: this._getParentOffset(),\n\n\t\t\t// This is a relative to absolute position minus the actual position calculation -\n\t\t\t// only used for relative positioned helper\n\t\t\trelative: this._getRelativeOffset()\n\t\t} );\n\n\t\t// Only after we got the offset, we can change the helper's position to absolute\n\t\t// TODO: Still need to figure out a way to make relative sorting possible\n\t\tthis.helper.css( \"position\", \"absolute\" );\n\t\tthis.cssPosition = this.helper.css( \"position\" );\n\n\t\t//Generate the original position\n\t\tthis.originalPosition = this._generatePosition( event );\n\t\tthis.originalPageX = event.pageX;\n\t\tthis.originalPageY = event.pageY;\n\n\t\t//Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n\t\t( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );\n\n\t\t//Cache the former DOM position\n\t\tthis.domPosition = {\n\t\t\tprev: this.currentItem.prev()[ 0 ],\n\t\t\tparent: this.currentItem.parent()[ 0 ]\n\t\t};\n\n\t\t// If the helper is not the original, hide the original so it's not playing any role during\n\t\t// the drag, won't cause anything bad this way\n\t\tif ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {\n\t\t\tthis.currentItem.hide();\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthis._createPlaceholder();\n\n\t\t//Set a containment if given in the options\n\t\tif ( o.containment ) {\n\t\t\tthis._setContainment();\n\t\t}\n\n\t\tif ( o.cursor && o.cursor !== \"auto\" ) { // cursor option\n\t\t\tbody = this.document.find( \"body\" );\n\n\t\t\t// Support: IE\n\t\t\tthis.storedCursor = body.css( \"cursor\" );\n\t\t\tbody.css( \"cursor\", o.cursor );\n\n\t\t\tthis.storedStylesheet =\n\t\t\t\t$( \"<style>*{ cursor: \" + o.cursor + \" !important; }</style>\" ).appendTo( body );\n\t\t}\n\n\t\tif ( o.opacity ) { // opacity option\n\t\t\tif ( this.helper.css( \"opacity\" ) ) {\n\t\t\t\tthis._storedOpacity = this.helper.css( \"opacity\" );\n\t\t\t}\n\t\t\tthis.helper.css( \"opacity\", o.opacity );\n\t\t}\n\n\t\tif ( o.zIndex ) { // zIndex option\n\t\t\tif ( this.helper.css( \"zIndex\" ) ) {\n\t\t\t\tthis._storedZIndex = this.helper.css( \"zIndex\" );\n\t\t\t}\n\t\t\tthis.helper.css( \"zIndex\", o.zIndex );\n\t\t}\n\n\t\t//Prepare scrolling\n\t\tif ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&\n\t\t\t\tthis.scrollParent[ 0 ].tagName !== \"HTML\" ) {\n\t\t\tthis.overflowOffset = this.scrollParent.offset();\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger( \"start\", event, this._uiHash() );\n\n\t\t//Recache the helper size\n\t\tif ( !this._preserveHelperProportions ) {\n\t\t\tthis._cacheHelperProportions();\n\t\t}\n\n\t\t//Post \"activate\" events to possible containers\n\t\tif ( !noActivation ) {\n\t\t\tfor ( i = this.containers.length - 1; i >= 0; i-- ) {\n\t\t\t\tthis.containers[ i ]._trigger( \"activate\", event, this._uiHash( this ) );\n\t\t\t}\n\t\t}\n\n\t\t//Prepare possible droppables\n\t\tif ( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.current = this;\n\t\t}\n\n\t\tif ( $.ui.ddmanager && !o.dropBehaviour ) {\n\t\t\t$.ui.ddmanager.prepareOffsets( this, event );\n\t\t}\n\n\t\tthis.dragging = true;\n\n\t\tthis._addClass( this.helper, \"ui-sortable-helper\" );\n\n\t\t// Execute the drag once - this causes the helper not to be visiblebefore getting its\n\t\t// correct position\n\t\tthis._mouseDrag( event );\n\t\treturn true;\n\n\t},\n\n\t_mouseDrag: function( event ) {\n\t\tvar i, item, itemElement, intersection,\n\t\t\to = this.options,\n\t\t\tscrolled = false;\n\n\t\t//Compute the helpers position\n\t\tthis.position = this._generatePosition( event );\n\t\tthis.positionAbs = this._convertPositionTo( \"absolute\" );\n\n\t\tif ( !this.lastPositionAbs ) {\n\t\t\tthis.lastPositionAbs = this.positionAbs;\n\t\t}\n\n\t\t//Do scrolling\n\t\tif ( this.options.scroll ) {\n\t\t\tif ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&\n\t\t\t\t\tthis.scrollParent[ 0 ].tagName !== \"HTML\" ) {\n\n\t\t\t\tif ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -\n\t\t\t\t\t\tevent.pageY < o.scrollSensitivity ) {\n\t\t\t\t\tthis.scrollParent[ 0 ].scrollTop =\n\t\t\t\t\t\tscrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;\n\t\t\t\t} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {\n\t\t\t\t\tthis.scrollParent[ 0 ].scrollTop =\n\t\t\t\t\t\tscrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t\tif ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -\n\t\t\t\t\t\tevent.pageX < o.scrollSensitivity ) {\n\t\t\t\t\tthis.scrollParent[ 0 ].scrollLeft = scrolled =\n\t\t\t\t\t\tthis.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;\n\t\t\t\t} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {\n\t\t\t\t\tthis.scrollParent[ 0 ].scrollLeft = scrolled =\n\t\t\t\t\t\tthis.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {\n\t\t\t\t\tscrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );\n\t\t\t\t} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <\n\t\t\t\t\t\to.scrollSensitivity ) {\n\t\t\t\t\tscrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );\n\t\t\t\t}\n\n\t\t\t\tif ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {\n\t\t\t\t\tscrolled = this.document.scrollLeft(\n\t\t\t\t\t\tthis.document.scrollLeft() - o.scrollSpeed\n\t\t\t\t\t);\n\t\t\t\t} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <\n\t\t\t\t\t\to.scrollSensitivity ) {\n\t\t\t\t\tscrolled = this.document.scrollLeft(\n\t\t\t\t\t\tthis.document.scrollLeft() + o.scrollSpeed\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {\n\t\t\t\t$.ui.ddmanager.prepareOffsets( this, event );\n\t\t\t}\n\t\t}\n\n\t\t//Regenerate the absolute position used for position checks\n\t\tthis.positionAbs = this._convertPositionTo( \"absolute\" );\n\n\t\t//Set the helper position\n\t\tif ( !this.options.axis || this.options.axis !== \"y\" ) {\n\t\t\tthis.helper[ 0 ].style.left = this.position.left + \"px\";\n\t\t}\n\t\tif ( !this.options.axis || this.options.axis !== \"x\" ) {\n\t\t\tthis.helper[ 0 ].style.top = this.position.top + \"px\";\n\t\t}\n\n\t\t//Rearrange\n\t\tfor ( i = this.items.length - 1; i >= 0; i-- ) {\n\n\t\t\t//Cache variables and intersection, continue if no intersection\n\t\t\titem = this.items[ i ];\n\t\t\titemElement = item.item[ 0 ];\n\t\t\tintersection = this._intersectsWithPointer( item );\n\t\t\tif ( !intersection ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Only put the placeholder inside the current Container, skip all\n\t\t\t// items from other containers. This works because when moving\n\t\t\t// an item from one container to another the\n\t\t\t// currentContainer is switched before the placeholder is moved.\n\t\t\t//\n\t\t\t// Without this, moving items in \"sub-sortables\" can cause\n\t\t\t// the placeholder to jitter between the outer and inner container.\n\t\t\tif ( item.instance !== this.currentContainer ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Cannot intersect with itself\n\t\t\t// no useless actions that have been done before\n\t\t\t// no action if the item moved is the parent of the item checked\n\t\t\tif ( itemElement !== this.currentItem[ 0 ] &&\n\t\t\t\tthis.placeholder[ intersection === 1 ? \"next\" : \"prev\" ]()[ 0 ] !== itemElement &&\n\t\t\t\t!$.contains( this.placeholder[ 0 ], itemElement ) &&\n\t\t\t\t( this.options.type === \"semi-dynamic\" ?\n\t\t\t\t\t!$.contains( this.element[ 0 ], itemElement ) :\n\t\t\t\t\ttrue\n\t\t\t\t)\n\t\t\t) {\n\n\t\t\t\tthis.direction = intersection === 1 ? \"down\" : \"up\";\n\n\t\t\t\tif ( this.options.tolerance === \"pointer\" || this._intersectsWithSides( item ) ) {\n\t\t\t\t\tthis._rearrange( event, item );\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tthis._trigger( \"change\", event, this._uiHash() );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//Post events to containers\n\t\tthis._contactContainers( event );\n\n\t\t//Interconnect with droppables\n\t\tif ( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.drag( this, event );\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger( \"sort\", event, this._uiHash() );\n\n\t\tthis.lastPositionAbs = this.positionAbs;\n\t\treturn false;\n\n\t},\n\n\t_mouseStop: function( event, noPropagation ) {\n\n\t\tif ( !event ) {\n\t\t\treturn;\n\t\t}\n\n\t\t//If we are using droppables, inform the manager about the drop\n\t\tif ( $.ui.ddmanager && !this.options.dropBehaviour ) {\n\t\t\t$.ui.ddmanager.drop( this, event );\n\t\t}\n\n\t\tif ( this.options.revert ) {\n\t\t\tvar that = this,\n\t\t\t\tcur = this.placeholder.offset(),\n\t\t\t\taxis = this.options.axis,\n\t\t\t\tanimation = {};\n\n\t\t\tif ( !axis || axis === \"x\" ) {\n\t\t\t\tanimation.left = cur.left - this.offset.parent.left - this.margins.left +\n\t\t\t\t\t( this.offsetParent[ 0 ] === this.document[ 0 ].body ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\tthis.offsetParent[ 0 ].scrollLeft\n\t\t\t\t\t);\n\t\t\t}\n\t\t\tif ( !axis || axis === \"y\" ) {\n\t\t\t\tanimation.top = cur.top - this.offset.parent.top - this.margins.top +\n\t\t\t\t\t( this.offsetParent[ 0 ] === this.document[ 0 ].body ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\tthis.offsetParent[ 0 ].scrollTop\n\t\t\t\t\t);\n\t\t\t}\n\t\t\tthis.reverting = true;\n\t\t\t$( this.helper ).animate(\n\t\t\t\tanimation,\n\t\t\t\tparseInt( this.options.revert, 10 ) || 500,\n\t\t\t\tfunction() {\n\t\t\t\t\tthat._clear( event );\n\t\t\t\t}\n\t\t\t);\n\t\t} else {\n\t\t\tthis._clear( event, noPropagation );\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\tcancel: function() {\n\n\t\tif ( this.dragging ) {\n\n\t\t\tthis._mouseUp( new $.Event( \"mouseup\", { target: null } ) );\n\n\t\t\tif ( this.options.helper === \"original\" ) {\n\t\t\t\tthis.currentItem.css( this._storedCSS );\n\t\t\t\tthis._removeClass( this.currentItem, \"ui-sortable-helper\" );\n\t\t\t} else {\n\t\t\t\tthis.currentItem.show();\n\t\t\t}\n\n\t\t\t//Post deactivating events to containers\n\t\t\tfor ( var i = this.containers.length - 1; i >= 0; i-- ) {\n\t\t\t\tthis.containers[ i ]._trigger( \"deactivate\", null, this._uiHash( this ) );\n\t\t\t\tif ( this.containers[ i ].containerCache.over ) {\n\t\t\t\t\tthis.containers[ i ]._trigger( \"out\", null, this._uiHash( this ) );\n\t\t\t\t\tthis.containers[ i ].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif ( this.placeholder ) {\n\n\t\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,\n\t\t\t// it unbinds ALL events from the original node!\n\t\t\tif ( this.placeholder[ 0 ].parentNode ) {\n\t\t\t\tthis.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );\n\t\t\t}\n\t\t\tif ( this.options.helper !== \"original\" && this.helper &&\n\t\t\t\t\tthis.helper[ 0 ].parentNode ) {\n\t\t\t\tthis.helper.remove();\n\t\t\t}\n\n\t\t\t$.extend( this, {\n\t\t\t\thelper: null,\n\t\t\t\tdragging: false,\n\t\t\t\treverting: false,\n\t\t\t\t_noFinalSort: null\n\t\t\t} );\n\n\t\t\tif ( this.domPosition.prev ) {\n\t\t\t\t$( this.domPosition.prev ).after( this.currentItem );\n\t\t\t} else {\n\t\t\t\t$( this.domPosition.parent ).prepend( this.currentItem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\n\t},\n\n\tserialize: function( o ) {\n\n\t\tvar items = this._getItemsAsjQuery( o && o.connected ),\n\t\t\tstr = [];\n\t\to = o || {};\n\n\t\t$( items ).each( function() {\n\t\t\tvar res = ( $( o.item || this ).attr( o.attribute || \"id\" ) || \"\" )\n\t\t\t\t.match( o.expression || ( /(.+)[\\-=_](.+)/ ) );\n\t\t\tif ( res ) {\n\t\t\t\tstr.push(\n\t\t\t\t\t( o.key || res[ 1 ] + \"[]\" ) +\n\t\t\t\t\t\"=\" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );\n\t\t\t}\n\t\t} );\n\n\t\tif ( !str.length && o.key ) {\n\t\t\tstr.push( o.key + \"=\" );\n\t\t}\n\n\t\treturn str.join( \"&\" );\n\n\t},\n\n\ttoArray: function( o ) {\n\n\t\tvar items = this._getItemsAsjQuery( o && o.connected ),\n\t\t\tret = [];\n\n\t\to = o || {};\n\n\t\titems.each( function() {\n\t\t\tret.push( $( o.item || this ).attr( o.attribute || \"id\" ) || \"\" );\n\t\t} );\n\t\treturn ret;\n\n\t},\n\n\t/* Be careful with the following core functions */\n\t_intersectsWith: function( item ) {\n\n\t\tvar x1 = this.positionAbs.left,\n\t\t\tx2 = x1 + this.helperProportions.width,\n\t\t\ty1 = this.positionAbs.top,\n\t\t\ty2 = y1 + this.helperProportions.height,\n\t\t\tl = item.left,\n\t\t\tr = l + item.width,\n\t\t\tt = item.top,\n\t\t\tb = t + item.height,\n\t\t\tdyClick = this.offset.click.top,\n\t\t\tdxClick = this.offset.click.left,\n\t\t\tisOverElementHeight = ( this.options.axis === \"x\" ) || ( ( y1 + dyClick ) > t &&\n\t\t\t\t( y1 + dyClick ) < b ),\n\t\t\tisOverElementWidth = ( this.options.axis === \"y\" ) || ( ( x1 + dxClick ) > l &&\n\t\t\t\t( x1 + dxClick ) < r ),\n\t\t\tisOverElement = isOverElementHeight && isOverElementWidth;\n\n\t\tif ( this.options.tolerance === \"pointer\" ||\n\t\t\tthis.options.forcePointerForContainers ||\n\t\t\t( this.options.tolerance !== \"pointer\" &&\n\t\t\t\tthis.helperProportions[ this.floating ? \"width\" : \"height\" ] >\n\t\t\t\titem[ this.floating ? \"width\" : \"height\" ] )\n\t\t) {\n\t\t\treturn isOverElement;\n\t\t} else {\n\n\t\t\treturn ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half\n\t\t\t\tx2 - ( this.helperProportions.width / 2 ) < r && // Left Half\n\t\t\t\tt < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half\n\t\t\t\ty2 - ( this.helperProportions.height / 2 ) < b ); // Top Half\n\n\t\t}\n\t},\n\n\t_intersectsWithPointer: function( item ) {\n\t\tvar verticalDirection, horizontalDirection,\n\t\t\tisOverElementHeight = ( this.options.axis === \"x\" ) ||\n\t\t\t\tthis._isOverAxis(\n\t\t\t\t\tthis.positionAbs.top + this.offset.click.top, item.top, item.height ),\n\t\t\tisOverElementWidth = ( this.options.axis === \"y\" ) ||\n\t\t\t\tthis._isOverAxis(\n\t\t\t\t\tthis.positionAbs.left + this.offset.click.left, item.left, item.width ),\n\t\t\tisOverElement = isOverElementHeight && isOverElementWidth;\n\n\t\tif ( !isOverElement ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tverticalDirection = this._getDragVerticalDirection();\n\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\treturn this.floating ?\n\t\t\t( ( horizontalDirection === \"right\" || verticalDirection === \"down\" ) ? 2 : 1 )\n\t\t\t: ( verticalDirection && ( verticalDirection === \"down\" ? 2 : 1 ) );\n\n\t},\n\n\t_intersectsWithSides: function( item ) {\n\n\t\tvar isOverBottomHalf = this._isOverAxis( this.positionAbs.top +\n\t\t\t\tthis.offset.click.top, item.top + ( item.height / 2 ), item.height ),\n\t\t\tisOverRightHalf = this._isOverAxis( this.positionAbs.left +\n\t\t\t\tthis.offset.click.left, item.left + ( item.width / 2 ), item.width ),\n\t\t\tverticalDirection = this._getDragVerticalDirection(),\n\t\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\tif ( this.floating && horizontalDirection ) {\n\t\t\treturn ( ( horizontalDirection === \"right\" && isOverRightHalf ) ||\n\t\t\t\t( horizontalDirection === \"left\" && !isOverRightHalf ) );\n\t\t} else {\n\t\t\treturn verticalDirection && ( ( verticalDirection === \"down\" && isOverBottomHalf ) ||\n\t\t\t\t( verticalDirection === \"up\" && !isOverBottomHalf ) );\n\t\t}\n\n\t},\n\n\t_getDragVerticalDirection: function() {\n\t\tvar delta = this.positionAbs.top - this.lastPositionAbs.top;\n\t\treturn delta !== 0 && ( delta > 0 ? \"down\" : \"up\" );\n\t},\n\n\t_getDragHorizontalDirection: function() {\n\t\tvar delta = this.positionAbs.left - this.lastPositionAbs.left;\n\t\treturn delta !== 0 && ( delta > 0 ? \"right\" : \"left\" );\n\t},\n\n\trefresh: function( event ) {\n\t\tthis._refreshItems( event );\n\t\tthis._setHandleClassName();\n\t\tthis.refreshPositions();\n\t\treturn this;\n\t},\n\n\t_connectWith: function() {\n\t\tvar options = this.options;\n\t\treturn options.connectWith.constructor === String ?\n\t\t\t[ options.connectWith ] :\n\t\t\toptions.connectWith;\n\t},\n\n\t_getItemsAsjQuery: function( connected ) {\n\n\t\tvar i, j, cur, inst,\n\t\t\titems = [],\n\t\t\tqueries = [],\n\t\t\tconnectWith = this._connectWith();\n\n\t\tif ( connectWith && connected ) {\n\t\t\tfor ( i = connectWith.length - 1; i >= 0; i-- ) {\n\t\t\t\tcur = $( connectWith[ i ], this.document[ 0 ] );\n\t\t\t\tfor ( j = cur.length - 1; j >= 0; j-- ) {\n\t\t\t\t\tinst = $.data( cur[ j ], this.widgetFullName );\n\t\t\t\t\tif ( inst && inst !== this && !inst.options.disabled ) {\n\t\t\t\t\t\tqueries.push( [ $.isFunction( inst.options.items ) ?\n\t\t\t\t\t\t\tinst.options.items.call( inst.element ) :\n\t\t\t\t\t\t\t$( inst.options.items, inst.element )\n\t\t\t\t\t\t\t\t.not( \".ui-sortable-helper\" )\n\t\t\t\t\t\t\t\t.not( \".ui-sortable-placeholder\" ), inst ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tqueries.push( [ $.isFunction( this.options.items ) ?\n\t\t\tthis.options.items\n\t\t\t\t.call( this.element, null, { options: this.options, item: this.currentItem } ) :\n\t\t\t$( this.options.items, this.element )\n\t\t\t\t.not( \".ui-sortable-helper\" )\n\t\t\t\t.not( \".ui-sortable-placeholder\" ), this ] );\n\n\t\tfunction addItems() {\n\t\t\titems.push( this );\n\t\t}\n\t\tfor ( i = queries.length - 1; i >= 0; i-- ) {\n\t\t\tqueries[ i ][ 0 ].each( addItems );\n\t\t}\n\n\t\treturn $( items );\n\n\t},\n\n\t_removeCurrentsFromItems: function() {\n\n\t\tvar list = this.currentItem.find( \":data(\" + this.widgetName + \"-item)\" );\n\n\t\tthis.items = $.grep( this.items, function( item ) {\n\t\t\tfor ( var j = 0; j < list.length; j++ ) {\n\t\t\t\tif ( list[ j ] === item.item[ 0 ] ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} );\n\n\t},\n\n\t_refreshItems: function( event ) {\n\n\t\tthis.items = [];\n\t\tthis.containers = [ this ];\n\n\t\tvar i, j, cur, inst, targetData, _queries, item, queriesLength,\n\t\t\titems = this.items,\n\t\t\tqueries = [ [ $.isFunction( this.options.items ) ?\n\t\t\t\tthis.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :\n\t\t\t\t$( this.options.items, this.element ), this ] ],\n\t\t\tconnectWith = this._connectWith();\n\n\t\t//Shouldn't be run the first time through due to massive slow-down\n\t\tif ( connectWith && this.ready ) {\n\t\t\tfor ( i = connectWith.length - 1; i >= 0; i-- ) {\n\t\t\t\tcur = $( connectWith[ i ], this.document[ 0 ] );\n\t\t\t\tfor ( j = cur.length - 1; j >= 0; j-- ) {\n\t\t\t\t\tinst = $.data( cur[ j ], this.widgetFullName );\n\t\t\t\t\tif ( inst && inst !== this && !inst.options.disabled ) {\n\t\t\t\t\t\tqueries.push( [ $.isFunction( inst.options.items ) ?\n\t\t\t\t\t\t\tinst.options.items\n\t\t\t\t\t\t\t\t.call( inst.element[ 0 ], event, { item: this.currentItem } ) :\n\t\t\t\t\t\t\t$( inst.options.items, inst.element ), inst ] );\n\t\t\t\t\t\tthis.containers.push( inst );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( i = queries.length - 1; i >= 0; i-- ) {\n\t\t\ttargetData = queries[ i ][ 1 ];\n\t\t\t_queries = queries[ i ][ 0 ];\n\n\t\t\tfor ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {\n\t\t\t\titem = $( _queries[ j ] );\n\n\t\t\t\t// Data for target checking (mouse manager)\n\t\t\t\titem.data( this.widgetName + \"-item\", targetData );\n\n\t\t\t\titems.push( {\n\t\t\t\t\titem: item,\n\t\t\t\t\tinstance: targetData,\n\t\t\t\t\twidth: 0, height: 0,\n\t\t\t\t\tleft: 0, top: 0\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t},\n\n\trefreshPositions: function( fast ) {\n\n\t\t// Determine whether items are being displayed horizontally\n\t\tthis.floating = this.items.length ?\n\t\t\tthis.options.axis === \"x\" || this._isFloating( this.items[ 0 ].item ) :\n\t\t\tfalse;\n\n\t\t//This has to be redone because due to the item being moved out/into the offsetParent,\n\t\t// the offsetParent's position will change\n\t\tif ( this.offsetParent && this.helper ) {\n\t\t\tthis.offset.parent = this._getParentOffset();\n\t\t}\n\n\t\tvar i, item, t, p;\n\n\t\tfor ( i = this.items.length - 1; i >= 0; i-- ) {\n\t\t\titem = this.items[ i ];\n\n\t\t\t//We ignore calculating positions of all connected containers when we're not over them\n\t\t\tif ( item.instance !== this.currentContainer && this.currentContainer &&\n\t\t\t\t\titem.item[ 0 ] !== this.currentItem[ 0 ] ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tt = this.options.toleranceElement ?\n\t\t\t\t$( this.options.toleranceElement, item.item ) :\n\t\t\t\titem.item;\n\n\t\t\tif ( !fast ) {\n\t\t\t\titem.width = t.outerWidth();\n\t\t\t\titem.height = t.outerHeight();\n\t\t\t}\n\n\t\t\tp = t.offset();\n\t\t\titem.left = p.left;\n\t\t\titem.top = p.top;\n\t\t}\n\n\t\tif ( this.options.custom && this.options.custom.refreshContainers ) {\n\t\t\tthis.options.custom.refreshContainers.call( this );\n\t\t} else {\n\t\t\tfor ( i = this.containers.length - 1; i >= 0; i-- ) {\n\t\t\t\tp = this.containers[ i ].element.offset();\n\t\t\t\tthis.containers[ i ].containerCache.left = p.left;\n\t\t\t\tthis.containers[ i ].containerCache.top = p.top;\n\t\t\t\tthis.containers[ i ].containerCache.width =\n\t\t\t\t\tthis.containers[ i ].element.outerWidth();\n\t\t\t\tthis.containers[ i ].containerCache.height =\n\t\t\t\t\tthis.containers[ i ].element.outerHeight();\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_createPlaceholder: function( that ) {\n\t\tthat = that || this;\n\t\tvar className,\n\t\t\to = that.options;\n\n\t\tif ( !o.placeholder || o.placeholder.constructor === String ) {\n\t\t\tclassName = o.placeholder;\n\t\t\to.placeholder = {\n\t\t\t\telement: function() {\n\n\t\t\t\t\tvar nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),\n\t\t\t\t\t\telement = $( \"<\" + nodeName + \">\", that.document[ 0 ] );\n\n\t\t\t\t\t\tthat._addClass( element, \"ui-sortable-placeholder\",\n\t\t\t\t\t\t\t\tclassName || that.currentItem[ 0 ].className )\n\t\t\t\t\t\t\t._removeClass( element, \"ui-sortable-helper\" );\n\n\t\t\t\t\tif ( nodeName === \"tbody\" ) {\n\t\t\t\t\t\tthat._createTrPlaceholder(\n\t\t\t\t\t\t\tthat.currentItem.find( \"tr\" ).eq( 0 ),\n\t\t\t\t\t\t\t$( \"<tr>\", that.document[ 0 ] ).appendTo( element )\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if ( nodeName === \"tr\" ) {\n\t\t\t\t\t\tthat._createTrPlaceholder( that.currentItem, element );\n\t\t\t\t\t} else if ( nodeName === \"img\" ) {\n\t\t\t\t\t\telement.attr( \"src\", that.currentItem.attr( \"src\" ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !className ) {\n\t\t\t\t\t\telement.css( \"visibility\", \"hidden\" );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn element;\n\t\t\t\t},\n\t\t\t\tupdate: function( container, p ) {\n\n\t\t\t\t\t// 1. If a className is set as 'placeholder option, we don't force sizes -\n\t\t\t\t\t// the class is responsible for that\n\t\t\t\t\t// 2. The option 'forcePlaceholderSize can be enabled to force it even if a\n\t\t\t\t\t// class name is specified\n\t\t\t\t\tif ( className && !o.forcePlaceholderSize ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t//If the element doesn't have a actual height by itself (without styles coming\n\t\t\t\t\t// from a stylesheet), it receives the inline height from the dragged item\n\t\t\t\t\tif ( !p.height() ) {\n\t\t\t\t\t\tp.height(\n\t\t\t\t\t\t\tthat.currentItem.innerHeight() -\n\t\t\t\t\t\t\tparseInt( that.currentItem.css( \"paddingTop\" ) || 0, 10 ) -\n\t\t\t\t\t\t\tparseInt( that.currentItem.css( \"paddingBottom\" ) || 0, 10 ) );\n\t\t\t\t\t}\n\t\t\t\t\tif ( !p.width() ) {\n\t\t\t\t\t\tp.width(\n\t\t\t\t\t\t\tthat.currentItem.innerWidth() -\n\t\t\t\t\t\t\tparseInt( that.currentItem.css( \"paddingLeft\" ) || 0, 10 ) -\n\t\t\t\t\t\t\tparseInt( that.currentItem.css( \"paddingRight\" ) || 0, 10 ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthat.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );\n\n\t\t//Append it after the actual current item\n\t\tthat.currentItem.after( that.placeholder );\n\n\t\t//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)\n\t\to.placeholder.update( that, that.placeholder );\n\n\t},\n\n\t_createTrPlaceholder: function( sourceTr, targetTr ) {\n\t\tvar that = this;\n\n\t\tsourceTr.children().each( function() {\n\t\t\t$( \"<td>&#160;</td>\", that.document[ 0 ] )\n\t\t\t\t.attr( \"colspan\", $( this ).attr( \"colspan\" ) || 1 )\n\t\t\t\t.appendTo( targetTr );\n\t\t} );\n\t},\n\n\t_contactContainers: function( event ) {\n\t\tvar i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,\n\t\t\tfloating, axis,\n\t\t\tinnermostContainer = null,\n\t\t\tinnermostIndex = null;\n\n\t\t// Get innermost container that intersects with item\n\t\tfor ( i = this.containers.length - 1; i >= 0; i-- ) {\n\n\t\t\t// Never consider a container that's located within the item itself\n\t\t\tif ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( this._intersectsWith( this.containers[ i ].containerCache ) ) {\n\n\t\t\t\t// If we've already found a container and it's more \"inner\" than this, then continue\n\t\t\t\tif ( innermostContainer &&\n\t\t\t\t\t\t$.contains(\n\t\t\t\t\t\t\tthis.containers[ i ].element[ 0 ],\n\t\t\t\t\t\t\tinnermostContainer.element[ 0 ] ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tinnermostContainer = this.containers[ i ];\n\t\t\t\tinnermostIndex = i;\n\n\t\t\t} else {\n\n\t\t\t\t// container doesn't intersect. trigger \"out\" event if necessary\n\t\t\t\tif ( this.containers[ i ].containerCache.over ) {\n\t\t\t\t\tthis.containers[ i ]._trigger( \"out\", event, this._uiHash( this ) );\n\t\t\t\t\tthis.containers[ i ].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t// If no intersecting containers found, return\n\t\tif ( !innermostContainer ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Move the item into the container if it's not there already\n\t\tif ( this.containers.length === 1 ) {\n\t\t\tif ( !this.containers[ innermostIndex ].containerCache.over ) {\n\t\t\t\tthis.containers[ innermostIndex ]._trigger( \"over\", event, this._uiHash( this ) );\n\t\t\t\tthis.containers[ innermostIndex ].containerCache.over = 1;\n\t\t\t}\n\t\t} else {\n\n\t\t\t// When entering a new container, we will find the item with the least distance and\n\t\t\t// append our item near it\n\t\t\tdist = 10000;\n\t\t\titemWithLeastDistance = null;\n\t\t\tfloating = innermostContainer.floating || this._isFloating( this.currentItem );\n\t\t\tposProperty = floating ? \"left\" : \"top\";\n\t\t\tsizeProperty = floating ? \"width\" : \"height\";\n\t\t\taxis = floating ? \"pageX\" : \"pageY\";\n\n\t\t\tfor ( j = this.items.length - 1; j >= 0; j-- ) {\n\t\t\t\tif ( !$.contains(\n\t\t\t\t\t\tthis.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tcur = this.items[ j ].item.offset()[ posProperty ];\n\t\t\t\tnearBottom = false;\n\t\t\t\tif ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {\n\t\t\t\t\tnearBottom = true;\n\t\t\t\t}\n\n\t\t\t\tif ( Math.abs( event[ axis ] - cur ) < dist ) {\n\t\t\t\t\tdist = Math.abs( event[ axis ] - cur );\n\t\t\t\t\titemWithLeastDistance = this.items[ j ];\n\t\t\t\t\tthis.direction = nearBottom ? \"up\" : \"down\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//Check if dropOnEmpty is enabled\n\t\t\tif ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this.currentContainer === this.containers[ innermostIndex ] ) {\n\t\t\t\tif ( !this.currentContainer.containerCache.over ) {\n\t\t\t\t\tthis.containers[ innermostIndex ]._trigger( \"over\", event, this._uiHash() );\n\t\t\t\t\tthis.currentContainer.containerCache.over = 1;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titemWithLeastDistance ?\n\t\t\t\tthis._rearrange( event, itemWithLeastDistance, null, true ) :\n\t\t\t\tthis._rearrange( event, null, this.containers[ innermostIndex ].element, true );\n\t\t\tthis._trigger( \"change\", event, this._uiHash() );\n\t\t\tthis.containers[ innermostIndex ]._trigger( \"change\", event, this._uiHash( this ) );\n\t\t\tthis.currentContainer = this.containers[ innermostIndex ];\n\n\t\t\t//Update the placeholder\n\t\t\tthis.options.placeholder.update( this.currentContainer, this.placeholder );\n\n\t\t\tthis.containers[ innermostIndex ]._trigger( \"over\", event, this._uiHash( this ) );\n\t\t\tthis.containers[ innermostIndex ].containerCache.over = 1;\n\t\t}\n\n\t},\n\n\t_createHelper: function( event ) {\n\n\t\tvar o = this.options,\n\t\t\thelper = $.isFunction( o.helper ) ?\n\t\t\t\t$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :\n\t\t\t\t( o.helper === \"clone\" ? this.currentItem.clone() : this.currentItem );\n\n\t\t//Add the helper to the DOM if that didn't happen already\n\t\tif ( !helper.parents( \"body\" ).length ) {\n\t\t\t$( o.appendTo !== \"parent\" ?\n\t\t\t\to.appendTo :\n\t\t\t\tthis.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );\n\t\t}\n\n\t\tif ( helper[ 0 ] === this.currentItem[ 0 ] ) {\n\t\t\tthis._storedCSS = {\n\t\t\t\twidth: this.currentItem[ 0 ].style.width,\n\t\t\t\theight: this.currentItem[ 0 ].style.height,\n\t\t\t\tposition: this.currentItem.css( \"position\" ),\n\t\t\t\ttop: this.currentItem.css( \"top\" ),\n\t\t\t\tleft: this.currentItem.css( \"left\" )\n\t\t\t};\n\t\t}\n\n\t\tif ( !helper[ 0 ].style.width || o.forceHelperSize ) {\n\t\t\thelper.width( this.currentItem.width() );\n\t\t}\n\t\tif ( !helper[ 0 ].style.height || o.forceHelperSize ) {\n\t\t\thelper.height( this.currentItem.height() );\n\t\t}\n\n\t\treturn helper;\n\n\t},\n\n\t_adjustOffsetFromHelper: function( obj ) {\n\t\tif ( typeof obj === \"string\" ) {\n\t\t\tobj = obj.split( \" \" );\n\t\t}\n\t\tif ( $.isArray( obj ) ) {\n\t\t\tobj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };\n\t\t}\n\t\tif ( \"left\" in obj ) {\n\t\t\tthis.offset.click.left = obj.left + this.margins.left;\n\t\t}\n\t\tif ( \"right\" in obj ) {\n\t\t\tthis.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n\t\t}\n\t\tif ( \"top\" in obj ) {\n\t\t\tthis.offset.click.top = obj.top + this.margins.top;\n\t\t}\n\t\tif ( \"bottom\" in obj ) {\n\t\t\tthis.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n\t\t}\n\t},\n\n\t_getParentOffset: function() {\n\n\t\t//Get the offsetParent and cache its position\n\t\tthis.offsetParent = this.helper.offsetParent();\n\t\tvar po = this.offsetParent.offset();\n\n\t\t// This is a special case where we need to modify a offset calculated on start, since the\n\t\t// following happened:\n\t\t// 1. The position of the helper is absolute, so it's position is calculated based on the\n\t\t// next positioned parent\n\t\t// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't\n\t\t// the document, which means that the scroll is included in the initial calculation of the\n\t\t// offset of the parent, and never recalculated upon drag\n\t\tif ( this.cssPosition === \"absolute\" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&\n\t\t\t\t$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {\n\t\t\tpo.left += this.scrollParent.scrollLeft();\n\t\t\tpo.top += this.scrollParent.scrollTop();\n\t\t}\n\n\t\t// This needs to be actually done for all browsers, since pageX/pageY includes this\n\t\t// information with an ugly IE fix\n\t\tif ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||\n\t\t\t\t( this.offsetParent[ 0 ].tagName &&\n\t\t\t\tthis.offsetParent[ 0 ].tagName.toLowerCase() === \"html\" && $.ui.ie ) ) {\n\t\t\tpo = { top: 0, left: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\ttop: po.top + ( parseInt( this.offsetParent.css( \"borderTopWidth\" ), 10 ) || 0 ),\n\t\t\tleft: po.left + ( parseInt( this.offsetParent.css( \"borderLeftWidth\" ), 10 ) || 0 )\n\t\t};\n\n\t},\n\n\t_getRelativeOffset: function() {\n\n\t\tif ( this.cssPosition === \"relative\" ) {\n\t\t\tvar p = this.currentItem.position();\n\t\t\treturn {\n\t\t\t\ttop: p.top - ( parseInt( this.helper.css( \"top\" ), 10 ) || 0 ) +\n\t\t\t\t\tthis.scrollParent.scrollTop(),\n\t\t\t\tleft: p.left - ( parseInt( this.helper.css( \"left\" ), 10 ) || 0 ) +\n\t\t\t\t\tthis.scrollParent.scrollLeft()\n\t\t\t};\n\t\t} else {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t},\n\n\t_cacheMargins: function() {\n\t\tthis.margins = {\n\t\t\tleft: ( parseInt( this.currentItem.css( \"marginLeft\" ), 10 ) || 0 ),\n\t\t\ttop: ( parseInt( this.currentItem.css( \"marginTop\" ), 10 ) || 0 )\n\t\t};\n\t},\n\n\t_cacheHelperProportions: function() {\n\t\tthis.helperProportions = {\n\t\t\twidth: this.helper.outerWidth(),\n\t\t\theight: this.helper.outerHeight()\n\t\t};\n\t},\n\n\t_setContainment: function() {\n\n\t\tvar ce, co, over,\n\t\t\to = this.options;\n\t\tif ( o.containment === \"parent\" ) {\n\t\t\to.containment = this.helper[ 0 ].parentNode;\n\t\t}\n\t\tif ( o.containment === \"document\" || o.containment === \"window\" ) {\n\t\t\tthis.containment = [\n\t\t\t\t0 - this.offset.relative.left - this.offset.parent.left,\n\t\t\t\t0 - this.offset.relative.top - this.offset.parent.top,\n\t\t\t\to.containment === \"document\" ?\n\t\t\t\t\tthis.document.width() :\n\t\t\t\t\tthis.window.width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t( o.containment === \"document\" ?\n\t\t\t\t\t( this.document.height() || document.body.parentNode.scrollHeight ) :\n\t\t\t\t\tthis.window.height() || this.document[ 0 ].body.parentNode.scrollHeight\n\t\t\t\t) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t\tif ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {\n\t\t\tce = $( o.containment )[ 0 ];\n\t\t\tco = $( o.containment ).offset();\n\t\t\tover = ( $( ce ).css( \"overflow\" ) !== \"hidden\" );\n\n\t\t\tthis.containment = [\n\t\t\t\tco.left + ( parseInt( $( ce ).css( \"borderLeftWidth\" ), 10 ) || 0 ) +\n\t\t\t\t\t( parseInt( $( ce ).css( \"paddingLeft\" ), 10 ) || 0 ) - this.margins.left,\n\t\t\t\tco.top + ( parseInt( $( ce ).css( \"borderTopWidth\" ), 10 ) || 0 ) +\n\t\t\t\t\t( parseInt( $( ce ).css( \"paddingTop\" ), 10 ) || 0 ) - this.margins.top,\n\t\t\t\tco.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -\n\t\t\t\t\t( parseInt( $( ce ).css( \"borderLeftWidth\" ), 10 ) || 0 ) -\n\t\t\t\t\t( parseInt( $( ce ).css( \"paddingRight\" ), 10 ) || 0 ) -\n\t\t\t\t\tthis.helperProportions.width - this.margins.left,\n\t\t\t\tco.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -\n\t\t\t\t\t( parseInt( $( ce ).css( \"borderTopWidth\" ), 10 ) || 0 ) -\n\t\t\t\t\t( parseInt( $( ce ).css( \"paddingBottom\" ), 10 ) || 0 ) -\n\t\t\t\t\tthis.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t},\n\n\t_convertPositionTo: function( d, pos ) {\n\n\t\tif ( !pos ) {\n\t\t\tpos = this.position;\n\t\t}\n\t\tvar mod = d === \"absolute\" ? 1 : -1,\n\t\t\tscroll = this.cssPosition === \"absolute\" &&\n\t\t\t\t!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&\n\t\t\t\t$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?\n\t\t\t\t\tthis.offsetParent :\n\t\t\t\t\tthis.scrollParent,\n\t\t\tscrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );\n\n\t\treturn {\n\t\t\ttop: (\n\n\t\t\t\t// The absolute mouse position\n\t\t\t\tpos.top\t+\n\n\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.relative.top * mod +\n\n\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\tthis.offset.parent.top * mod -\n\t\t\t\t( ( this.cssPosition === \"fixed\" ?\n\t\t\t\t\t-this.scrollParent.scrollTop() :\n\t\t\t\t\t( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )\n\t\t\t),\n\t\t\tleft: (\n\n\t\t\t\t// The absolute mouse position\n\t\t\t\tpos.left +\n\n\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.relative.left * mod +\n\n\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\tthis.offset.parent.left * mod\t-\n\t\t\t\t( ( this.cssPosition === \"fixed\" ?\n\t\t\t\t\t-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :\n\t\t\t\t\tscroll.scrollLeft() ) * mod )\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_generatePosition: function( event ) {\n\n\t\tvar top, left,\n\t\t\to = this.options,\n\t\t\tpageX = event.pageX,\n\t\t\tpageY = event.pageY,\n\t\t\tscroll = this.cssPosition === \"absolute\" &&\n\t\t\t\t!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&\n\t\t\t\t$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?\n\t\t\t\t\tthis.offsetParent :\n\t\t\t\t\tthis.scrollParent,\n\t\t\t\tscrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );\n\n\t\t// This is another very weird special case that only happens for relative elements:\n\t\t// 1. If the css position is relative\n\t\t// 2. and the scroll parent is the document or similar to the offset parent\n\t\t// we have to refresh the relative offset during the scroll so there are no jumps\n\t\tif ( this.cssPosition === \"relative\" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&\n\t\t\t\tthis.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {\n\t\t\tthis.offset.relative = this._getRelativeOffset();\n\t\t}\n\n\t\t/*\n\t\t * - Position constraining -\n\t\t * Constrain the position to a mix of grid, containment.\n\t\t */\n\n\t\tif ( this.originalPosition ) { //If we are not dragging yet, we won't check for options\n\n\t\t\tif ( this.containment ) {\n\t\t\t\tif ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {\n\t\t\t\t\tpageX = this.containment[ 0 ] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {\n\t\t\t\t\tpageY = this.containment[ 1 ] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t\tif ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {\n\t\t\t\t\tpageX = this.containment[ 2 ] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {\n\t\t\t\t\tpageY = this.containment[ 3 ] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( o.grid ) {\n\t\t\t\ttop = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /\n\t\t\t\t\to.grid[ 1 ] ) * o.grid[ 1 ];\n\t\t\t\tpageY = this.containment ?\n\t\t\t\t\t( ( top - this.offset.click.top >= this.containment[ 1 ] &&\n\t\t\t\t\t\ttop - this.offset.click.top <= this.containment[ 3 ] ) ?\n\t\t\t\t\t\t\ttop :\n\t\t\t\t\t\t\t( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?\n\t\t\t\t\t\t\t\ttop - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :\n\t\t\t\t\t\t\t\ttop;\n\n\t\t\t\tleft = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /\n\t\t\t\t\to.grid[ 0 ] ) * o.grid[ 0 ];\n\t\t\t\tpageX = this.containment ?\n\t\t\t\t\t( ( left - this.offset.click.left >= this.containment[ 0 ] &&\n\t\t\t\t\t\tleft - this.offset.click.left <= this.containment[ 2 ] ) ?\n\t\t\t\t\t\t\tleft :\n\t\t\t\t\t\t\t( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?\n\t\t\t\t\t\t\t\tleft - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :\n\t\t\t\t\t\t\t\tleft;\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\n\t\t\t\t// The absolute mouse position\n\t\t\t\tpageY -\n\n\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.click.top -\n\n\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.relative.top -\n\n\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\tthis.offset.parent.top +\n\t\t\t\t( ( this.cssPosition === \"fixed\" ?\n\t\t\t\t\t-this.scrollParent.scrollTop() :\n\t\t\t\t\t( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )\n\t\t\t),\n\t\t\tleft: (\n\n\t\t\t\t// The absolute mouse position\n\t\t\t\tpageX -\n\n\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.click.left -\n\n\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.relative.left -\n\n\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\tthis.offset.parent.left +\n\t\t\t\t( ( this.cssPosition === \"fixed\" ?\n\t\t\t\t\t-this.scrollParent.scrollLeft() :\n\t\t\t\t\tscrollIsRootNode ? 0 : scroll.scrollLeft() ) )\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_rearrange: function( event, i, a, hardRefresh ) {\n\n\t\ta ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :\n\t\t\ti.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],\n\t\t\t\t( this.direction === \"down\" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );\n\n\t\t//Various things done here to improve the performance:\n\t\t// 1. we create a setTimeout, that calls refreshPositions\n\t\t// 2. on the instance, we have a counter variable, that get's higher after every append\n\t\t// 3. on the local scope, we copy the counter variable, and check in the timeout,\n\t\t// if it's still the same\n\t\t// 4. this lets only the last addition to the timeout stack through\n\t\tthis.counter = this.counter ? ++this.counter : 1;\n\t\tvar counter = this.counter;\n\n\t\tthis._delay( function() {\n\t\t\tif ( counter === this.counter ) {\n\n\t\t\t\t//Precompute after each DOM insertion, NOT on mousemove\n\t\t\t\tthis.refreshPositions( !hardRefresh );\n\t\t\t}\n\t\t} );\n\n\t},\n\n\t_clear: function( event, noPropagation ) {\n\n\t\tthis.reverting = false;\n\n\t\t// We delay all events that have to be triggered to after the point where the placeholder\n\t\t// has been removed and everything else normalized again\n\t\tvar i,\n\t\t\tdelayedTriggers = [];\n\n\t\t// We first have to update the dom position of the actual currentItem\n\t\t// Note: don't do it if the current item is already removed (by a user), or it gets\n\t\t// reappended (see #4088)\n\t\tif ( !this._noFinalSort && this.currentItem.parent().length ) {\n\t\t\tthis.placeholder.before( this.currentItem );\n\t\t}\n\t\tthis._noFinalSort = null;\n\n\t\tif ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {\n\t\t\tfor ( i in this._storedCSS ) {\n\t\t\t\tif ( this._storedCSS[ i ] === \"auto\" || this._storedCSS[ i ] === \"static\" ) {\n\t\t\t\t\tthis._storedCSS[ i ] = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.currentItem.css( this._storedCSS );\n\t\t\tthis._removeClass( this.currentItem, \"ui-sortable-helper\" );\n\t\t} else {\n\t\t\tthis.currentItem.show();\n\t\t}\n\n\t\tif ( this.fromOutside && !noPropagation ) {\n\t\t\tdelayedTriggers.push( function( event ) {\n\t\t\t\tthis._trigger( \"receive\", event, this._uiHash( this.fromOutside ) );\n\t\t\t} );\n\t\t}\n\t\tif ( ( this.fromOutside ||\n\t\t\t\tthis.domPosition.prev !==\n\t\t\t\tthis.currentItem.prev().not( \".ui-sortable-helper\" )[ 0 ] ||\n\t\t\t\tthis.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {\n\n\t\t\t// Trigger update callback if the DOM position has changed\n\t\t\tdelayedTriggers.push( function( event ) {\n\t\t\t\tthis._trigger( \"update\", event, this._uiHash() );\n\t\t\t} );\n\t\t}\n\n\t\t// Check if the items Container has Changed and trigger appropriate\n\t\t// events.\n\t\tif ( this !== this.currentContainer ) {\n\t\t\tif ( !noPropagation ) {\n\t\t\t\tdelayedTriggers.push( function( event ) {\n\t\t\t\t\tthis._trigger( \"remove\", event, this._uiHash() );\n\t\t\t\t} );\n\t\t\t\tdelayedTriggers.push( ( function( c ) {\n\t\t\t\t\treturn function( event ) {\n\t\t\t\t\t\tc._trigger( \"receive\", event, this._uiHash( this ) );\n\t\t\t\t\t};\n\t\t\t\t} ).call( this, this.currentContainer ) );\n\t\t\t\tdelayedTriggers.push( ( function( c ) {\n\t\t\t\t\treturn function( event ) {\n\t\t\t\t\t\tc._trigger( \"update\", event, this._uiHash( this ) );\n\t\t\t\t\t};\n\t\t\t\t} ).call( this, this.currentContainer ) );\n\t\t\t}\n\t\t}\n\n\t\t//Post events to containers\n\t\tfunction delayEvent( type, instance, container ) {\n\t\t\treturn function( event ) {\n\t\t\t\tcontainer._trigger( type, event, instance._uiHash( instance ) );\n\t\t\t};\n\t\t}\n\t\tfor ( i = this.containers.length - 1; i >= 0; i-- ) {\n\t\t\tif ( !noPropagation ) {\n\t\t\t\tdelayedTriggers.push( delayEvent( \"deactivate\", this, this.containers[ i ] ) );\n\t\t\t}\n\t\t\tif ( this.containers[ i ].containerCache.over ) {\n\t\t\t\tdelayedTriggers.push( delayEvent( \"out\", this, this.containers[ i ] ) );\n\t\t\t\tthis.containers[ i ].containerCache.over = 0;\n\t\t\t}\n\t\t}\n\n\t\t//Do what was originally in plugins\n\t\tif ( this.storedCursor ) {\n\t\t\tthis.document.find( \"body\" ).css( \"cursor\", this.storedCursor );\n\t\t\tthis.storedStylesheet.remove();\n\t\t}\n\t\tif ( this._storedOpacity ) {\n\t\t\tthis.helper.css( \"opacity\", this._storedOpacity );\n\t\t}\n\t\tif ( this._storedZIndex ) {\n\t\t\tthis.helper.css( \"zIndex\", this._storedZIndex === \"auto\" ? \"\" : this._storedZIndex );\n\t\t}\n\n\t\tthis.dragging = false;\n\n\t\tif ( !noPropagation ) {\n\t\t\tthis._trigger( \"beforeStop\", event, this._uiHash() );\n\t\t}\n\n\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,\n\t\t// it unbinds ALL events from the original node!\n\t\tthis.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );\n\n\t\tif ( !this.cancelHelperRemoval ) {\n\t\t\tif ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {\n\t\t\t\tthis.helper.remove();\n\t\t\t}\n\t\t\tthis.helper = null;\n\t\t}\n\n\t\tif ( !noPropagation ) {\n\t\t\tfor ( i = 0; i < delayedTriggers.length; i++ ) {\n\n\t\t\t\t// Trigger all delayed events\n\t\t\t\tdelayedTriggers[ i ].call( this, event );\n\t\t\t}\n\t\t\tthis._trigger( \"stop\", event, this._uiHash() );\n\t\t}\n\n\t\tthis.fromOutside = false;\n\t\treturn !this.cancelHelperRemoval;\n\n\t},\n\n\t_trigger: function() {\n\t\tif ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {\n\t\t\tthis.cancel();\n\t\t}\n\t},\n\n\t_uiHash: function( _inst ) {\n\t\tvar inst = _inst || this;\n\t\treturn {\n\t\t\thelper: inst.helper,\n\t\t\tplaceholder: inst.placeholder || $( [] ),\n\t\t\tposition: inst.position,\n\t\t\toriginalPosition: inst.originalPosition,\n\t\t\toffset: inst.positionAbs,\n\t\t\titem: inst.currentItem,\n\t\t\tsender: _inst ? _inst.element : null\n\t\t};\n\t}\n\n} );\n\n} ) );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/jquery3.js",
    "content": "/*!\n * jQuery JavaScript Library v3.6.0\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright OpenJS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2021-03-02T17:08Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar flat = arr.flat ? function( array ) {\n\treturn arr.flat.call( array );\n} : function( array ) {\n\treturn arr.concat.apply( [], array );\n};\n\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n\t\t// Support: Chrome <=57, Firefox <=52\n\t\t// In some browsers, typeof returns \"function\" for HTML <object> elements\n\t\t// (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n\t\t// We don't want to classify *any* DOM node as a function.\n\t\t// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5\n\t\t// Plus for old WebKit, typeof returns \"function\" for HTML collections\n\t\t// (e.g., `typeof document.getElementsByTagName(\"div\") === \"function\"`). (gh-4756)\n\t\treturn typeof obj === \"function\" && typeof obj.nodeType !== \"number\" &&\n\t\t\ttypeof obj.item !== \"function\";\n\t};\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\nvar document = window.document;\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.6.0\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teven: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn ( i + 1 ) % 2;\n\t\t} ) );\n\t},\n\n\todd: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn i % 2;\n\t\t} ) );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a provided context; falls back to the global one\n\t// if not specified.\n\tglobalEval: function( code, options, doc ) {\n\t\tDOMEval( code, { nonce: options && options.nonce }, doc );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn flat( ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\n\tfunction( _i, name ) {\n\t\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n\t} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.6\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2021-02-16\n */\n( function( window ) {\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ( {} ).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpushNative = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|\" +\n\t\t\"ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n\tidentifier = \"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace +\n\t\t\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\n\t\t// \"Attribute values must be CSS identifiers [capture 5]\n\t\t// or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" +\n\t\twhitespace + \"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" +\n\t\twhitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace +\n\t\t\"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" +\n\t\t\twhitespace + \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" +\n\t\t\twhitespace + \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace +\n\t\t\t\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n\t\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace + \"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\", \"g\" ),\n\tfunescape = function( escape, nonHex ) {\n\t\tvar high = \"0x\" + escape.slice( 1 ) - 0x10000;\n\n\t\treturn nonHex ?\n\n\t\t\t// Strip the backslash prefix from a non-hex escape sequence\n\t\t\tnonHex :\n\n\t\t\t// Replace a hexadecimal escape sequence with the encoded Unicode code point\n\t\t\t// Support: IE <=11+\n\t\t\t// For values outside the Basic Multilingual Plane (BMP), manually construct a\n\t\t\t// surrogate pair\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" +\n\t\t\t\tch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t( arr = slice.call( preferredDoc.childNodes ) ),\n\t\tpreferredDoc.childNodes\n\t);\n\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\t// eslint-disable-next-line no-unused-expressions\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpushNative.apply( target, slice.call( els ) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( ( target[ j++ ] = els[ i++ ] ) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\t\tsetDocument( context );\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( ( m = match[ 1 ] ) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( ( elem = context.getElementById( m ) ) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && ( elem = newContext.getElementById( m ) ) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[ 2 ] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t( nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\" ) ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// The technique has to be used as well when a leading combinator is used\n\t\t\t\t// as such selectors are not recognized by querySelectorAll.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 &&\n\t\t\t\t\t( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\n\t\t\t\t\t// We can use :scope instead of the ID hack if the browser\n\t\t\t\t\t// supports it & if we're not changing the context.\n\t\t\t\t\tif ( newContext !== context || !support.scope ) {\n\n\t\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\t\tif ( ( nid = context.getAttribute( \"id\" ) ) ) {\n\t\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontext.setAttribute( \"id\", ( nid = expando ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[ i ] = ( nid ? \"#\" + nid : \":scope\" ) + \" \" +\n\t\t\t\t\t\t\ttoSelector( groups[ i ] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn ( cache[ key + \" \" ] = value );\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement( \"fieldset\" );\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch ( e ) {\n\t\treturn false;\n\t} finally {\n\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split( \"|\" ),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[ i ] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( ( cur = cur.nextSibling ) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn ( name === \"input\" || name === \"button\" ) && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction( function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction( function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ ( j = matchIndexes[ i ] ) ] ) {\n\t\t\t\t\tseed[ j ] = !( matches[ j ] = seed[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem && elem.namespaceURI,\n\t\tdocElem = elem && ( elem.ownerDocument || elem ).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( preferredDoc != document &&\n\t\t( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,\n\t// Safari 4 - 5 only, Opera <=11.6 - 12.x only\n\t// IE/Edge & older browsers don't support the :scope pseudo-class.\n\t// Support: Safari 6.0 only\n\t// Safari 6.0 supports :scope but it's an alias of :root there.\n\tsupport.scope = assert( function( el ) {\n\t\tdocElem.appendChild( el ).appendChild( document.createElement( \"div\" ) );\n\t\treturn typeof el.querySelectorAll !== \"undefined\" &&\n\t\t\t!el.querySelectorAll( \":scope fieldset div\" ).length;\n\t} );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert( function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute( \"className\" );\n\t} );\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert( function( el ) {\n\t\tel.appendChild( document.createComment( \"\" ) );\n\t\treturn !el.getElementsByTagName( \"*\" ).length;\n\t} );\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert( function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t} );\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[ \"ID\" ] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute( \"id\" ) === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[ \"ID\" ] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode( \"id\" );\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( ( elem = elems[ i++ ] ) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[ \"TAG\" ] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[ \"CLASS\" ] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {\n\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert( function( el ) {\n\n\t\t\tvar input;\n\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll( \"[msallowcapture^='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll( \"[selected]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"~=\" );\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 15 - 18+\n\t\t\t// IE 11/Edge don't find elements on a `[name='']` query in some cases.\n\t\t\t// Adding a temporary attribute to the document before the selection works\n\t\t\t// around the issue.\n\t\t\t// Interestingly, IE 10 & older don't seem to have the issue.\n\t\t\tinput = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"name\", \"\" );\n\t\t\tel.appendChild( input );\n\t\t\tif ( !el.querySelectorAll( \"[name='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*name\" + whitespace + \"*=\" +\n\t\t\t\t\twhitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll( \":checked\" ).length ) {\n\t\t\t\trbuggyQSA.push( \":checked\" );\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push( \".#.+[+~]\" );\n\t\t\t}\n\n\t\t\t// Support: Firefox <=3.6 - 5 only\n\t\t\t// Old Firefox doesn't throw on a badly-escaped identifier.\n\t\t\tel.querySelectorAll( \"\\\\\\f\" );\n\t\t\trbuggyQSA.push( \"[\\\\r\\\\n\\\\f]\" );\n\t\t} );\n\n\t\tassert( function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll( \"[name=d]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll( \":enabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll( \":disabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: Opera 10 - 11 only\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll( \"*,:x\" );\n\t\t\trbuggyQSA.push( \",.*:\" );\n\t\t} );\n\t}\n\n\tif ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector ) ) ) ) {\n\n\t\tassert( function( el ) {\n\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t} );\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( \"|\" ) );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( \"|\" ) );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t) );\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( ( b = b.parentNode ) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tcompare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( a == document || a.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, a ) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( b == document || b.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, b ) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\treturn a == document ? -1 :\n\t\t\t\tb == document ? 1 :\n\t\t\t\t/* eslint-enable eqeqeq */\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[ i ] === bp[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[ i ], bp[ i ] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\tap[ i ] == preferredDoc ? -1 :\n\t\t\tbp[ i ] == preferredDoc ? 1 :\n\t\t\t/* eslint-enable eqeqeq */\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tsetDocument( elem );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\n\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t// fragment in IE 9\n\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( context.ownerDocument || context ) != document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( elem.ownerDocument || elem ) != document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn ( sel + \"\" ).replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( ( node = elem[ i++ ] ) ) {\n\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[ 1 ] = match[ 1 ].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[ 3 ] = ( match[ 3 ] || match[ 4 ] ||\n\t\t\t\tmatch[ 5 ] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[ 2 ] === \"~=\" ) {\n\t\t\t\tmatch[ 3 ] = \" \" + match[ 3 ] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[ 1 ] = match[ 1 ].toLowerCase();\n\n\t\t\tif ( match[ 1 ].slice( 0, 3 ) === \"nth\" ) {\n\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[ 3 ] ) {\n\t\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[ 4 ] = +( match[ 4 ] ?\n\t\t\t\t\tmatch[ 5 ] + ( match[ 6 ] || 1 ) :\n\t\t\t\t\t2 * ( match[ 3 ] === \"even\" || match[ 3 ] === \"odd\" ) );\n\t\t\t\tmatch[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === \"odd\" );\n\n\t\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[ 3 ] ) {\n\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[ 6 ] && match[ 2 ];\n\n\t\t\tif ( matchExpr[ \"CHILD\" ].test( match[ 0 ] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[ 3 ] ) {\n\t\t\t\tmatch[ 2 ] = match[ 4 ] || match[ 5 ] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t( excess = tokenize( unquoted, true ) ) &&\n\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t( excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length ) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[ 0 ] = match[ 0 ].slice( 0, excess );\n\t\t\t\tmatch[ 2 ] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() {\n\t\t\t\t\treturn true;\n\t\t\t\t} :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t( pattern = new RegExp( \"(^|\" + whitespace +\n\t\t\t\t\t\")\" + className + \"(\" + whitespace + \"|$)\" ) ) && classCache(\n\t\t\t\t\t\tclassName, function( elem ) {\n\t\t\t\t\t\t\treturn pattern.test(\n\t\t\t\t\t\t\t\ttypeof elem.className === \"string\" && elem.className ||\n\t\t\t\t\t\t\t\ttypeof elem.getAttribute !== \"undefined\" &&\n\t\t\t\t\t\t\t\t\telem.getAttribute( \"class\" ) ||\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\t/* eslint-disable max-len */\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t\t/* eslint-enable max-len */\n\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, _argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( ( node = node[ dir ] ) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction( function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[ i ] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction( function( selector ) {\n\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction( function( seed, matches, _context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\t\t\t\t\tseed[ i ] = !( matches[ i ] = elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} ) :\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tinput[ 0 ] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[ 0 ] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t} ),\n\n\t\t\"has\": markFunction( function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t} ),\n\n\t\t\"contains\": markFunction( function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t} ),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test( lang || \"\" ) ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( ( elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute( \"xml:lang\" ) || elem.getAttribute( \"lang\" ) ) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t} ),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement &&\n\t\t\t\t( !document.hasFocus || document.hasFocus() ) &&\n\t\t\t\t!!( elem.type || elem.href || ~elem.tabIndex );\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn ( nodeName === \"input\" && !!elem.checked ) ||\n\t\t\t\t( nodeName === \"option\" && !!elem.selected );\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\t// eslint-disable-next-line no-unused-expressions\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[ \"empty\" ]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( ( attr = elem.getAttribute( \"type\" ) ) == null ||\n\t\t\t\t\tattr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo( function() {\n\t\t\treturn [ 0 ];\n\t\t} ),\n\n\t\t\"last\": createPositionalPseudo( function( _matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t} ),\n\n\t\t\"eq\": createPositionalPseudo( function( _matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t} ),\n\n\t\t\"even\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"odd\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"lt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"gt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} )\n\t}\n};\n\nExpr.pseudos[ \"nth\" ] = Expr.pseudos[ \"eq\" ];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || ( match = rcomma.exec( soFar ) ) ) {\n\t\t\tif ( match ) {\n\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[ 0 ].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( ( tokens = [] ) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( ( match = rcombinators.exec( soFar ) ) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push( {\n\t\t\t\tvalue: matched,\n\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[ 0 ].replace( rtrim, \" \" )\n\t\t\t} );\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||\n\t\t\t\t( match = preFilters[ type ]( match ) ) ) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push( {\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t} );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[ i ].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] ||\n\t\t\t\t\t\t\t( outerCache[ elem.uniqueID ] = {} );\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( ( oldCache = uniqueCache[ key ] ) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn ( newCache[ 2 ] = oldCache[ 2 ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[ i ]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[ 0 ];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[ i ], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction( function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts(\n\t\t\t\tselector || \"*\",\n\t\t\t\tcontext.nodeType ? [ context ] : context,\n\t\t\t\t[]\n\t\t\t),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( ( elem = temp[ i ] ) ) {\n\t\t\t\t\tmatcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) ) {\n\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( ( matcherIn[ i ] = elem ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, ( matcherOut = [] ), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) &&\n\t\t\t\t\t\t( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {\n\n\t\t\t\t\t\tseed[ temp ] = !( results[ temp ] = elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t} );\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[ 0 ].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[ \" \" ],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t( checkContext = context ).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[ j ].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\n\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\ttokens\n\t\t\t\t\t\t.slice( 0, i - 1 )\n\t\t\t\t\t\t.concat( { value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" } )\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[ \"TAG\" ]( \"*\", outermost ),\n\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\n\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\toutermostContext = context == document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( !context && elem.ownerDocument != document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( ( matcher = elementMatchers[ j++ ] ) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( ( elem = !matcher && elem ) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( ( matcher = setMatchers[ j++ ] ) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !( unmatched[ i ] || setMatched[ i ] ) ) {\n\t\t\t\t\t\t\t\tsetMatched[ i ] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[ i ] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache(\n\t\t\tselector,\n\t\t\tmatcherFromGroupMatchers( elementMatchers, setMatchers )\n\t\t);\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( ( selector = compiled.selector || selector ) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[ 0 ] = match[ 0 ].slice( 0 );\n\t\tif ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === \"ID\" &&\n\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {\n\n\t\t\tcontext = ( Expr.find[ \"ID\" ]( token.matches[ 0 ]\n\t\t\t\t.replace( runescape, funescape ), context ) || [] )[ 0 ];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[ \"needsContext\" ].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[ i ];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ ( type = token.type ) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( ( find = Expr.find[ type ] ) ) {\n\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( ( seed = find(\n\t\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext\n\t\t\t\t) ) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split( \"\" ).sort( sortOrder ).join( \"\" ) === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert( function( el ) {\n\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement( \"fieldset\" ) ) & 1;\n} );\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert( function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute( \"href\" ) === \"#\";\n} ) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert( function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n} ) ) {\n\taddHandle( \"value\", function( elem, _name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert( function( el ) {\n\treturn el.getAttribute( \"disabled\" ) == null;\n} ) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\t\tnull;\n\t\t}\n\t} );\n}\n\nreturn Sizzle;\n\n} )( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n}\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( elem.contentDocument != null &&\n\n\t\t\t// Support: IE 11+\n\t\t\t// <object> elements with no `data` attribute has an object\n\t\t\t// `contentDocument` with a `null` prototype.\n\t\t\tgetProto( elem.contentDocument ) ) {\n\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( _i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the primary Deferred\n\t\t\tprimary = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tprimary.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( primary.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn primary.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );\n\t\t}\n\n\t\treturn primary.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, _key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\t\tvalue :\n\t\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( _all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces <option> tags with their contents when inserted outside of\n\t// the select element.\n\tdiv.innerHTML = \"<option></option>\";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, \"<select multiple='multiple'>\", \"</select>\" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar rtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\tdataPriv.get( this, \"events\" ) || Object.create( null )\n\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\t\t// Support: Chrome 86+\n\t\t\t\t\t\t// In Chrome, if an element having a focusout handler is blurred by\n\t\t\t\t\t\t// clicking outside of it, it invokes the handler synchronously. If\n\t\t\t\t\t\t// that handler calls `.remove()` on the element, the data is cleared,\n\t\t\t\t\t\t// leaving `result` undefined. We need to guard against this.\n\t\t\t\t\t\treturn result && result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\twhich: true\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\t// Suppress native focus or blur as it's already being fired\n\t\t// in leverageNative.\n\t\t_default: function() {\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, \"handle events\" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\t//\n\t\t// Support: Firefox 70+\n\t\t// Only Firefox includes border widths\n\t\t// in computed dimensions. (gh-4529)\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( \"table\" );\n\t\t\t\ttr = document.createElement( \"tr\" );\n\t\t\t\ttrChild = document.createElement( \"div\" );\n\n\t\t\t\ttable.style.cssText = \"position:absolute;left:-11111px;border-collapse:separate\";\n\t\t\t\ttr.style.cssText = \"border:1px solid\";\n\n\t\t\t\t// Support: Chrome 86+\n\t\t\t\t// Height set through cssText does not get applied.\n\t\t\t\t// Computed height then comes back as 0.\n\t\t\t\ttr.style.height = \"1px\";\n\t\t\t\ttrChild.style.height = \"9px\";\n\n\t\t\t\t// Support: Android 8 Chrome 86+\n\t\t\t\t// In our bodyBackground.html iframe,\n\t\t\t\t// display for all div elements is set to \"inline\",\n\t\t\t\t// which causes a problem only in Android 8 Chrome 86.\n\t\t\t\t// Ensuring the div is display: block\n\t\t\t\t// gets around this issue.\n\t\t\t\ttrChild.style.display = \"block\";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderTopWidth, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Interestingly, in some cases IE 9 doesn't suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, \"tr\" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === \"auto\" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t} ) :\n\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\n\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || Object.create( null ) )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\n\t\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, parserErrorElem;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {}\n\n\tparserErrorElem = xml && xml.getElementsByTagName( \"parsererror\" )[ 0 ];\n\tif ( !xml || parserErrorElem ) {\n\t\tjQuery.error( \"Invalid XML: \" + (\n\t\t\tparserErrorElem ?\n\t\t\t\tjQuery.map( parserErrorElem.childNodes, function( el ) {\n\t\t\t\t\treturn el.textContent;\n\t\t\t\t} ).join( \"\\n\" ) :\n\t\t\t\tdata\n\t\t) );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} ).filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} ).map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\noriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script but not if jsonp\n\t\t\tif ( !isSuccess &&\n\t\t\t\tjQuery.inArray( \"script\", s.dataTypes ) > -1 &&\n\t\t\t\tjQuery.inArray( \"json\", s.dataTypes ) < 0 ) {\n\t\t\t\ts.converters[ \"text script\" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === \"content-type\" ) {\n\t\t\ts.contentType = s.headers[ i ] || \"\";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce.guid++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( _i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( {\n\t\tpadding: \"inner\" + name,\n\t\tcontent: type,\n\t\t\"\": \"outer\" + name\n\t}, function( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( _i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\njQuery.each(\n\t( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( _i, name ) {\n\n\t\t// Handle event binding\n\t\tjQuery.fn[ name ] = function( data, fn ) {\n\t\t\treturn arguments.length > 0 ?\n\t\t\t\tthis.on( name, null, data, fn ) :\n\t\t\t\tthis.trigger( name );\n\t\t};\n\t}\n);\n\n\n\n\n// Support: Android <=4.0 only\n// Make sure we trim BOM and NBSP\nvar rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\njQuery.trim = function( text ) {\n\treturn text == null ?\n\t\t\"\" :\n\t\t( text + \"\" ).replace( rtrim, \"\" );\n};\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === \"undefined\" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "vendor/assets/javascripts/rails_admin/popper.js",
    "content": "/**\n * @popperjs/core v2.11.0 - MIT License\n */\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Popper = {}));\n}(this, (function (exports) { 'use strict';\n\n  function getWindow(node) {\n    if (node == null) {\n      return window;\n    }\n\n    if (node.toString() !== '[object Window]') {\n      var ownerDocument = node.ownerDocument;\n      return ownerDocument ? ownerDocument.defaultView || window : window;\n    }\n\n    return node;\n  }\n\n  function isElement(node) {\n    var OwnElement = getWindow(node).Element;\n    return node instanceof OwnElement || node instanceof Element;\n  }\n\n  function isHTMLElement(node) {\n    var OwnElement = getWindow(node).HTMLElement;\n    return node instanceof OwnElement || node instanceof HTMLElement;\n  }\n\n  function isShadowRoot(node) {\n    // IE 11 has no ShadowRoot\n    if (typeof ShadowRoot === 'undefined') {\n      return false;\n    }\n\n    var OwnElement = getWindow(node).ShadowRoot;\n    return node instanceof OwnElement || node instanceof ShadowRoot;\n  }\n\n  var max = Math.max;\n  var min = Math.min;\n  var round = Math.round;\n\n  function getBoundingClientRect(element, includeScale) {\n    if (includeScale === void 0) {\n      includeScale = false;\n    }\n\n    var rect = element.getBoundingClientRect();\n    var scaleX = 1;\n    var scaleY = 1;\n\n    if (isHTMLElement(element) && includeScale) {\n      var offsetHeight = element.offsetHeight;\n      var offsetWidth = element.offsetWidth; // Do not attempt to divide by 0, otherwise we get `Infinity` as scale\n      // Fallback to 1 in case both values are `0`\n\n      if (offsetWidth > 0) {\n        scaleX = round(rect.width) / offsetWidth || 1;\n      }\n\n      if (offsetHeight > 0) {\n        scaleY = round(rect.height) / offsetHeight || 1;\n      }\n    }\n\n    return {\n      width: rect.width / scaleX,\n      height: rect.height / scaleY,\n      top: rect.top / scaleY,\n      right: rect.right / scaleX,\n      bottom: rect.bottom / scaleY,\n      left: rect.left / scaleX,\n      x: rect.left / scaleX,\n      y: rect.top / scaleY\n    };\n  }\n\n  function getWindowScroll(node) {\n    var win = getWindow(node);\n    var scrollLeft = win.pageXOffset;\n    var scrollTop = win.pageYOffset;\n    return {\n      scrollLeft: scrollLeft,\n      scrollTop: scrollTop\n    };\n  }\n\n  function getHTMLElementScroll(element) {\n    return {\n      scrollLeft: element.scrollLeft,\n      scrollTop: element.scrollTop\n    };\n  }\n\n  function getNodeScroll(node) {\n    if (node === getWindow(node) || !isHTMLElement(node)) {\n      return getWindowScroll(node);\n    } else {\n      return getHTMLElementScroll(node);\n    }\n  }\n\n  function getNodeName(element) {\n    return element ? (element.nodeName || '').toLowerCase() : null;\n  }\n\n  function getDocumentElement(element) {\n    // $FlowFixMe[incompatible-return]: assume body is always available\n    return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n    element.document) || window.document).documentElement;\n  }\n\n  function getWindowScrollBarX(element) {\n    // If <html> has a CSS width greater than the viewport, then this will be\n    // incorrect for RTL.\n    // Popper 1 is broken in this case and never had a bug report so let's assume\n    // it's not an issue. I don't think anyone ever specifies width on <html>\n    // anyway.\n    // Browsers where the left scrollbar doesn't cause an issue report `0` for\n    // this (e.g. Edge 2019, IE11, Safari)\n    return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n  }\n\n  function getComputedStyle(element) {\n    return getWindow(element).getComputedStyle(element);\n  }\n\n  function isScrollParent(element) {\n    // Firefox wants us to check `-x` and `-y` variations as well\n    var _getComputedStyle = getComputedStyle(element),\n        overflow = _getComputedStyle.overflow,\n        overflowX = _getComputedStyle.overflowX,\n        overflowY = _getComputedStyle.overflowY;\n\n    return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n  }\n\n  function isElementScaled(element) {\n    var rect = element.getBoundingClientRect();\n    var scaleX = round(rect.width) / element.offsetWidth || 1;\n    var scaleY = round(rect.height) / element.offsetHeight || 1;\n    return scaleX !== 1 || scaleY !== 1;\n  } // Returns the composite rect of an element relative to its offsetParent.\n  // Composite means it takes into account transforms as well as layout.\n\n\n  function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n    if (isFixed === void 0) {\n      isFixed = false;\n    }\n\n    var isOffsetParentAnElement = isHTMLElement(offsetParent);\n    var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n    var documentElement = getDocumentElement(offsetParent);\n    var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled);\n    var scroll = {\n      scrollLeft: 0,\n      scrollTop: 0\n    };\n    var offsets = {\n      x: 0,\n      y: 0\n    };\n\n    if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n      if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n      isScrollParent(documentElement)) {\n        scroll = getNodeScroll(offsetParent);\n      }\n\n      if (isHTMLElement(offsetParent)) {\n        offsets = getBoundingClientRect(offsetParent, true);\n        offsets.x += offsetParent.clientLeft;\n        offsets.y += offsetParent.clientTop;\n      } else if (documentElement) {\n        offsets.x = getWindowScrollBarX(documentElement);\n      }\n    }\n\n    return {\n      x: rect.left + scroll.scrollLeft - offsets.x,\n      y: rect.top + scroll.scrollTop - offsets.y,\n      width: rect.width,\n      height: rect.height\n    };\n  }\n\n  // means it doesn't take into account transforms.\n\n  function getLayoutRect(element) {\n    var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n    // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n    var width = element.offsetWidth;\n    var height = element.offsetHeight;\n\n    if (Math.abs(clientRect.width - width) <= 1) {\n      width = clientRect.width;\n    }\n\n    if (Math.abs(clientRect.height - height) <= 1) {\n      height = clientRect.height;\n    }\n\n    return {\n      x: element.offsetLeft,\n      y: element.offsetTop,\n      width: width,\n      height: height\n    };\n  }\n\n  function getParentNode(element) {\n    if (getNodeName(element) === 'html') {\n      return element;\n    }\n\n    return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n      // $FlowFixMe[incompatible-return]\n      // $FlowFixMe[prop-missing]\n      element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n      element.parentNode || ( // DOM Element detected\n      isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n      // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n      getDocumentElement(element) // fallback\n\n    );\n  }\n\n  function getScrollParent(node) {\n    if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n      // $FlowFixMe[incompatible-return]: assume body is always available\n      return node.ownerDocument.body;\n    }\n\n    if (isHTMLElement(node) && isScrollParent(node)) {\n      return node;\n    }\n\n    return getScrollParent(getParentNode(node));\n  }\n\n  /*\n  given a DOM element, return the list of all scroll parents, up the list of ancesors\n  until we get to the top window object. This list is what we attach scroll listeners\n  to, because if any of these parent elements scroll, we'll need to re-calculate the\n  reference element's position.\n  */\n\n  function listScrollParents(element, list) {\n    var _element$ownerDocumen;\n\n    if (list === void 0) {\n      list = [];\n    }\n\n    var scrollParent = getScrollParent(element);\n    var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n    var win = getWindow(scrollParent);\n    var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n    var updatedList = list.concat(target);\n    return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n    updatedList.concat(listScrollParents(getParentNode(target)));\n  }\n\n  function isTableElement(element) {\n    return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n  }\n\n  function getTrueOffsetParent(element) {\n    if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n    getComputedStyle(element).position === 'fixed') {\n      return null;\n    }\n\n    return element.offsetParent;\n  } // `.offsetParent` reports `null` for fixed elements, while absolute elements\n  // return the containing block\n\n\n  function getContainingBlock(element) {\n    var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') !== -1;\n    var isIE = navigator.userAgent.indexOf('Trident') !== -1;\n\n    if (isIE && isHTMLElement(element)) {\n      // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n      var elementCss = getComputedStyle(element);\n\n      if (elementCss.position === 'fixed') {\n        return null;\n      }\n    }\n\n    var currentNode = getParentNode(element);\n\n    while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n      var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n      // create a containing block.\n      // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n      if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n        return currentNode;\n      } else {\n        currentNode = currentNode.parentNode;\n      }\n    }\n\n    return null;\n  } // Gets the closest ancestor positioned element. Handles some edge cases,\n  // such as table ancestors and cross browser bugs.\n\n\n  function getOffsetParent(element) {\n    var window = getWindow(element);\n    var offsetParent = getTrueOffsetParent(element);\n\n    while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {\n      offsetParent = getTrueOffsetParent(offsetParent);\n    }\n\n    if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {\n      return window;\n    }\n\n    return offsetParent || getContainingBlock(element) || window;\n  }\n\n  var top = 'top';\n  var bottom = 'bottom';\n  var right = 'right';\n  var left = 'left';\n  var auto = 'auto';\n  var basePlacements = [top, bottom, right, left];\n  var start = 'start';\n  var end = 'end';\n  var clippingParents = 'clippingParents';\n  var viewport = 'viewport';\n  var popper = 'popper';\n  var reference = 'reference';\n  var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n    return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n  }, []);\n  var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n    return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n  }, []); // modifiers that need to read the DOM\n\n  var beforeRead = 'beforeRead';\n  var read = 'read';\n  var afterRead = 'afterRead'; // pure-logic modifiers\n\n  var beforeMain = 'beforeMain';\n  var main = 'main';\n  var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\n  var beforeWrite = 'beforeWrite';\n  var write = 'write';\n  var afterWrite = 'afterWrite';\n  var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];\n\n  function order(modifiers) {\n    var map = new Map();\n    var visited = new Set();\n    var result = [];\n    modifiers.forEach(function (modifier) {\n      map.set(modifier.name, modifier);\n    }); // On visiting object, check for its dependencies and visit them recursively\n\n    function sort(modifier) {\n      visited.add(modifier.name);\n      var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n      requires.forEach(function (dep) {\n        if (!visited.has(dep)) {\n          var depModifier = map.get(dep);\n\n          if (depModifier) {\n            sort(depModifier);\n          }\n        }\n      });\n      result.push(modifier);\n    }\n\n    modifiers.forEach(function (modifier) {\n      if (!visited.has(modifier.name)) {\n        // check for visited object\n        sort(modifier);\n      }\n    });\n    return result;\n  }\n\n  function orderModifiers(modifiers) {\n    // order based on dependencies\n    var orderedModifiers = order(modifiers); // order based on phase\n\n    return modifierPhases.reduce(function (acc, phase) {\n      return acc.concat(orderedModifiers.filter(function (modifier) {\n        return modifier.phase === phase;\n      }));\n    }, []);\n  }\n\n  function debounce(fn) {\n    var pending;\n    return function () {\n      if (!pending) {\n        pending = new Promise(function (resolve) {\n          Promise.resolve().then(function () {\n            pending = undefined;\n            resolve(fn());\n          });\n        });\n      }\n\n      return pending;\n    };\n  }\n\n  function format(str) {\n    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      args[_key - 1] = arguments[_key];\n    }\n\n    return [].concat(args).reduce(function (p, c) {\n      return p.replace(/%s/, c);\n    }, str);\n  }\n\n  var INVALID_MODIFIER_ERROR = 'Popper: modifier \"%s\" provided an invalid %s property, expected %s but got %s';\n  var MISSING_DEPENDENCY_ERROR = 'Popper: modifier \"%s\" requires \"%s\", but \"%s\" modifier is not available';\n  var VALID_PROPERTIES = ['name', 'enabled', 'phase', 'fn', 'effect', 'requires', 'options'];\n  function validateModifiers(modifiers) {\n    modifiers.forEach(function (modifier) {\n      [].concat(Object.keys(modifier), VALID_PROPERTIES) // IE11-compatible replacement for `new Set(iterable)`\n      .filter(function (value, index, self) {\n        return self.indexOf(value) === index;\n      }).forEach(function (key) {\n        switch (key) {\n          case 'name':\n            if (typeof modifier.name !== 'string') {\n              console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '\"name\"', '\"string\"', \"\\\"\" + String(modifier.name) + \"\\\"\"));\n            }\n\n            break;\n\n          case 'enabled':\n            if (typeof modifier.enabled !== 'boolean') {\n              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '\"enabled\"', '\"boolean\"', \"\\\"\" + String(modifier.enabled) + \"\\\"\"));\n            }\n\n            break;\n\n          case 'phase':\n            if (modifierPhases.indexOf(modifier.phase) < 0) {\n              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '\"phase\"', \"either \" + modifierPhases.join(', '), \"\\\"\" + String(modifier.phase) + \"\\\"\"));\n            }\n\n            break;\n\n          case 'fn':\n            if (typeof modifier.fn !== 'function') {\n              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '\"fn\"', '\"function\"', \"\\\"\" + String(modifier.fn) + \"\\\"\"));\n            }\n\n            break;\n\n          case 'effect':\n            if (modifier.effect != null && typeof modifier.effect !== 'function') {\n              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '\"effect\"', '\"function\"', \"\\\"\" + String(modifier.fn) + \"\\\"\"));\n            }\n\n            break;\n\n          case 'requires':\n            if (modifier.requires != null && !Array.isArray(modifier.requires)) {\n              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '\"requires\"', '\"array\"', \"\\\"\" + String(modifier.requires) + \"\\\"\"));\n            }\n\n            break;\n\n          case 'requiresIfExists':\n            if (!Array.isArray(modifier.requiresIfExists)) {\n              console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '\"requiresIfExists\"', '\"array\"', \"\\\"\" + String(modifier.requiresIfExists) + \"\\\"\"));\n            }\n\n            break;\n\n          case 'options':\n          case 'data':\n            break;\n\n          default:\n            console.error(\"PopperJS: an invalid property has been provided to the \\\"\" + modifier.name + \"\\\" modifier, valid properties are \" + VALID_PROPERTIES.map(function (s) {\n              return \"\\\"\" + s + \"\\\"\";\n            }).join(', ') + \"; but \\\"\" + key + \"\\\" was provided.\");\n        }\n\n        modifier.requires && modifier.requires.forEach(function (requirement) {\n          if (modifiers.find(function (mod) {\n            return mod.name === requirement;\n          }) == null) {\n            console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement));\n          }\n        });\n      });\n    });\n  }\n\n  function uniqueBy(arr, fn) {\n    var identifiers = new Set();\n    return arr.filter(function (item) {\n      var identifier = fn(item);\n\n      if (!identifiers.has(identifier)) {\n        identifiers.add(identifier);\n        return true;\n      }\n    });\n  }\n\n  function getBasePlacement(placement) {\n    return placement.split('-')[0];\n  }\n\n  function mergeByName(modifiers) {\n    var merged = modifiers.reduce(function (merged, current) {\n      var existing = merged[current.name];\n      merged[current.name] = existing ? Object.assign({}, existing, current, {\n        options: Object.assign({}, existing.options, current.options),\n        data: Object.assign({}, existing.data, current.data)\n      }) : current;\n      return merged;\n    }, {}); // IE11 does not support Object.values\n\n    return Object.keys(merged).map(function (key) {\n      return merged[key];\n    });\n  }\n\n  function getViewportRect(element) {\n    var win = getWindow(element);\n    var html = getDocumentElement(element);\n    var visualViewport = win.visualViewport;\n    var width = html.clientWidth;\n    var height = html.clientHeight;\n    var x = 0;\n    var y = 0; // NB: This isn't supported on iOS <= 12. If the keyboard is open, the popper\n    // can be obscured underneath it.\n    // Also, `html.clientHeight` adds the bottom bar height in Safari iOS, even\n    // if it isn't open, so if this isn't available, the popper will be detected\n    // to overflow the bottom of the screen too early.\n\n    if (visualViewport) {\n      width = visualViewport.width;\n      height = visualViewport.height; // Uses Layout Viewport (like Chrome; Safari does not currently)\n      // In Chrome, it returns a value very close to 0 (+/-) but contains rounding\n      // errors due to floating point numbers, so we need to check precision.\n      // Safari returns a number <= 0, usually < -1 when pinch-zoomed\n      // Feature detection fails in mobile emulation mode in Chrome.\n      // Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) <\n      // 0.001\n      // Fallback here: \"Not Safari\" userAgent\n\n      if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {\n        x = visualViewport.offsetLeft;\n        y = visualViewport.offsetTop;\n      }\n    }\n\n    return {\n      width: width,\n      height: height,\n      x: x + getWindowScrollBarX(element),\n      y: y\n    };\n  }\n\n  // of the `<html>` and `<body>` rect bounds if horizontally scrollable\n\n  function getDocumentRect(element) {\n    var _element$ownerDocumen;\n\n    var html = getDocumentElement(element);\n    var winScroll = getWindowScroll(element);\n    var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n    var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n    var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n    var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n    var y = -winScroll.scrollTop;\n\n    if (getComputedStyle(body || html).direction === 'rtl') {\n      x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n    }\n\n    return {\n      width: width,\n      height: height,\n      x: x,\n      y: y\n    };\n  }\n\n  function contains(parent, child) {\n    var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n    if (parent.contains(child)) {\n      return true;\n    } // then fallback to custom implementation with Shadow DOM support\n    else if (rootNode && isShadowRoot(rootNode)) {\n        var next = child;\n\n        do {\n          if (next && parent.isSameNode(next)) {\n            return true;\n          } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n          next = next.parentNode || next.host;\n        } while (next);\n      } // Give up, the result is false\n\n\n    return false;\n  }\n\n  function rectToClientRect(rect) {\n    return Object.assign({}, rect, {\n      left: rect.x,\n      top: rect.y,\n      right: rect.x + rect.width,\n      bottom: rect.y + rect.height\n    });\n  }\n\n  function getInnerBoundingClientRect(element) {\n    var rect = getBoundingClientRect(element);\n    rect.top = rect.top + element.clientTop;\n    rect.left = rect.left + element.clientLeft;\n    rect.bottom = rect.top + element.clientHeight;\n    rect.right = rect.left + element.clientWidth;\n    rect.width = element.clientWidth;\n    rect.height = element.clientHeight;\n    rect.x = rect.left;\n    rect.y = rect.top;\n    return rect;\n  }\n\n  function getClientRectFromMixedType(element, clippingParent) {\n    return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n  } // A \"clipping parent\" is an overflowable container with the characteristic of\n  // clipping (or hiding) overflowing elements with a position different from\n  // `initial`\n\n\n  function getClippingParents(element) {\n    var clippingParents = listScrollParents(getParentNode(element));\n    var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;\n    var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n    if (!isElement(clipperElement)) {\n      return [];\n    } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n    return clippingParents.filter(function (clippingParent) {\n      return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body' && (canEscapeClipping ? getComputedStyle(clippingParent).position !== 'static' : true);\n    });\n  } // Gets the maximum area that the element is visible in due to any number of\n  // clipping parents\n\n\n  function getClippingRect(element, boundary, rootBoundary) {\n    var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n    var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n    var firstClippingParent = clippingParents[0];\n    var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n      var rect = getClientRectFromMixedType(element, clippingParent);\n      accRect.top = max(rect.top, accRect.top);\n      accRect.right = min(rect.right, accRect.right);\n      accRect.bottom = min(rect.bottom, accRect.bottom);\n      accRect.left = max(rect.left, accRect.left);\n      return accRect;\n    }, getClientRectFromMixedType(element, firstClippingParent));\n    clippingRect.width = clippingRect.right - clippingRect.left;\n    clippingRect.height = clippingRect.bottom - clippingRect.top;\n    clippingRect.x = clippingRect.left;\n    clippingRect.y = clippingRect.top;\n    return clippingRect;\n  }\n\n  function getVariation(placement) {\n    return placement.split('-')[1];\n  }\n\n  function getMainAxisFromPlacement(placement) {\n    return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n  }\n\n  function computeOffsets(_ref) {\n    var reference = _ref.reference,\n        element = _ref.element,\n        placement = _ref.placement;\n    var basePlacement = placement ? getBasePlacement(placement) : null;\n    var variation = placement ? getVariation(placement) : null;\n    var commonX = reference.x + reference.width / 2 - element.width / 2;\n    var commonY = reference.y + reference.height / 2 - element.height / 2;\n    var offsets;\n\n    switch (basePlacement) {\n      case top:\n        offsets = {\n          x: commonX,\n          y: reference.y - element.height\n        };\n        break;\n\n      case bottom:\n        offsets = {\n          x: commonX,\n          y: reference.y + reference.height\n        };\n        break;\n\n      case right:\n        offsets = {\n          x: reference.x + reference.width,\n          y: commonY\n        };\n        break;\n\n      case left:\n        offsets = {\n          x: reference.x - element.width,\n          y: commonY\n        };\n        break;\n\n      default:\n        offsets = {\n          x: reference.x,\n          y: reference.y\n        };\n    }\n\n    var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n    if (mainAxis != null) {\n      var len = mainAxis === 'y' ? 'height' : 'width';\n\n      switch (variation) {\n        case start:\n          offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n          break;\n\n        case end:\n          offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n          break;\n      }\n    }\n\n    return offsets;\n  }\n\n  function getFreshSideObject() {\n    return {\n      top: 0,\n      right: 0,\n      bottom: 0,\n      left: 0\n    };\n  }\n\n  function mergePaddingObject(paddingObject) {\n    return Object.assign({}, getFreshSideObject(), paddingObject);\n  }\n\n  function expandToHashMap(value, keys) {\n    return keys.reduce(function (hashMap, key) {\n      hashMap[key] = value;\n      return hashMap;\n    }, {});\n  }\n\n  function detectOverflow(state, options) {\n    if (options === void 0) {\n      options = {};\n    }\n\n    var _options = options,\n        _options$placement = _options.placement,\n        placement = _options$placement === void 0 ? state.placement : _options$placement,\n        _options$boundary = _options.boundary,\n        boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n        _options$rootBoundary = _options.rootBoundary,\n        rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n        _options$elementConte = _options.elementContext,\n        elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n        _options$altBoundary = _options.altBoundary,\n        altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n        _options$padding = _options.padding,\n        padding = _options$padding === void 0 ? 0 : _options$padding;\n    var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n    var altContext = elementContext === popper ? reference : popper;\n    var popperRect = state.rects.popper;\n    var element = state.elements[altBoundary ? altContext : elementContext];\n    var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary);\n    var referenceClientRect = getBoundingClientRect(state.elements.reference);\n    var popperOffsets = computeOffsets({\n      reference: referenceClientRect,\n      element: popperRect,\n      strategy: 'absolute',\n      placement: placement\n    });\n    var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n    var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n    // 0 or negative = within the clipping rect\n\n    var overflowOffsets = {\n      top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n      bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n      left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n      right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n    };\n    var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n    if (elementContext === popper && offsetData) {\n      var offset = offsetData[placement];\n      Object.keys(overflowOffsets).forEach(function (key) {\n        var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n        var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n        overflowOffsets[key] += offset[axis] * multiply;\n      });\n    }\n\n    return overflowOffsets;\n  }\n\n  var INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.';\n  var INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.';\n  var DEFAULT_OPTIONS = {\n    placement: 'bottom',\n    modifiers: [],\n    strategy: 'absolute'\n  };\n\n  function areValidElements() {\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    return !args.some(function (element) {\n      return !(element && typeof element.getBoundingClientRect === 'function');\n    });\n  }\n\n  function popperGenerator(generatorOptions) {\n    if (generatorOptions === void 0) {\n      generatorOptions = {};\n    }\n\n    var _generatorOptions = generatorOptions,\n        _generatorOptions$def = _generatorOptions.defaultModifiers,\n        defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n        _generatorOptions$def2 = _generatorOptions.defaultOptions,\n        defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n    return function createPopper(reference, popper, options) {\n      if (options === void 0) {\n        options = defaultOptions;\n      }\n\n      var state = {\n        placement: 'bottom',\n        orderedModifiers: [],\n        options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n        modifiersData: {},\n        elements: {\n          reference: reference,\n          popper: popper\n        },\n        attributes: {},\n        styles: {}\n      };\n      var effectCleanupFns = [];\n      var isDestroyed = false;\n      var instance = {\n        state: state,\n        setOptions: function setOptions(setOptionsAction) {\n          var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;\n          cleanupModifierEffects();\n          state.options = Object.assign({}, defaultOptions, state.options, options);\n          state.scrollParents = {\n            reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n            popper: listScrollParents(popper)\n          }; // Orders the modifiers based on their dependencies and `phase`\n          // properties\n\n          var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n          state.orderedModifiers = orderedModifiers.filter(function (m) {\n            return m.enabled;\n          }); // Validate the provided modifiers so that the consumer will get warned\n          // if one of the modifiers is invalid for any reason\n\n          {\n            var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) {\n              var name = _ref.name;\n              return name;\n            });\n            validateModifiers(modifiers);\n\n            if (getBasePlacement(state.options.placement) === auto) {\n              var flipModifier = state.orderedModifiers.find(function (_ref2) {\n                var name = _ref2.name;\n                return name === 'flip';\n              });\n\n              if (!flipModifier) {\n                console.error(['Popper: \"auto\" placements require the \"flip\" modifier be', 'present and enabled to work.'].join(' '));\n              }\n            }\n\n            var _getComputedStyle = getComputedStyle(popper),\n                marginTop = _getComputedStyle.marginTop,\n                marginRight = _getComputedStyle.marginRight,\n                marginBottom = _getComputedStyle.marginBottom,\n                marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can\n            // cause bugs with positioning, so we'll warn the consumer\n\n\n            if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) {\n              return parseFloat(margin);\n            })) {\n              console.warn(['Popper: CSS \"margin\" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' '));\n            }\n          }\n\n          runModifierEffects();\n          return instance.update();\n        },\n        // Sync update – it will always be executed, even if not necessary. This\n        // is useful for low frequency updates where sync behavior simplifies the\n        // logic.\n        // For high frequency updates (e.g. `resize` and `scroll` events), always\n        // prefer the async Popper#update method\n        forceUpdate: function forceUpdate() {\n          if (isDestroyed) {\n            return;\n          }\n\n          var _state$elements = state.elements,\n              reference = _state$elements.reference,\n              popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n          // anymore\n\n          if (!areValidElements(reference, popper)) {\n            {\n              console.error(INVALID_ELEMENT_ERROR);\n            }\n\n            return;\n          } // Store the reference and popper rects to be read by modifiers\n\n\n          state.rects = {\n            reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n            popper: getLayoutRect(popper)\n          }; // Modifiers have the ability to reset the current update cycle. The\n          // most common use case for this is the `flip` modifier changing the\n          // placement, which then needs to re-run all the modifiers, because the\n          // logic was previously ran for the previous placement and is therefore\n          // stale/incorrect\n\n          state.reset = false;\n          state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n          // is filled with the initial data specified by the modifier. This means\n          // it doesn't persist and is fresh on each update.\n          // To ensure persistent data, use `${name}#persistent`\n\n          state.orderedModifiers.forEach(function (modifier) {\n            return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n          });\n          var __debug_loops__ = 0;\n\n          for (var index = 0; index < state.orderedModifiers.length; index++) {\n            {\n              __debug_loops__ += 1;\n\n              if (__debug_loops__ > 100) {\n                console.error(INFINITE_LOOP_ERROR);\n                break;\n              }\n            }\n\n            if (state.reset === true) {\n              state.reset = false;\n              index = -1;\n              continue;\n            }\n\n            var _state$orderedModifie = state.orderedModifiers[index],\n                fn = _state$orderedModifie.fn,\n                _state$orderedModifie2 = _state$orderedModifie.options,\n                _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n                name = _state$orderedModifie.name;\n\n            if (typeof fn === 'function') {\n              state = fn({\n                state: state,\n                options: _options,\n                name: name,\n                instance: instance\n              }) || state;\n            }\n          }\n        },\n        // Async and optimistically optimized update – it will not be executed if\n        // not necessary (debounced to run at most once-per-tick)\n        update: debounce(function () {\n          return new Promise(function (resolve) {\n            instance.forceUpdate();\n            resolve(state);\n          });\n        }),\n        destroy: function destroy() {\n          cleanupModifierEffects();\n          isDestroyed = true;\n        }\n      };\n\n      if (!areValidElements(reference, popper)) {\n        {\n          console.error(INVALID_ELEMENT_ERROR);\n        }\n\n        return instance;\n      }\n\n      instance.setOptions(options).then(function (state) {\n        if (!isDestroyed && options.onFirstUpdate) {\n          options.onFirstUpdate(state);\n        }\n      }); // Modifiers have the ability to execute arbitrary code before the first\n      // update cycle runs. They will be executed in the same order as the update\n      // cycle. This is useful when a modifier adds some persistent data that\n      // other modifiers need to use, but the modifier is run after the dependent\n      // one.\n\n      function runModifierEffects() {\n        state.orderedModifiers.forEach(function (_ref3) {\n          var name = _ref3.name,\n              _ref3$options = _ref3.options,\n              options = _ref3$options === void 0 ? {} : _ref3$options,\n              effect = _ref3.effect;\n\n          if (typeof effect === 'function') {\n            var cleanupFn = effect({\n              state: state,\n              name: name,\n              instance: instance,\n              options: options\n            });\n\n            var noopFn = function noopFn() {};\n\n            effectCleanupFns.push(cleanupFn || noopFn);\n          }\n        });\n      }\n\n      function cleanupModifierEffects() {\n        effectCleanupFns.forEach(function (fn) {\n          return fn();\n        });\n        effectCleanupFns = [];\n      }\n\n      return instance;\n    };\n  }\n\n  var passive = {\n    passive: true\n  };\n\n  function effect$2(_ref) {\n    var state = _ref.state,\n        instance = _ref.instance,\n        options = _ref.options;\n    var _options$scroll = options.scroll,\n        scroll = _options$scroll === void 0 ? true : _options$scroll,\n        _options$resize = options.resize,\n        resize = _options$resize === void 0 ? true : _options$resize;\n    var window = getWindow(state.elements.popper);\n    var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n    if (scroll) {\n      scrollParents.forEach(function (scrollParent) {\n        scrollParent.addEventListener('scroll', instance.update, passive);\n      });\n    }\n\n    if (resize) {\n      window.addEventListener('resize', instance.update, passive);\n    }\n\n    return function () {\n      if (scroll) {\n        scrollParents.forEach(function (scrollParent) {\n          scrollParent.removeEventListener('scroll', instance.update, passive);\n        });\n      }\n\n      if (resize) {\n        window.removeEventListener('resize', instance.update, passive);\n      }\n    };\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var eventListeners = {\n    name: 'eventListeners',\n    enabled: true,\n    phase: 'write',\n    fn: function fn() {},\n    effect: effect$2,\n    data: {}\n  };\n\n  function popperOffsets(_ref) {\n    var state = _ref.state,\n        name = _ref.name;\n    // Offsets are the actual position the popper needs to have to be\n    // properly positioned near its reference element\n    // This is the most basic placement, and will be adjusted by\n    // the modifiers in the next step\n    state.modifiersData[name] = computeOffsets({\n      reference: state.rects.reference,\n      element: state.rects.popper,\n      strategy: 'absolute',\n      placement: state.placement\n    });\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var popperOffsets$1 = {\n    name: 'popperOffsets',\n    enabled: true,\n    phase: 'read',\n    fn: popperOffsets,\n    data: {}\n  };\n\n  var unsetSides = {\n    top: 'auto',\n    right: 'auto',\n    bottom: 'auto',\n    left: 'auto'\n  }; // Round the offsets to the nearest suitable subpixel based on the DPR.\n  // Zooming can change the DPR, but it seems to report a value that will\n  // cleanly divide the values into the appropriate subpixels.\n\n  function roundOffsetsByDPR(_ref) {\n    var x = _ref.x,\n        y = _ref.y;\n    var win = window;\n    var dpr = win.devicePixelRatio || 1;\n    return {\n      x: round(x * dpr) / dpr || 0,\n      y: round(y * dpr) / dpr || 0\n    };\n  }\n\n  function mapToStyles(_ref2) {\n    var _Object$assign2;\n\n    var popper = _ref2.popper,\n        popperRect = _ref2.popperRect,\n        placement = _ref2.placement,\n        variation = _ref2.variation,\n        offsets = _ref2.offsets,\n        position = _ref2.position,\n        gpuAcceleration = _ref2.gpuAcceleration,\n        adaptive = _ref2.adaptive,\n        roundOffsets = _ref2.roundOffsets,\n        isFixed = _ref2.isFixed;\n\n    var _ref3 = roundOffsets === true ? roundOffsetsByDPR(offsets) : typeof roundOffsets === 'function' ? roundOffsets(offsets) : offsets,\n        _ref3$x = _ref3.x,\n        x = _ref3$x === void 0 ? 0 : _ref3$x,\n        _ref3$y = _ref3.y,\n        y = _ref3$y === void 0 ? 0 : _ref3$y;\n\n    var hasX = offsets.hasOwnProperty('x');\n    var hasY = offsets.hasOwnProperty('y');\n    var sideX = left;\n    var sideY = top;\n    var win = window;\n\n    if (adaptive) {\n      var offsetParent = getOffsetParent(popper);\n      var heightProp = 'clientHeight';\n      var widthProp = 'clientWidth';\n\n      if (offsetParent === getWindow(popper)) {\n        offsetParent = getDocumentElement(popper);\n\n        if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {\n          heightProp = 'scrollHeight';\n          widthProp = 'scrollWidth';\n        }\n      } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n      offsetParent = offsetParent;\n\n      if (placement === top || (placement === left || placement === right) && variation === end) {\n        sideY = bottom;\n        var offsetY = isFixed && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]\n        offsetParent[heightProp];\n        y -= offsetY - popperRect.height;\n        y *= gpuAcceleration ? 1 : -1;\n      }\n\n      if (placement === left || (placement === top || placement === bottom) && variation === end) {\n        sideX = right;\n        var offsetX = isFixed && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]\n        offsetParent[widthProp];\n        x -= offsetX - popperRect.width;\n        x *= gpuAcceleration ? 1 : -1;\n      }\n    }\n\n    var commonStyles = Object.assign({\n      position: position\n    }, adaptive && unsetSides);\n\n    if (gpuAcceleration) {\n      var _Object$assign;\n\n      return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n    }\n\n    return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n  }\n\n  function computeStyles(_ref4) {\n    var state = _ref4.state,\n        options = _ref4.options;\n    var _options$gpuAccelerat = options.gpuAcceleration,\n        gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n        _options$adaptive = options.adaptive,\n        adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n        _options$roundOffsets = options.roundOffsets,\n        roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n\n    {\n      var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || '';\n\n      if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {\n        return transitionProperty.indexOf(property) >= 0;\n      })) {\n        console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: \"transform\", \"top\", \"right\", \"bottom\", \"left\".', '\\n\\n', 'Disable the \"computeStyles\" modifier\\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\\n\\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' '));\n      }\n    }\n\n    var commonStyles = {\n      placement: getBasePlacement(state.placement),\n      variation: getVariation(state.placement),\n      popper: state.elements.popper,\n      popperRect: state.rects.popper,\n      gpuAcceleration: gpuAcceleration,\n      isFixed: state.options.strategy === 'fixed'\n    };\n\n    if (state.modifiersData.popperOffsets != null) {\n      state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n        offsets: state.modifiersData.popperOffsets,\n        position: state.options.strategy,\n        adaptive: adaptive,\n        roundOffsets: roundOffsets\n      })));\n    }\n\n    if (state.modifiersData.arrow != null) {\n      state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n        offsets: state.modifiersData.arrow,\n        position: 'absolute',\n        adaptive: false,\n        roundOffsets: roundOffsets\n      })));\n    }\n\n    state.attributes.popper = Object.assign({}, state.attributes.popper, {\n      'data-popper-placement': state.placement\n    });\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var computeStyles$1 = {\n    name: 'computeStyles',\n    enabled: true,\n    phase: 'beforeWrite',\n    fn: computeStyles,\n    data: {}\n  };\n\n  // and applies them to the HTMLElements such as popper and arrow\n\n  function applyStyles(_ref) {\n    var state = _ref.state;\n    Object.keys(state.elements).forEach(function (name) {\n      var style = state.styles[name] || {};\n      var attributes = state.attributes[name] || {};\n      var element = state.elements[name]; // arrow is optional + virtual elements\n\n      if (!isHTMLElement(element) || !getNodeName(element)) {\n        return;\n      } // Flow doesn't support to extend this property, but it's the most\n      // effective way to apply styles to an HTMLElement\n      // $FlowFixMe[cannot-write]\n\n\n      Object.assign(element.style, style);\n      Object.keys(attributes).forEach(function (name) {\n        var value = attributes[name];\n\n        if (value === false) {\n          element.removeAttribute(name);\n        } else {\n          element.setAttribute(name, value === true ? '' : value);\n        }\n      });\n    });\n  }\n\n  function effect$1(_ref2) {\n    var state = _ref2.state;\n    var initialStyles = {\n      popper: {\n        position: state.options.strategy,\n        left: '0',\n        top: '0',\n        margin: '0'\n      },\n      arrow: {\n        position: 'absolute'\n      },\n      reference: {}\n    };\n    Object.assign(state.elements.popper.style, initialStyles.popper);\n    state.styles = initialStyles;\n\n    if (state.elements.arrow) {\n      Object.assign(state.elements.arrow.style, initialStyles.arrow);\n    }\n\n    return function () {\n      Object.keys(state.elements).forEach(function (name) {\n        var element = state.elements[name];\n        var attributes = state.attributes[name] || {};\n        var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n        var style = styleProperties.reduce(function (style, property) {\n          style[property] = '';\n          return style;\n        }, {}); // arrow is optional + virtual elements\n\n        if (!isHTMLElement(element) || !getNodeName(element)) {\n          return;\n        }\n\n        Object.assign(element.style, style);\n        Object.keys(attributes).forEach(function (attribute) {\n          element.removeAttribute(attribute);\n        });\n      });\n    };\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var applyStyles$1 = {\n    name: 'applyStyles',\n    enabled: true,\n    phase: 'write',\n    fn: applyStyles,\n    effect: effect$1,\n    requires: ['computeStyles']\n  };\n\n  function distanceAndSkiddingToXY(placement, rects, offset) {\n    var basePlacement = getBasePlacement(placement);\n    var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n    var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n      placement: placement\n    })) : offset,\n        skidding = _ref[0],\n        distance = _ref[1];\n\n    skidding = skidding || 0;\n    distance = (distance || 0) * invertDistance;\n    return [left, right].indexOf(basePlacement) >= 0 ? {\n      x: distance,\n      y: skidding\n    } : {\n      x: skidding,\n      y: distance\n    };\n  }\n\n  function offset(_ref2) {\n    var state = _ref2.state,\n        options = _ref2.options,\n        name = _ref2.name;\n    var _options$offset = options.offset,\n        offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n    var data = placements.reduce(function (acc, placement) {\n      acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n      return acc;\n    }, {});\n    var _data$state$placement = data[state.placement],\n        x = _data$state$placement.x,\n        y = _data$state$placement.y;\n\n    if (state.modifiersData.popperOffsets != null) {\n      state.modifiersData.popperOffsets.x += x;\n      state.modifiersData.popperOffsets.y += y;\n    }\n\n    state.modifiersData[name] = data;\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var offset$1 = {\n    name: 'offset',\n    enabled: true,\n    phase: 'main',\n    requires: ['popperOffsets'],\n    fn: offset\n  };\n\n  var hash$1 = {\n    left: 'right',\n    right: 'left',\n    bottom: 'top',\n    top: 'bottom'\n  };\n  function getOppositePlacement(placement) {\n    return placement.replace(/left|right|bottom|top/g, function (matched) {\n      return hash$1[matched];\n    });\n  }\n\n  var hash = {\n    start: 'end',\n    end: 'start'\n  };\n  function getOppositeVariationPlacement(placement) {\n    return placement.replace(/start|end/g, function (matched) {\n      return hash[matched];\n    });\n  }\n\n  function computeAutoPlacement(state, options) {\n    if (options === void 0) {\n      options = {};\n    }\n\n    var _options = options,\n        placement = _options.placement,\n        boundary = _options.boundary,\n        rootBoundary = _options.rootBoundary,\n        padding = _options.padding,\n        flipVariations = _options.flipVariations,\n        _options$allowedAutoP = _options.allowedAutoPlacements,\n        allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;\n    var variation = getVariation(placement);\n    var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n      return getVariation(placement) === variation;\n    }) : basePlacements;\n    var allowedPlacements = placements$1.filter(function (placement) {\n      return allowedAutoPlacements.indexOf(placement) >= 0;\n    });\n\n    if (allowedPlacements.length === 0) {\n      allowedPlacements = placements$1;\n\n      {\n        console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, \"auto\" cannot be used to allow \"bottom-start\".', 'Use \"auto-start\" instead.'].join(' '));\n      }\n    } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n    var overflows = allowedPlacements.reduce(function (acc, placement) {\n      acc[placement] = detectOverflow(state, {\n        placement: placement,\n        boundary: boundary,\n        rootBoundary: rootBoundary,\n        padding: padding\n      })[getBasePlacement(placement)];\n      return acc;\n    }, {});\n    return Object.keys(overflows).sort(function (a, b) {\n      return overflows[a] - overflows[b];\n    });\n  }\n\n  function getExpandedFallbackPlacements(placement) {\n    if (getBasePlacement(placement) === auto) {\n      return [];\n    }\n\n    var oppositePlacement = getOppositePlacement(placement);\n    return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n  }\n\n  function flip(_ref) {\n    var state = _ref.state,\n        options = _ref.options,\n        name = _ref.name;\n\n    if (state.modifiersData[name]._skip) {\n      return;\n    }\n\n    var _options$mainAxis = options.mainAxis,\n        checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n        _options$altAxis = options.altAxis,\n        checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n        specifiedFallbackPlacements = options.fallbackPlacements,\n        padding = options.padding,\n        boundary = options.boundary,\n        rootBoundary = options.rootBoundary,\n        altBoundary = options.altBoundary,\n        _options$flipVariatio = options.flipVariations,\n        flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n        allowedAutoPlacements = options.allowedAutoPlacements;\n    var preferredPlacement = state.options.placement;\n    var basePlacement = getBasePlacement(preferredPlacement);\n    var isBasePlacement = basePlacement === preferredPlacement;\n    var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n    var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n      return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n        placement: placement,\n        boundary: boundary,\n        rootBoundary: rootBoundary,\n        padding: padding,\n        flipVariations: flipVariations,\n        allowedAutoPlacements: allowedAutoPlacements\n      }) : placement);\n    }, []);\n    var referenceRect = state.rects.reference;\n    var popperRect = state.rects.popper;\n    var checksMap = new Map();\n    var makeFallbackChecks = true;\n    var firstFittingPlacement = placements[0];\n\n    for (var i = 0; i < placements.length; i++) {\n      var placement = placements[i];\n\n      var _basePlacement = getBasePlacement(placement);\n\n      var isStartVariation = getVariation(placement) === start;\n      var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n      var len = isVertical ? 'width' : 'height';\n      var overflow = detectOverflow(state, {\n        placement: placement,\n        boundary: boundary,\n        rootBoundary: rootBoundary,\n        altBoundary: altBoundary,\n        padding: padding\n      });\n      var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n      if (referenceRect[len] > popperRect[len]) {\n        mainVariationSide = getOppositePlacement(mainVariationSide);\n      }\n\n      var altVariationSide = getOppositePlacement(mainVariationSide);\n      var checks = [];\n\n      if (checkMainAxis) {\n        checks.push(overflow[_basePlacement] <= 0);\n      }\n\n      if (checkAltAxis) {\n        checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n      }\n\n      if (checks.every(function (check) {\n        return check;\n      })) {\n        firstFittingPlacement = placement;\n        makeFallbackChecks = false;\n        break;\n      }\n\n      checksMap.set(placement, checks);\n    }\n\n    if (makeFallbackChecks) {\n      // `2` may be desired in some cases – research later\n      var numberOfChecks = flipVariations ? 3 : 1;\n\n      var _loop = function _loop(_i) {\n        var fittingPlacement = placements.find(function (placement) {\n          var checks = checksMap.get(placement);\n\n          if (checks) {\n            return checks.slice(0, _i).every(function (check) {\n              return check;\n            });\n          }\n        });\n\n        if (fittingPlacement) {\n          firstFittingPlacement = fittingPlacement;\n          return \"break\";\n        }\n      };\n\n      for (var _i = numberOfChecks; _i > 0; _i--) {\n        var _ret = _loop(_i);\n\n        if (_ret === \"break\") break;\n      }\n    }\n\n    if (state.placement !== firstFittingPlacement) {\n      state.modifiersData[name]._skip = true;\n      state.placement = firstFittingPlacement;\n      state.reset = true;\n    }\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var flip$1 = {\n    name: 'flip',\n    enabled: true,\n    phase: 'main',\n    fn: flip,\n    requiresIfExists: ['offset'],\n    data: {\n      _skip: false\n    }\n  };\n\n  function getAltAxis(axis) {\n    return axis === 'x' ? 'y' : 'x';\n  }\n\n  function within(min$1, value, max$1) {\n    return max(min$1, min(value, max$1));\n  }\n  function withinMaxClamp(min, value, max) {\n    var v = within(min, value, max);\n    return v > max ? max : v;\n  }\n\n  function preventOverflow(_ref) {\n    var state = _ref.state,\n        options = _ref.options,\n        name = _ref.name;\n    var _options$mainAxis = options.mainAxis,\n        checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n        _options$altAxis = options.altAxis,\n        checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n        boundary = options.boundary,\n        rootBoundary = options.rootBoundary,\n        altBoundary = options.altBoundary,\n        padding = options.padding,\n        _options$tether = options.tether,\n        tether = _options$tether === void 0 ? true : _options$tether,\n        _options$tetherOffset = options.tetherOffset,\n        tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n    var overflow = detectOverflow(state, {\n      boundary: boundary,\n      rootBoundary: rootBoundary,\n      padding: padding,\n      altBoundary: altBoundary\n    });\n    var basePlacement = getBasePlacement(state.placement);\n    var variation = getVariation(state.placement);\n    var isBasePlacement = !variation;\n    var mainAxis = getMainAxisFromPlacement(basePlacement);\n    var altAxis = getAltAxis(mainAxis);\n    var popperOffsets = state.modifiersData.popperOffsets;\n    var referenceRect = state.rects.reference;\n    var popperRect = state.rects.popper;\n    var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n      placement: state.placement\n    })) : tetherOffset;\n    var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {\n      mainAxis: tetherOffsetValue,\n      altAxis: tetherOffsetValue\n    } : Object.assign({\n      mainAxis: 0,\n      altAxis: 0\n    }, tetherOffsetValue);\n    var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;\n    var data = {\n      x: 0,\n      y: 0\n    };\n\n    if (!popperOffsets) {\n      return;\n    }\n\n    if (checkMainAxis) {\n      var _offsetModifierState$;\n\n      var mainSide = mainAxis === 'y' ? top : left;\n      var altSide = mainAxis === 'y' ? bottom : right;\n      var len = mainAxis === 'y' ? 'height' : 'width';\n      var offset = popperOffsets[mainAxis];\n      var min$1 = offset + overflow[mainSide];\n      var max$1 = offset - overflow[altSide];\n      var additive = tether ? -popperRect[len] / 2 : 0;\n      var minLen = variation === start ? referenceRect[len] : popperRect[len];\n      var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n      // outside the reference bounds\n\n      var arrowElement = state.elements.arrow;\n      var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n        width: 0,\n        height: 0\n      };\n      var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n      var arrowPaddingMin = arrowPaddingObject[mainSide];\n      var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n      // to include its full size in the calculation. If the reference is small\n      // and near the edge of a boundary, the popper can overflow even if the\n      // reference is not overflowing as well (e.g. virtual elements with no\n      // width or height)\n\n      var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n      var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;\n      var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;\n      var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n      var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n      var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;\n      var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;\n      var tetherMax = offset + maxOffset - offsetModifierValue;\n      var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1);\n      popperOffsets[mainAxis] = preventedOffset;\n      data[mainAxis] = preventedOffset - offset;\n    }\n\n    if (checkAltAxis) {\n      var _offsetModifierState$2;\n\n      var _mainSide = mainAxis === 'x' ? top : left;\n\n      var _altSide = mainAxis === 'x' ? bottom : right;\n\n      var _offset = popperOffsets[altAxis];\n\n      var _len = altAxis === 'y' ? 'height' : 'width';\n\n      var _min = _offset + overflow[_mainSide];\n\n      var _max = _offset - overflow[_altSide];\n\n      var isOriginSide = [top, left].indexOf(basePlacement) !== -1;\n\n      var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;\n\n      var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;\n\n      var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;\n\n      var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);\n\n      popperOffsets[altAxis] = _preventedOffset;\n      data[altAxis] = _preventedOffset - _offset;\n    }\n\n    state.modifiersData[name] = data;\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var preventOverflow$1 = {\n    name: 'preventOverflow',\n    enabled: true,\n    phase: 'main',\n    fn: preventOverflow,\n    requiresIfExists: ['offset']\n  };\n\n  var toPaddingObject = function toPaddingObject(padding, state) {\n    padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n      placement: state.placement\n    })) : padding;\n    return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n  };\n\n  function arrow(_ref) {\n    var _state$modifiersData$;\n\n    var state = _ref.state,\n        name = _ref.name,\n        options = _ref.options;\n    var arrowElement = state.elements.arrow;\n    var popperOffsets = state.modifiersData.popperOffsets;\n    var basePlacement = getBasePlacement(state.placement);\n    var axis = getMainAxisFromPlacement(basePlacement);\n    var isVertical = [left, right].indexOf(basePlacement) >= 0;\n    var len = isVertical ? 'height' : 'width';\n\n    if (!arrowElement || !popperOffsets) {\n      return;\n    }\n\n    var paddingObject = toPaddingObject(options.padding, state);\n    var arrowRect = getLayoutRect(arrowElement);\n    var minProp = axis === 'y' ? top : left;\n    var maxProp = axis === 'y' ? bottom : right;\n    var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n    var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n    var arrowOffsetParent = getOffsetParent(arrowElement);\n    var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n    var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n    // outside of the popper bounds\n\n    var min = paddingObject[minProp];\n    var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n    var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n    var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n    var axisProp = axis;\n    state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n  }\n\n  function effect(_ref2) {\n    var state = _ref2.state,\n        options = _ref2.options;\n    var _options$element = options.element,\n        arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n    if (arrowElement == null) {\n      return;\n    } // CSS selector\n\n\n    if (typeof arrowElement === 'string') {\n      arrowElement = state.elements.popper.querySelector(arrowElement);\n\n      if (!arrowElement) {\n        return;\n      }\n    }\n\n    {\n      if (!isHTMLElement(arrowElement)) {\n        console.error(['Popper: \"arrow\" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' '));\n      }\n    }\n\n    if (!contains(state.elements.popper, arrowElement)) {\n      {\n        console.error(['Popper: \"arrow\" modifier\\'s `element` must be a child of the popper', 'element.'].join(' '));\n      }\n\n      return;\n    }\n\n    state.elements.arrow = arrowElement;\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var arrow$1 = {\n    name: 'arrow',\n    enabled: true,\n    phase: 'main',\n    fn: arrow,\n    effect: effect,\n    requires: ['popperOffsets'],\n    requiresIfExists: ['preventOverflow']\n  };\n\n  function getSideOffsets(overflow, rect, preventedOffsets) {\n    if (preventedOffsets === void 0) {\n      preventedOffsets = {\n        x: 0,\n        y: 0\n      };\n    }\n\n    return {\n      top: overflow.top - rect.height - preventedOffsets.y,\n      right: overflow.right - rect.width + preventedOffsets.x,\n      bottom: overflow.bottom - rect.height + preventedOffsets.y,\n      left: overflow.left - rect.width - preventedOffsets.x\n    };\n  }\n\n  function isAnySideFullyClipped(overflow) {\n    return [top, right, bottom, left].some(function (side) {\n      return overflow[side] >= 0;\n    });\n  }\n\n  function hide(_ref) {\n    var state = _ref.state,\n        name = _ref.name;\n    var referenceRect = state.rects.reference;\n    var popperRect = state.rects.popper;\n    var preventedOffsets = state.modifiersData.preventOverflow;\n    var referenceOverflow = detectOverflow(state, {\n      elementContext: 'reference'\n    });\n    var popperAltOverflow = detectOverflow(state, {\n      altBoundary: true\n    });\n    var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n    var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n    var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n    var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n    state.modifiersData[name] = {\n      referenceClippingOffsets: referenceClippingOffsets,\n      popperEscapeOffsets: popperEscapeOffsets,\n      isReferenceHidden: isReferenceHidden,\n      hasPopperEscaped: hasPopperEscaped\n    };\n    state.attributes.popper = Object.assign({}, state.attributes.popper, {\n      'data-popper-reference-hidden': isReferenceHidden,\n      'data-popper-escaped': hasPopperEscaped\n    });\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var hide$1 = {\n    name: 'hide',\n    enabled: true,\n    phase: 'main',\n    requiresIfExists: ['preventOverflow'],\n    fn: hide\n  };\n\n  var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1];\n  var createPopper$1 = /*#__PURE__*/popperGenerator({\n    defaultModifiers: defaultModifiers$1\n  }); // eslint-disable-next-line import/no-unused-modules\n\n  var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1];\n  var createPopper = /*#__PURE__*/popperGenerator({\n    defaultModifiers: defaultModifiers\n  }); // eslint-disable-next-line import/no-unused-modules\n\n  exports.applyStyles = applyStyles$1;\n  exports.arrow = arrow$1;\n  exports.computeStyles = computeStyles$1;\n  exports.createPopper = createPopper;\n  exports.createPopperLite = createPopper$1;\n  exports.defaultModifiers = defaultModifiers;\n  exports.detectOverflow = detectOverflow;\n  exports.eventListeners = eventListeners;\n  exports.flip = flip$1;\n  exports.hide = hide$1;\n  exports.offset = offset$1;\n  exports.popperGenerator = popperGenerator;\n  exports.popperOffsets = popperOffsets$1;\n  exports.preventOverflow = preventOverflow$1;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n//# sourceMappingURL=popper.js.map\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_accordion.scss",
    "content": "//\n// Base styles\n//\n\n.accordion-button {\n  position: relative;\n  display: flex;\n  align-items: center;\n  width: 100%;\n  padding: $accordion-button-padding-y $accordion-button-padding-x;\n  @include font-size($font-size-base);\n  color: $accordion-button-color;\n  text-align: left; // Reset button style\n  background-color: $accordion-button-bg;\n  border: 0;\n  @include border-radius(0);\n  overflow-anchor: none;\n  @include transition($accordion-transition);\n\n  &:not(.collapsed) {\n    color: $accordion-button-active-color;\n    background-color: $accordion-button-active-bg;\n    box-shadow: inset 0 ($accordion-border-width * -1) 0 $accordion-border-color;\n\n    &::after {\n      background-image: escape-svg($accordion-button-active-icon);\n      transform: $accordion-icon-transform;\n    }\n  }\n\n  // Accordion icon\n  &::after {\n    flex-shrink: 0;\n    width: $accordion-icon-width;\n    height: $accordion-icon-width;\n    margin-left: auto;\n    content: \"\";\n    background-image: escape-svg($accordion-button-icon);\n    background-repeat: no-repeat;\n    background-size: $accordion-icon-width;\n    @include transition($accordion-icon-transition);\n  }\n\n  &:hover {\n    z-index: 2;\n  }\n\n  &:focus {\n    z-index: 3;\n    border-color: $accordion-button-focus-border-color;\n    outline: 0;\n    box-shadow: $accordion-button-focus-box-shadow;\n  }\n}\n\n.accordion-header {\n  margin-bottom: 0;\n}\n\n.accordion-item {\n  background-color: $accordion-bg;\n  border: $accordion-border-width solid $accordion-border-color;\n\n  &:first-of-type {\n    @include border-top-radius($accordion-border-radius);\n\n    .accordion-button {\n      @include border-top-radius($accordion-inner-border-radius);\n    }\n  }\n\n  &:not(:first-of-type) {\n    border-top: 0;\n  }\n\n  // Only set a border-radius on the last item if the accordion is collapsed\n  &:last-of-type {\n    @include border-bottom-radius($accordion-border-radius);\n\n    .accordion-button {\n      &.collapsed {\n        @include border-bottom-radius($accordion-inner-border-radius);\n      }\n    }\n\n    .accordion-collapse {\n      @include border-bottom-radius($accordion-border-radius);\n    }\n  }\n}\n\n.accordion-body {\n  padding: $accordion-body-padding-y $accordion-body-padding-x;\n}\n\n\n// Flush accordion items\n//\n// Remove borders and border-radius to keep accordion items edge-to-edge.\n\n.accordion-flush {\n  .accordion-collapse {\n    border-width: 0;\n  }\n\n  .accordion-item {\n    border-right: 0;\n    border-left: 0;\n    @include border-radius(0);\n\n    &:first-child { border-top: 0; }\n    &:last-child { border-bottom: 0; }\n\n    .accordion-button {\n      @include border-radius(0);\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_alert.scss",
    "content": "//\n// Base styles\n//\n\n.alert {\n  position: relative;\n  padding: $alert-padding-y $alert-padding-x;\n  margin-bottom: $alert-margin-bottom;\n  border: $alert-border-width solid transparent;\n  @include border-radius($alert-border-radius);\n}\n\n// Headings for larger alerts\n.alert-heading {\n  // Specified to prevent conflicts of changing $headings-color\n  color: inherit;\n}\n\n// Provide class for links that match alerts\n.alert-link {\n  font-weight: $alert-link-font-weight;\n}\n\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissible {\n  padding-right: $alert-dismissible-padding-r;\n\n  // Adjust close link position\n  .btn-close {\n    position: absolute;\n    top: 0;\n    right: 0;\n    z-index: $stretched-link-z-index + 1;\n    padding: $alert-padding-y * 1.25 $alert-padding-x;\n  }\n}\n\n\n// scss-docs-start alert-modifiers\n// Generate contextual modifier classes for colorizing the alert.\n\n@each $state, $value in $theme-colors {\n  $alert-background: shift-color($value, $alert-bg-scale);\n  $alert-border: shift-color($value, $alert-border-scale);\n  $alert-color: shift-color($value, $alert-color-scale);\n  @if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) {\n    $alert-color: mix($value, color-contrast($alert-background), abs($alert-color-scale));\n  }\n  .alert-#{$state} {\n    @include alert-variant($alert-background, $alert-border, $alert-color);\n  }\n}\n// scss-docs-end alert-modifiers\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_badge.scss",
    "content": "// Base class\n//\n// Requires one of the contextual, color modifier classes for `color` and\n// `background-color`.\n\n.badge {\n  display: inline-block;\n  padding: $badge-padding-y $badge-padding-x;\n  @include font-size($badge-font-size);\n  font-weight: $badge-font-weight;\n  line-height: 1;\n  color: $badge-color;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  @include border-radius($badge-border-radius);\n  @include gradient-bg();\n\n  // Empty badges collapse automatically\n  &:empty {\n    display: none;\n  }\n}\n\n// Quick fix for badges in buttons\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_breadcrumb.scss",
    "content": ".breadcrumb {\n  display: flex;\n  flex-wrap: wrap;\n  padding: $breadcrumb-padding-y $breadcrumb-padding-x;\n  margin-bottom: $breadcrumb-margin-bottom;\n  @include font-size($breadcrumb-font-size);\n  list-style: none;\n  background-color: $breadcrumb-bg;\n  @include border-radius($breadcrumb-border-radius);\n}\n\n.breadcrumb-item {\n  // The separator between breadcrumbs (by default, a forward-slash: \"/\")\n  + .breadcrumb-item {\n    padding-left: $breadcrumb-item-padding-x;\n\n    &::before {\n      float: left; // Suppress inline spacings and underlining of the separator\n      padding-right: $breadcrumb-item-padding-x;\n      color: $breadcrumb-divider-color;\n      content: var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{\"/* rtl:\"} var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{\"*/\"};\n    }\n  }\n\n  &.active {\n    color: $breadcrumb-active-color;\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_button-group.scss",
    "content": "// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-flex;\n  vertical-align: middle; // match .btn alignment given font-size hack above\n\n  > .btn {\n    position: relative;\n    flex: 1 1 auto;\n  }\n\n  // Bring the hover, focused, and \"active\" buttons to the front to overlay\n  // the borders properly\n  > .btn-check:checked + .btn,\n  > .btn-check:focus + .btn,\n  > .btn:hover,\n  > .btn:focus,\n  > .btn:active,\n  > .btn.active {\n    z-index: 1;\n  }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n\n  .input-group {\n    width: auto;\n  }\n}\n\n.btn-group {\n  // Prevent double borders when buttons are next to each other\n  > .btn:not(:first-child),\n  > .btn-group:not(:first-child) {\n    margin-left: -$btn-border-width;\n  }\n\n  // Reset rounded corners\n  > .btn:not(:last-child):not(.dropdown-toggle),\n  > .btn-group:not(:last-child) > .btn {\n    @include border-end-radius(0);\n  }\n\n  // The left radius should be 0 if the button is:\n  // - the \"third or more\" child\n  // - the second child and the previous element isn't `.btn-check` (making it the first child visually)\n  // - part of a btn-group which isn't the first child\n  > .btn:nth-child(n + 3),\n  > :not(.btn-check) + .btn,\n  > .btn-group:not(:first-child) > .btn {\n    @include border-start-radius(0);\n  }\n}\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-sm > .btn { @extend .btn-sm; }\n.btn-group-lg > .btn { @extend .btn-lg; }\n\n\n//\n// Split button dropdowns\n//\n\n.dropdown-toggle-split {\n  padding-right: $btn-padding-x * .75;\n  padding-left: $btn-padding-x * .75;\n\n  &::after,\n  .dropup &::after,\n  .dropend &::after {\n    margin-left: 0;\n  }\n\n  .dropstart &::before {\n    margin-right: 0;\n  }\n}\n\n.btn-sm + .dropdown-toggle-split {\n  padding-right: $btn-padding-x-sm * .75;\n  padding-left: $btn-padding-x-sm * .75;\n}\n\n.btn-lg + .dropdown-toggle-split {\n  padding-right: $btn-padding-x-lg * .75;\n  padding-left: $btn-padding-x-lg * .75;\n}\n\n\n// The clickable button for toggling the menu\n// Set the same inset shadow as the :active state\n.btn-group.show .dropdown-toggle {\n  @include box-shadow($btn-active-box-shadow);\n\n  // Show no shadow for `.btn-link` since it has no other button styles.\n  &.btn-link {\n    @include box-shadow(none);\n  }\n}\n\n\n//\n// Vertical button groups\n//\n\n.btn-group-vertical {\n  flex-direction: column;\n  align-items: flex-start;\n  justify-content: center;\n\n  > .btn,\n  > .btn-group {\n    width: 100%;\n  }\n\n  > .btn:not(:first-child),\n  > .btn-group:not(:first-child) {\n    margin-top: -$btn-border-width;\n  }\n\n  // Reset rounded corners\n  > .btn:not(:last-child):not(.dropdown-toggle),\n  > .btn-group:not(:last-child) > .btn {\n    @include border-bottom-radius(0);\n  }\n\n  > .btn ~ .btn,\n  > .btn-group:not(:first-child) > .btn {\n    @include border-top-radius(0);\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_buttons.scss",
    "content": "//\n// Base styles\n//\n\n.btn {\n  display: inline-block;\n  font-family: $btn-font-family;\n  font-weight: $btn-font-weight;\n  line-height: $btn-line-height;\n  color: $body-color;\n  text-align: center;\n  text-decoration: if($link-decoration == none, null, none);\n  white-space: $btn-white-space;\n  vertical-align: middle;\n  cursor: if($enable-button-pointers, pointer, null);\n  user-select: none;\n  background-color: transparent;\n  border: $btn-border-width solid transparent;\n  @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius);\n  @include transition($btn-transition);\n\n  &:hover {\n    color: $body-color;\n    text-decoration: if($link-hover-decoration == underline, none, null);\n  }\n\n  .btn-check:focus + &,\n  &:focus {\n    outline: 0;\n    box-shadow: $btn-focus-box-shadow;\n  }\n\n  .btn-check:checked + &,\n  .btn-check:active + &,\n  &:active,\n  &.active {\n    @include box-shadow($btn-active-box-shadow);\n\n    &:focus {\n      @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);\n    }\n  }\n\n  &:disabled,\n  &.disabled,\n  fieldset:disabled & {\n    pointer-events: none;\n    opacity: $btn-disabled-opacity;\n    @include box-shadow(none);\n  }\n}\n\n\n//\n// Alternate buttons\n//\n\n// scss-docs-start btn-variant-loops\n@each $color, $value in $theme-colors {\n  .btn-#{$color} {\n    @include button-variant($value, $value);\n  }\n}\n\n@each $color, $value in $theme-colors {\n  .btn-outline-#{$color} {\n    @include button-outline-variant($value);\n  }\n}\n// scss-docs-end btn-variant-loops\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n  font-weight: $font-weight-normal;\n  color: $btn-link-color;\n  text-decoration: $link-decoration;\n\n  &:hover {\n    color: $btn-link-hover-color;\n    text-decoration: $link-hover-decoration;\n  }\n\n  &:focus {\n    text-decoration: $link-hover-decoration;\n  }\n\n  &:disabled,\n  &.disabled {\n    color: $btn-link-disabled-color;\n  }\n\n  // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n  @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n  @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_card.scss",
    "content": "//\n// Base styles\n//\n\n.card {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106\n  height: $card-height;\n  word-wrap: break-word;\n  background-color: $card-bg;\n  background-clip: border-box;\n  border: $card-border-width solid $card-border-color;\n  @include border-radius($card-border-radius);\n  @include box-shadow($card-box-shadow);\n\n  > hr {\n    margin-right: 0;\n    margin-left: 0;\n  }\n\n  > .list-group {\n    border-top: inherit;\n    border-bottom: inherit;\n\n    &:first-child {\n      border-top-width: 0;\n      @include border-top-radius($card-inner-border-radius);\n    }\n\n    &:last-child  {\n      border-bottom-width: 0;\n      @include border-bottom-radius($card-inner-border-radius);\n    }\n  }\n\n  // Due to specificity of the above selector (`.card > .list-group`), we must\n  // use a child selector here to prevent double borders.\n  > .card-header + .list-group,\n  > .list-group + .card-footer {\n    border-top: 0;\n  }\n}\n\n.card-body {\n  // Enable `flex-grow: 1` for decks and groups so that card blocks take up\n  // as much space as possible, ensuring footers are aligned to the bottom.\n  flex: 1 1 auto;\n  padding: $card-spacer-y $card-spacer-x;\n  color: $card-color;\n}\n\n.card-title {\n  margin-bottom: $card-title-spacer-y;\n}\n\n.card-subtitle {\n  margin-top: -$card-title-spacer-y * .5;\n  margin-bottom: 0;\n}\n\n.card-text:last-child {\n  margin-bottom: 0;\n}\n\n.card-link {\n  &:hover {\n    text-decoration: if($link-hover-decoration == underline, none, null);\n  }\n\n  + .card-link {\n    margin-left: $card-spacer-x;\n  }\n}\n\n//\n// Optional textual caps\n//\n\n.card-header {\n  padding: $card-cap-padding-y $card-cap-padding-x;\n  margin-bottom: 0; // Removes the default margin-bottom of <hN>\n  color: $card-cap-color;\n  background-color: $card-cap-bg;\n  border-bottom: $card-border-width solid $card-border-color;\n\n  &:first-child {\n    @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);\n  }\n}\n\n.card-footer {\n  padding: $card-cap-padding-y $card-cap-padding-x;\n  color: $card-cap-color;\n  background-color: $card-cap-bg;\n  border-top: $card-border-width solid $card-border-color;\n\n  &:last-child {\n    @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);\n  }\n}\n\n\n//\n// Header navs\n//\n\n.card-header-tabs {\n  margin-right: -$card-cap-padding-x * .5;\n  margin-bottom: -$card-cap-padding-y;\n  margin-left: -$card-cap-padding-x * .5;\n  border-bottom: 0;\n\n  @if $nav-tabs-link-active-bg != $card-bg {\n    .nav-link.active {\n      background-color: $card-bg;\n      border-bottom-color: $card-bg;\n    }\n  }\n}\n\n.card-header-pills {\n  margin-right: -$card-cap-padding-x * .5;\n  margin-left: -$card-cap-padding-x * .5;\n}\n\n// Card image\n.card-img-overlay {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  padding: $card-img-overlay-padding;\n  @include border-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n  width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n}\n\n.card-img,\n.card-img-top {\n  @include border-top-radius($card-inner-border-radius);\n}\n\n.card-img,\n.card-img-bottom {\n  @include border-bottom-radius($card-inner-border-radius);\n}\n\n\n//\n// Card groups\n//\n\n.card-group {\n  // The child selector allows nested `.card` within `.card-group`\n  // to display properly.\n  > .card {\n    margin-bottom: $card-group-margin;\n  }\n\n  @include media-breakpoint-up(sm) {\n    display: flex;\n    flex-flow: row wrap;\n    // The child selector allows nested `.card` within `.card-group`\n    // to display properly.\n    > .card {\n      // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n      flex: 1 0 0%;\n      margin-bottom: 0;\n\n      + .card {\n        margin-left: 0;\n        border-left: 0;\n      }\n\n      // Handle rounded corners\n      @if $enable-rounded {\n        &:not(:last-child) {\n          @include border-end-radius(0);\n\n          .card-img-top,\n          .card-header {\n            // stylelint-disable-next-line property-disallowed-list\n            border-top-right-radius: 0;\n          }\n          .card-img-bottom,\n          .card-footer {\n            // stylelint-disable-next-line property-disallowed-list\n            border-bottom-right-radius: 0;\n          }\n        }\n\n        &:not(:first-child) {\n          @include border-start-radius(0);\n\n          .card-img-top,\n          .card-header {\n            // stylelint-disable-next-line property-disallowed-list\n            border-top-left-radius: 0;\n          }\n          .card-img-bottom,\n          .card-footer {\n            // stylelint-disable-next-line property-disallowed-list\n            border-bottom-left-radius: 0;\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_carousel.scss",
    "content": "// Notes on the classes:\n//\n// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)\n//    even when their scroll action started on a carousel, but for compatibility (with Firefox)\n//    we're preventing all actions instead\n// 2. The .carousel-item-start and .carousel-item-end is used to indicate where\n//    the active slide is heading.\n// 3. .active.carousel-item is the current slide.\n// 4. .active.carousel-item-start and .active.carousel-item-end is the current\n//    slide in its in-transition state. Only one of these occurs at a time.\n// 5. .carousel-item-next.carousel-item-start and .carousel-item-prev.carousel-item-end\n//    is the upcoming slide in transition.\n\n.carousel {\n  position: relative;\n}\n\n.carousel.pointer-event {\n  touch-action: pan-y;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n  @include clearfix();\n}\n\n.carousel-item {\n  position: relative;\n  display: none;\n  float: left;\n  width: 100%;\n  margin-right: -100%;\n  backface-visibility: hidden;\n  @include transition($carousel-transition);\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n  display: block;\n}\n\n/* rtl:begin:ignore */\n.carousel-item-next:not(.carousel-item-start),\n.active.carousel-item-end {\n  transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-end),\n.active.carousel-item-start {\n  transform: translateX(-100%);\n}\n\n/* rtl:end:ignore */\n\n\n//\n// Alternate transitions\n//\n\n.carousel-fade {\n  .carousel-item {\n    opacity: 0;\n    transition-property: opacity;\n    transform: none;\n  }\n\n  .carousel-item.active,\n  .carousel-item-next.carousel-item-start,\n  .carousel-item-prev.carousel-item-end {\n    z-index: 1;\n    opacity: 1;\n  }\n\n  .active.carousel-item-start,\n  .active.carousel-item-end {\n    z-index: 0;\n    opacity: 0;\n    @include transition(opacity 0s $carousel-transition-duration);\n  }\n}\n\n\n//\n// Left/right controls for nav\n//\n\n.carousel-control-prev,\n.carousel-control-next {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  z-index: 1;\n  // Use flex for alignment (1-3)\n  display: flex; // 1. allow flex styles\n  align-items: center; // 2. vertically center contents\n  justify-content: center; // 3. horizontally center contents\n  width: $carousel-control-width;\n  padding: 0;\n  color: $carousel-control-color;\n  text-align: center;\n  background: none;\n  border: 0;\n  opacity: $carousel-control-opacity;\n  @include transition($carousel-control-transition);\n\n  // Hover/focus state\n  &:hover,\n  &:focus {\n    color: $carousel-control-color;\n    text-decoration: none;\n    outline: 0;\n    opacity: $carousel-control-hover-opacity;\n  }\n}\n.carousel-control-prev {\n  left: 0;\n  background-image: if($enable-gradients, linear-gradient(90deg, rgba($black, .25), rgba($black, .001)), null);\n}\n.carousel-control-next {\n  right: 0;\n  background-image: if($enable-gradients, linear-gradient(270deg, rgba($black, .25), rgba($black, .001)), null);\n}\n\n// Icons for within\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n  display: inline-block;\n  width: $carousel-control-icon-width;\n  height: $carousel-control-icon-width;\n  background-repeat: no-repeat;\n  background-position: 50%;\n  background-size: 100% 100%;\n}\n\n/* rtl:options: {\n  \"autoRename\": true,\n  \"stringMap\":[ {\n    \"name\"    : \"prev-next\",\n    \"search\"  : \"prev\",\n    \"replace\" : \"next\"\n  } ]\n} */\n.carousel-control-prev-icon {\n  background-image: escape-svg($carousel-control-prev-icon-bg);\n}\n.carousel-control-next-icon {\n  background-image: escape-svg($carousel-control-next-icon-bg);\n}\n\n// Optional indicator pips/controls\n//\n// Add a container (such as a list) with the following class and add an item (ideally a focusable control,\n// like a button) with data-bs-target for each slide your carousel holds.\n\n.carousel-indicators {\n  position: absolute;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 2;\n  display: flex;\n  justify-content: center;\n  padding: 0;\n  // Use the .carousel-control's width as margin so we don't overlay those\n  margin-right: $carousel-control-width;\n  margin-bottom: 1rem;\n  margin-left: $carousel-control-width;\n  list-style: none;\n\n  [data-bs-target] {\n    box-sizing: content-box;\n    flex: 0 1 auto;\n    width: $carousel-indicator-width;\n    height: $carousel-indicator-height;\n    padding: 0;\n    margin-right: $carousel-indicator-spacer;\n    margin-left: $carousel-indicator-spacer;\n    text-indent: -999px;\n    cursor: pointer;\n    background-color: $carousel-indicator-active-bg;\n    background-clip: padding-box;\n    border: 0;\n    // Use transparent borders to increase the hit area by 10px on top and bottom.\n    border-top: $carousel-indicator-hit-area-height solid transparent;\n    border-bottom: $carousel-indicator-hit-area-height solid transparent;\n    opacity: $carousel-indicator-opacity;\n    @include transition($carousel-indicator-transition);\n  }\n\n  .active {\n    opacity: $carousel-indicator-active-opacity;\n  }\n}\n\n\n// Optional captions\n//\n//\n\n.carousel-caption {\n  position: absolute;\n  right: (100% - $carousel-caption-width) * .5;\n  bottom: $carousel-caption-spacer;\n  left: (100% - $carousel-caption-width) * .5;\n  padding-top: $carousel-caption-padding-y;\n  padding-bottom: $carousel-caption-padding-y;\n  color: $carousel-caption-color;\n  text-align: center;\n}\n\n// Dark mode carousel\n\n.carousel-dark {\n  .carousel-control-prev-icon,\n  .carousel-control-next-icon {\n    filter: $carousel-dark-control-icon-filter;\n  }\n\n  .carousel-indicators [data-bs-target] {\n    background-color: $carousel-dark-indicator-active-bg;\n  }\n\n  .carousel-caption {\n    color: $carousel-dark-caption-color;\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_close.scss",
    "content": "// transparent background and border properties included for button version.\n// iOS requires the button element instead of an anchor tag.\n// If you want the anchor version, it requires `href=\"#\"`.\n// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n.btn-close {\n  box-sizing: content-box;\n  width: $btn-close-width;\n  height: $btn-close-height;\n  padding: $btn-close-padding-y $btn-close-padding-x;\n  color: $btn-close-color;\n  background: transparent escape-svg($btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements\n  border: 0; // for button elements\n  @include border-radius();\n  opacity: $btn-close-opacity;\n\n  // Override <a>'s hover style\n  &:hover {\n    color: $btn-close-color;\n    text-decoration: none;\n    opacity: $btn-close-hover-opacity;\n  }\n\n  &:focus {\n    outline: 0;\n    box-shadow: $btn-close-focus-shadow;\n    opacity: $btn-close-focus-opacity;\n  }\n\n  &:disabled,\n  &.disabled {\n    pointer-events: none;\n    user-select: none;\n    opacity: $btn-close-disabled-opacity;\n  }\n}\n\n.btn-close-white {\n  filter: $btn-close-white-filter;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_containers.scss",
    "content": "// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n  // Single container class with breakpoint max-widths\n  .container,\n  // 100% wide container at all breakpoints\n  .container-fluid {\n    @include make-container();\n  }\n\n  // Responsive containers that are 100% wide until a breakpoint\n  @each $breakpoint, $container-max-width in $container-max-widths {\n    .container-#{$breakpoint} {\n      @extend .container-fluid;\n    }\n\n    @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n      %responsive-container-#{$breakpoint} {\n        max-width: $container-max-width;\n      }\n\n      // Extend each breakpoint which is smaller or equal to the current breakpoint\n      $extend-breakpoint: true;\n\n      @each $name, $width in $grid-breakpoints {\n        @if ($extend-breakpoint) {\n          .container#{breakpoint-infix($name, $grid-breakpoints)} {\n            @extend %responsive-container-#{$breakpoint};\n          }\n\n          // Once the current breakpoint is reached, stop extending\n          @if ($breakpoint == $name) {\n            $extend-breakpoint: false;\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_dropdown.scss",
    "content": "// The dropdown wrapper (`<div>`)\n.dropup,\n.dropend,\n.dropdown,\n.dropstart {\n  position: relative;\n}\n\n.dropdown-toggle {\n  white-space: nowrap;\n\n  // Generate the caret automatically\n  @include caret();\n}\n\n// The dropdown menu\n.dropdown-menu {\n  position: absolute;\n  z-index: $zindex-dropdown;\n  display: none; // none by default, but block on \"open\" of the menu\n  min-width: $dropdown-min-width;\n  padding: $dropdown-padding-y $dropdown-padding-x;\n  margin: 0; // Override default margin of ul\n  @include font-size($dropdown-font-size);\n  color: $dropdown-color;\n  text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n  list-style: none;\n  background-color: $dropdown-bg;\n  background-clip: padding-box;\n  border: $dropdown-border-width solid $dropdown-border-color;\n  @include border-radius($dropdown-border-radius);\n  @include box-shadow($dropdown-box-shadow);\n\n  &[data-bs-popper] {\n    top: 100%;\n    left: 0;\n    margin-top: $dropdown-spacer;\n  }\n}\n\n// scss-docs-start responsive-breakpoints\n// We deliberately hardcode the `bs-` prefix because we check\n// this custom property in JS to determine Popper's positioning\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n  @include media-breakpoint-up($breakpoint) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    .dropdown-menu#{$infix}-start {\n      --bs-position: start;\n\n      &[data-bs-popper] {\n        right: auto;\n        left: 0;\n      }\n    }\n\n    .dropdown-menu#{$infix}-end {\n      --bs-position: end;\n\n      &[data-bs-popper] {\n        right: 0;\n        left: auto;\n      }\n    }\n  }\n}\n// scss-docs-end responsive-breakpoints\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n// Just add .dropup after the standard .dropdown class and you're set.\n.dropup {\n  .dropdown-menu[data-bs-popper] {\n    top: auto;\n    bottom: 100%;\n    margin-top: 0;\n    margin-bottom: $dropdown-spacer;\n  }\n\n  .dropdown-toggle {\n    @include caret(up);\n  }\n}\n\n.dropend {\n  .dropdown-menu[data-bs-popper] {\n    top: 0;\n    right: auto;\n    left: 100%;\n    margin-top: 0;\n    margin-left: $dropdown-spacer;\n  }\n\n  .dropdown-toggle {\n    @include caret(end);\n    &::after {\n      vertical-align: 0;\n    }\n  }\n}\n\n.dropstart {\n  .dropdown-menu[data-bs-popper] {\n    top: 0;\n    right: 100%;\n    left: auto;\n    margin-top: 0;\n    margin-right: $dropdown-spacer;\n  }\n\n  .dropdown-toggle {\n    @include caret(start);\n    &::before {\n      vertical-align: 0;\n    }\n  }\n}\n\n\n// Dividers (basically an `<hr>`) within the dropdown\n.dropdown-divider {\n  height: 0;\n  margin: $dropdown-divider-margin-y 0;\n  overflow: hidden;\n  border-top: 1px solid $dropdown-divider-bg;\n}\n\n// Links, buttons, and more within the dropdown menu\n//\n// `<button>`-specific styles are denoted with `// For <button>s`\n.dropdown-item {\n  display: block;\n  width: 100%; // For `<button>`s\n  padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n  clear: both;\n  font-weight: $font-weight-normal;\n  color: $dropdown-link-color;\n  text-align: inherit; // For `<button>`s\n  text-decoration: if($link-decoration == none, null, none);\n  white-space: nowrap; // prevent links from randomly breaking onto new lines\n  background-color: transparent; // For `<button>`s\n  border: 0; // For `<button>`s\n\n  // Prevent dropdown overflow if there's no padding\n  // See https://github.com/twbs/bootstrap/pull/27703\n  @if $dropdown-padding-y == 0 {\n    &:first-child {\n      @include border-top-radius($dropdown-inner-border-radius);\n    }\n\n    &:last-child {\n      @include border-bottom-radius($dropdown-inner-border-radius);\n    }\n  }\n\n  &:hover,\n  &:focus {\n    color: $dropdown-link-hover-color;\n    text-decoration: if($link-hover-decoration == underline, none, null);\n    @include gradient-bg($dropdown-link-hover-bg);\n  }\n\n  &.active,\n  &:active {\n    color: $dropdown-link-active-color;\n    text-decoration: none;\n    @include gradient-bg($dropdown-link-active-bg);\n  }\n\n  &.disabled,\n  &:disabled {\n    color: $dropdown-link-disabled-color;\n    pointer-events: none;\n    background-color: transparent;\n    // Remove CSS gradients if they're enabled\n    background-image: if($enable-gradients, none, null);\n  }\n}\n\n.dropdown-menu.show {\n  display: block;\n}\n\n// Dropdown section headers\n.dropdown-header {\n  display: block;\n  padding: $dropdown-header-padding;\n  margin-bottom: 0; // for use with heading elements\n  @include font-size($font-size-sm);\n  color: $dropdown-header-color;\n  white-space: nowrap; // as with > li > a\n}\n\n// Dropdown text\n.dropdown-item-text {\n  display: block;\n  padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n  color: $dropdown-link-color;\n}\n\n// Dark dropdowns\n.dropdown-menu-dark {\n  color: $dropdown-dark-color;\n  background-color: $dropdown-dark-bg;\n  border-color: $dropdown-dark-border-color;\n  @include box-shadow($dropdown-dark-box-shadow);\n\n  .dropdown-item {\n    color: $dropdown-dark-link-color;\n\n    &:hover,\n    &:focus {\n      color: $dropdown-dark-link-hover-color;\n      @include gradient-bg($dropdown-dark-link-hover-bg);\n    }\n\n    &.active,\n    &:active {\n      color: $dropdown-dark-link-active-color;\n      @include gradient-bg($dropdown-dark-link-active-bg);\n    }\n\n    &.disabled,\n    &:disabled {\n      color: $dropdown-dark-link-disabled-color;\n    }\n  }\n\n  .dropdown-divider {\n    border-color: $dropdown-dark-divider-bg;\n  }\n\n  .dropdown-item-text {\n    color: $dropdown-dark-link-color;\n  }\n\n  .dropdown-header {\n    color: $dropdown-dark-header-color;\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_forms.scss",
    "content": "@import \"forms/labels\";\n@import \"forms/form-text\";\n@import \"forms/form-control\";\n@import \"forms/form-select\";\n@import \"forms/form-check\";\n@import \"forms/form-range\";\n@import \"forms/floating-labels\";\n@import \"forms/input-group\";\n@import \"forms/validation\";\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_functions.scss",
    "content": "// Bootstrap functions\n//\n// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.\n\n// Ascending\n// Used to evaluate Sass maps like our grid breakpoints.\n@mixin _assert-ascending($map, $map-name) {\n  $prev-key: null;\n  $prev-num: null;\n  @each $key, $num in $map {\n    @if $prev-num == null or unit($num) == \"%\" or unit($prev-num) == \"%\" {\n      // Do nothing\n    } @else if not comparable($prev-num, $num) {\n      @warn \"Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n    } @else if $prev-num >= $num {\n      @warn \"Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n    }\n    $prev-key: $key;\n    $prev-num: $num;\n  }\n}\n\n// Starts at zero\n// Used to ensure the min-width of the lowest breakpoint starts at 0.\n@mixin _assert-starts-at-zero($map, $map-name: \"$grid-breakpoints\") {\n  @if length($map) > 0 {\n    $values: map-values($map);\n    $first-value: nth($values, 1);\n    @if $first-value != 0 {\n      @warn \"First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.\";\n    }\n  }\n}\n\n// Colors\n@function to-rgb($value) {\n  @return red($value), green($value), blue($value);\n}\n\n// stylelint-disable scss/dollar-variable-pattern\n@function rgba-css-var($identifier, $target) {\n  @if $identifier == \"body\" and $target == \"bg\" {\n    @return rgba(var(--#{$variable-prefix}#{$identifier}-bg-rgb), var(--#{$variable-prefix}#{$target}-opacity));\n  } @if $identifier == \"body\" and $target == \"text\" {\n    @return rgba(var(--#{$variable-prefix}#{$identifier}-color-rgb), var(--#{$variable-prefix}#{$target}-opacity));\n  } @else {\n    @return rgba(var(--#{$variable-prefix}#{$identifier}-rgb), var(--#{$variable-prefix}#{$target}-opacity));\n  }\n}\n\n@function map-loop($map, $func, $args...) {\n  $_map: ();\n\n  @each $key, $value in $map {\n    // allow to pass the $key and $value of the map as an function argument\n    $_args: ();\n    @each $arg in $args {\n      $_args: append($_args, if($arg == \"$key\", $key, if($arg == \"$value\", $value, $arg)));\n    }\n\n    $_map: map-merge($_map, ($key: call(get-function($func), $_args...)));\n  }\n\n  @return $_map;\n}\n// stylelint-enable scss/dollar-variable-pattern\n\n@function varify($list) {\n  $result: null;\n  @each $entry in $list {\n    $result: append($result, var(--#{$variable-prefix}#{$entry}), space);\n  }\n  @return $result;\n}\n\n// Internal Bootstrap function to turn maps into its negative variant.\n// It prefixes the keys with `n` and makes the value negative.\n@function negativify-map($map) {\n  $result: ();\n  @each $key, $value in $map {\n    @if $key != 0 {\n      $result: map-merge($result, (\"n\" + $key: (-$value)));\n    }\n  }\n  @return $result;\n}\n\n// Get multiple keys from a sass map\n@function map-get-multiple($map, $values) {\n  $result: ();\n  @each $key, $value in $map {\n    @if (index($values, $key) != null) {\n      $result: map-merge($result, ($key: $value));\n    }\n  }\n  @return $result;\n}\n\n// Merge multiple maps\n@function map-merge-multiple($maps...) {\n  $merged-maps: ();\n\n  @each $map in $maps {\n    $merged-maps: map-merge($merged-maps, $map);\n  }\n  @return $merged-maps;\n}\n\n// Replace `$search` with `$replace` in `$string`\n// Used on our SVG icon backgrounds for custom forms.\n//\n// @author Hugo Giraudel\n// @param {String} $string - Initial string\n// @param {String} $search - Substring to replace\n// @param {String} $replace ('') - New value\n// @return {String} - Updated string\n@function str-replace($string, $search, $replace: \"\") {\n  $index: str-index($string, $search);\n\n  @if $index {\n    @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);\n  }\n\n  @return $string;\n}\n\n// See https://codepen.io/kevinweber/pen/dXWoRw\n//\n// Requires the use of quotes around data URIs.\n\n@function escape-svg($string) {\n  @if str-index($string, \"data:image/svg+xml\") {\n    @each $char, $encoded in $escaped-characters {\n      // Do not escape the url brackets\n      @if str-index($string, \"url(\") == 1 {\n        $string: url(\"#{str-replace(str-slice($string, 6, -3), $char, $encoded)}\");\n      } @else {\n        $string: str-replace($string, $char, $encoded);\n      }\n    }\n  }\n\n  @return $string;\n}\n\n// Color contrast\n// See https://github.com/twbs/bootstrap/pull/30168\n\n// A list of pre-calculated numbers of pow(divide((divide($value, 255) + .055), 1.055), 2.4). (from 0 to 255)\n// stylelint-disable-next-line scss/dollar-variable-default, scss/dollar-variable-pattern\n$_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 .0033 .0037 .004 .0044 .0048 .0052 .0056 .006 .0065 .007 .0075 .008 .0086 .0091 .0097 .0103 .011 .0116 .0123 .013 .0137 .0144 .0152 .016 .0168 .0176 .0185 .0194 .0203 .0212 .0222 .0232 .0242 .0252 .0262 .0273 .0284 .0296 .0307 .0319 .0331 .0343 .0356 .0369 .0382 .0395 .0409 .0423 .0437 .0452 .0467 .0482 .0497 .0513 .0529 .0545 .0561 .0578 .0595 .0612 .063 .0648 .0666 .0685 .0704 .0723 .0742 .0762 .0782 .0802 .0823 .0844 .0865 .0887 .0908 .0931 .0953 .0976 .0999 .1022 .1046 .107 .1095 .1119 .1144 .117 .1195 .1221 .1248 .1274 .1301 .1329 .1356 .1384 .1413 .1441 .147 .15 .1529 .1559 .159 .162 .1651 .1683 .1714 .1746 .1779 .1812 .1845 .1878 .1912 .1946 .1981 .2016 .2051 .2086 .2122 .2159 .2195 .2232 .227 .2307 .2346 .2384 .2423 .2462 .2502 .2542 .2582 .2623 .2664 .2705 .2747 .2789 .2831 .2874 .2918 .2961 .3005 .305 .3095 .314 .3185 .3231 .3278 .3325 .3372 .3419 .3467 .3515 .3564 .3613 .3663 .3712 .3763 .3813 .3864 .3916 .3968 .402 .4072 .4125 .4179 .4233 .4287 .4342 .4397 .4452 .4508 .4564 .4621 .4678 .4735 .4793 .4851 .491 .4969 .5029 .5089 .5149 .521 .5271 .5333 .5395 .5457 .552 .5583 .5647 .5711 .5776 .5841 .5906 .5972 .6038 .6105 .6172 .624 .6308 .6376 .6445 .6514 .6584 .6654 .6724 .6795 .6867 .6939 .7011 .7084 .7157 .7231 .7305 .7379 .7454 .7529 .7605 .7682 .7758 .7835 .7913 .7991 .807 .8148 .8228 .8308 .8388 .8469 .855 .8632 .8714 .8796 .8879 .8963 .9047 .9131 .9216 .9301 .9387 .9473 .956 .9647 .9734 .9823 .9911 1;\n\n@function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light, $min-contrast-ratio: $min-contrast-ratio) {\n  $foregrounds: $color-contrast-light, $color-contrast-dark, $white, $black;\n  $max-ratio: 0;\n  $max-ratio-color: null;\n\n  @each $color in $foregrounds {\n    $contrast-ratio: contrast-ratio($background, $color);\n    @if $contrast-ratio > $min-contrast-ratio {\n      @return $color;\n    } @else if $contrast-ratio > $max-ratio {\n      $max-ratio: $contrast-ratio;\n      $max-ratio-color: $color;\n    }\n  }\n\n  @warn \"Found no color leading to #{$min-contrast-ratio}:1 contrast ratio against #{$background}...\";\n\n  @return $max-ratio-color;\n}\n\n@function contrast-ratio($background, $foreground: $color-contrast-light) {\n  $l1: luminance($background);\n  $l2: luminance(opaque($background, $foreground));\n\n  @return if($l1 > $l2, divide($l1 + .05, $l2 + .05), divide($l2 + .05, $l1 + .05));\n}\n\n// Return WCAG2.0 relative luminance\n// See https://www.w3.org/WAI/GL/wiki/Relative_luminance\n// See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests\n@function luminance($color) {\n  $rgb: (\n    \"r\": red($color),\n    \"g\": green($color),\n    \"b\": blue($color)\n  );\n\n  @each $name, $value in $rgb {\n    $value: if(divide($value, 255) < .03928, divide(divide($value, 255), 12.92), nth($_luminance-list, $value + 1));\n    $rgb: map-merge($rgb, ($name: $value));\n  }\n\n  @return (map-get($rgb, \"r\") * .2126) + (map-get($rgb, \"g\") * .7152) + (map-get($rgb, \"b\") * .0722);\n}\n\n// Return opaque color\n// opaque(#fff, rgba(0, 0, 0, .5)) => #808080\n@function opaque($background, $foreground) {\n  @return mix(rgba($foreground, 1), $background, opacity($foreground) * 100);\n}\n\n// scss-docs-start color-functions\n// Tint a color: mix a color with white\n@function tint-color($color, $weight) {\n  @return mix(white, $color, $weight);\n}\n\n// Shade a color: mix a color with black\n@function shade-color($color, $weight) {\n  @return mix(black, $color, $weight);\n}\n\n// Shade the color if the weight is positive, else tint it\n@function shift-color($color, $weight) {\n  @return if($weight > 0, shade-color($color, $weight), tint-color($color, -$weight));\n}\n// scss-docs-end color-functions\n\n// Return valid calc\n@function add($value1, $value2, $return-calc: true) {\n  @if $value1 == null {\n    @return $value2;\n  }\n\n  @if $value2 == null {\n    @return $value1;\n  }\n\n  @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {\n    @return $value1 + $value2;\n  }\n\n  @return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(\" + \") + $value2);\n}\n\n@function subtract($value1, $value2, $return-calc: true) {\n  @if $value1 == null and $value2 == null {\n    @return null;\n  }\n\n  @if $value1 == null {\n    @return -$value2;\n  }\n\n  @if $value2 == null {\n    @return $value1;\n  }\n\n  @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {\n    @return $value1 - $value2;\n  }\n\n  @if type-of($value2) != number {\n    $value2: unquote(\"(\") + $value2 + unquote(\")\");\n  }\n\n  @return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(\" - \") + $value2);\n}\n\n@function divide($dividend, $divisor, $precision: 10) {\n  $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);\n  $dividend: abs($dividend);\n  $divisor: abs($divisor);\n  @if $dividend == 0 {\n    @return 0;\n  }\n  @if $divisor == 0 {\n    @error \"Cannot divide by 0\";\n  }\n  $remainder: $dividend;\n  $result: 0;\n  $factor: 10;\n  @while ($remainder > 0 and $precision >= 0) {\n    $quotient: 0;\n    @while ($remainder >= $divisor) {\n      $remainder: $remainder - $divisor;\n      $quotient: $quotient + 1;\n    }\n    $result: $result * 10 + $quotient;\n    $factor: $factor * .1;\n    $remainder: $remainder * 10;\n    $precision: $precision - 1;\n    @if ($precision < 0 and $remainder >= $divisor * 5) {\n      $result: $result + 1;\n    }\n  }\n  $result: $result * $factor * $sign;\n  $dividend-unit: unit($dividend);\n  $divisor-unit: unit($divisor);\n  $unit-map: (\n    \"px\": 1px,\n    \"rem\": 1rem,\n    \"em\": 1em,\n    \"%\": 1%\n  );\n  @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {\n    $result: $result * map-get($unit-map, $dividend-unit);\n  }\n  @return $result;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_grid.scss",
    "content": "// Row\n//\n// Rows contain your columns.\n\n@if $enable-grid-classes {\n  .row {\n    @include make-row();\n\n    > * {\n      @include make-col-ready();\n    }\n  }\n}\n\n@if $enable-cssgrid {\n  .grid {\n    display: grid;\n    grid-template-rows: repeat(var(--#{$variable-prefix}rows, 1), 1fr);\n    grid-template-columns: repeat(var(--#{$variable-prefix}columns, #{$grid-columns}), 1fr);\n    gap: var(--#{$variable-prefix}gap, #{$grid-gutter-width});\n\n    @include make-cssgrid();\n  }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n  @include make-grid-columns();\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_helpers.scss",
    "content": "@import \"helpers/clearfix\";\n@import \"helpers/colored-links\";\n@import \"helpers/ratio\";\n@import \"helpers/position\";\n@import \"helpers/stacks\";\n@import \"helpers/visually-hidden\";\n@import \"helpers/stretched-link\";\n@import \"helpers/text-truncation\";\n@import \"helpers/vr\";\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_images.scss",
    "content": "// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n  @include img-fluid();\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n  padding: $thumbnail-padding;\n  background-color: $thumbnail-bg;\n  border: $thumbnail-border-width solid $thumbnail-border-color;\n  @include border-radius($thumbnail-border-radius);\n  @include box-shadow($thumbnail-box-shadow);\n\n  // Keep them at most 100% wide\n  @include img-fluid();\n}\n\n//\n// Figures\n//\n\n.figure {\n  // Ensures the caption's text aligns with the image.\n  display: inline-block;\n}\n\n.figure-img {\n  margin-bottom: $spacer * .5;\n  line-height: 1;\n}\n\n.figure-caption {\n  @include font-size($figure-caption-font-size);\n  color: $figure-caption-color;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_list-group.scss",
    "content": "// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n  display: flex;\n  flex-direction: column;\n\n  // No need to set list-style: none; since .list-group-item is block level\n  padding-left: 0; // reset padding because ul and ol\n  margin-bottom: 0;\n  @include border-radius($list-group-border-radius);\n}\n\n.list-group-numbered {\n  list-style-type: none;\n  counter-reset: section;\n\n  > li::before {\n    // Increments only this instance of the section counter\n    content: counters(section, \".\") \". \";\n    counter-increment: section;\n  }\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive\n// list items. Includes an extra `.active` modifier class for selected items.\n\n.list-group-item-action {\n  width: 100%; // For `<button>`s (anchors become 100% by default though)\n  color: $list-group-action-color;\n  text-align: inherit; // For `<button>`s (anchors inherit)\n\n  // Hover state\n  &:hover,\n  &:focus {\n    z-index: 1; // Place hover/focus items above their siblings for proper border styling\n    color: $list-group-action-hover-color;\n    text-decoration: none;\n    background-color: $list-group-hover-bg;\n  }\n\n  &:active {\n    color: $list-group-action-active-color;\n    background-color: $list-group-action-active-bg;\n  }\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: $list-group-item-padding-y $list-group-item-padding-x;\n  color: $list-group-color;\n  text-decoration: if($link-decoration == none, null, none);\n  background-color: $list-group-bg;\n  border: $list-group-border-width solid $list-group-border-color;\n\n  &:first-child {\n    @include border-top-radius(inherit);\n  }\n\n  &:last-child {\n    @include border-bottom-radius(inherit);\n  }\n\n  &.disabled,\n  &:disabled {\n    color: $list-group-disabled-color;\n    pointer-events: none;\n    background-color: $list-group-disabled-bg;\n  }\n\n  // Include both here for `<a>`s and `<button>`s\n  &.active {\n    z-index: 2; // Place active items above their siblings for proper border styling\n    color: $list-group-active-color;\n    background-color: $list-group-active-bg;\n    border-color: $list-group-active-border-color;\n  }\n\n  & + & {\n    border-top-width: 0;\n\n    &.active {\n      margin-top: -$list-group-border-width;\n      border-top-width: $list-group-border-width;\n    }\n  }\n}\n\n\n// Horizontal\n//\n// Change the layout of list group items from vertical (default) to horizontal.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n  @include media-breakpoint-up($breakpoint) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    .list-group-horizontal#{$infix} {\n      flex-direction: row;\n\n      > .list-group-item {\n        &:first-child {\n          @include border-bottom-start-radius($list-group-border-radius);\n          @include border-top-end-radius(0);\n        }\n\n        &:last-child {\n          @include border-top-end-radius($list-group-border-radius);\n          @include border-bottom-start-radius(0);\n        }\n\n        &.active {\n          margin-top: 0;\n        }\n\n        + .list-group-item {\n          border-top-width: $list-group-border-width;\n          border-left-width: 0;\n\n          &.active {\n            margin-left: -$list-group-border-width;\n            border-left-width: $list-group-border-width;\n          }\n        }\n      }\n    }\n  }\n}\n\n\n// Flush list items\n//\n// Remove borders and border-radius to keep list group items edge-to-edge. Most\n// useful within other components (e.g., cards).\n\n.list-group-flush {\n  @include border-radius(0);\n\n  > .list-group-item {\n    border-width: 0 0 $list-group-border-width;\n\n    &:last-child {\n      border-bottom-width: 0;\n    }\n  }\n}\n\n\n// scss-docs-start list-group-modifiers\n// List group contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n@each $state, $value in $theme-colors {\n  $list-group-variant-bg: shift-color($value, $list-group-item-bg-scale);\n  $list-group-variant-color: shift-color($value, $list-group-item-color-scale);\n  @if (contrast-ratio($list-group-variant-bg, $list-group-variant-color) < $min-contrast-ratio) {\n    $list-group-variant-color: mix($value, color-contrast($list-group-variant-bg), abs($list-group-item-color-scale));\n  }\n\n  @include list-group-item-variant($state, $list-group-variant-bg, $list-group-variant-color);\n}\n// scss-docs-end list-group-modifiers\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_mixins.scss",
    "content": "// Toggles\n//\n// Used in conjunction with global variables to enable certain theme features.\n\n// Vendor\n@import \"vendor/rfs\";\n\n// Deprecate\n@import \"mixins/deprecate\";\n\n// Helpers\n@import \"mixins/breakpoints\";\n@import \"mixins/color-scheme\";\n@import \"mixins/image\";\n@import \"mixins/resize\";\n@import \"mixins/visually-hidden\";\n@import \"mixins/reset-text\";\n@import \"mixins/text-truncate\";\n\n// Utilities\n@import \"mixins/utilities\";\n\n// Components\n@import \"mixins/alert\";\n@import \"mixins/backdrop\";\n@import \"mixins/buttons\";\n@import \"mixins/caret\";\n@import \"mixins/pagination\";\n@import \"mixins/lists\";\n@import \"mixins/list-group\";\n@import \"mixins/forms\";\n@import \"mixins/table-variants\";\n\n// Skins\n@import \"mixins/border-radius\";\n@import \"mixins/box-shadow\";\n@import \"mixins/gradients\";\n@import \"mixins/transition\";\n\n// Layout\n@import \"mixins/clearfix\";\n@import \"mixins/container\";\n@import \"mixins/grid\";\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_modal.scss",
    "content": "// .modal-open      - body class for killing the scroll\n// .modal           - container to scroll within\n// .modal-dialog    - positioning shell for the actual modal\n// .modal-content   - actual modal w/ bg and corners and stuff\n\n\n// Container that the modal scrolls within\n.modal {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: $zindex-modal;\n  display: none;\n  width: 100%;\n  height: 100%;\n  overflow-x: hidden;\n  overflow-y: auto;\n  // Prevent Chrome on Windows from adding a focus outline. For details, see\n  // https://github.com/twbs/bootstrap/pull/10951.\n  outline: 0;\n  // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a\n  // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342\n  // See also https://github.com/twbs/bootstrap/issues/17695\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: $modal-dialog-margin;\n  // allow clicks to pass through for custom click handling to close modal\n  pointer-events: none;\n\n  // When fading in the modal, animate it to slide down\n  .modal.fade & {\n    @include transition($modal-transition);\n    transform: $modal-fade-transform;\n  }\n  .modal.show & {\n    transform: $modal-show-transform;\n  }\n\n  // When trying to close, animate focus to scale\n  .modal.modal-static & {\n    transform: $modal-scale-transform;\n  }\n}\n\n.modal-dialog-scrollable {\n  height: subtract(100%, $modal-dialog-margin * 2);\n\n  .modal-content {\n    max-height: 100%;\n    overflow: hidden;\n  }\n\n  .modal-body {\n    overflow-y: auto;\n  }\n}\n\n.modal-dialog-centered {\n  display: flex;\n  align-items: center;\n  min-height: subtract(100%, $modal-dialog-margin * 2);\n}\n\n// Actual modal\n.modal-content {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`\n  // counteract the pointer-events: none; in the .modal-dialog\n  color: $modal-content-color;\n  pointer-events: auto;\n  background-color: $modal-content-bg;\n  background-clip: padding-box;\n  border: $modal-content-border-width solid $modal-content-border-color;\n  @include border-radius($modal-content-border-radius);\n  @include box-shadow($modal-content-box-shadow-xs);\n  // Remove focus outline from opened modal\n  outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n  @include overlay-backdrop($zindex-modal-backdrop, $modal-backdrop-bg, $modal-backdrop-opacity);\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n  display: flex;\n  flex-shrink: 0;\n  align-items: center;\n  justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends\n  padding: $modal-header-padding;\n  border-bottom: $modal-header-border-width solid $modal-header-border-color;\n  @include border-top-radius($modal-content-inner-border-radius);\n\n  .btn-close {\n    padding: ($modal-header-padding-y * .5) ($modal-header-padding-x * .5);\n    margin: ($modal-header-padding-y * -.5) ($modal-header-padding-x * -.5) ($modal-header-padding-y * -.5) auto;\n  }\n}\n\n// Title text within header\n.modal-title {\n  margin-bottom: 0;\n  line-height: $modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n  position: relative;\n  // Enable `flex-grow: 1` so that the body take up as much space as possible\n  // when there should be a fixed height on `.modal-dialog`.\n  flex: 1 1 auto;\n  padding: $modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n  display: flex;\n  flex-wrap: wrap;\n  flex-shrink: 0;\n  align-items: center; // vertically center\n  justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items\n  padding: $modal-inner-padding - $modal-footer-margin-between * .5;\n  border-top: $modal-footer-border-width solid $modal-footer-border-color;\n  @include border-bottom-radius($modal-content-inner-border-radius);\n\n  // Place margin between footer elements\n  // This solution is far from ideal because of the universal selector usage,\n  // but is needed to fix https://github.com/twbs/bootstrap/issues/24800\n  > * {\n    margin: $modal-footer-margin-between * .5;\n  }\n}\n\n// Scale up the modal\n@include media-breakpoint-up(sm) {\n  // Automatically set modal's width for larger viewports\n  .modal-dialog {\n    max-width: $modal-md;\n    margin: $modal-dialog-margin-y-sm-up auto;\n  }\n\n  .modal-dialog-scrollable {\n    height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n  }\n\n  .modal-dialog-centered {\n    min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);\n  }\n\n  .modal-content {\n    @include box-shadow($modal-content-box-shadow-sm-up);\n  }\n\n  .modal-sm { max-width: $modal-sm; }\n}\n\n@include media-breakpoint-up(lg) {\n  .modal-lg,\n  .modal-xl {\n    max-width: $modal-lg;\n  }\n}\n\n@include media-breakpoint-up(xl) {\n  .modal-xl { max-width: $modal-xl; }\n}\n\n// scss-docs-start modal-fullscreen-loop\n@each $breakpoint in map-keys($grid-breakpoints) {\n  $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n  $postfix: if($infix != \"\", $infix + \"-down\", \"\");\n\n  @include media-breakpoint-down($breakpoint) {\n    .modal-fullscreen#{$postfix} {\n      width: 100vw;\n      max-width: none;\n      height: 100%;\n      margin: 0;\n\n      .modal-content {\n        height: 100%;\n        border: 0;\n        @include border-radius(0);\n      }\n\n      .modal-header {\n        @include border-radius(0);\n      }\n\n      .modal-body {\n        overflow-y: auto;\n      }\n\n      .modal-footer {\n        @include border-radius(0);\n      }\n    }\n  }\n}\n// scss-docs-end modal-fullscreen-loop\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_nav.scss",
    "content": "// Base class\n//\n// Kickstart any navigation component with a set of style resets. Works with\n// `<nav>`s, `<ul>`s or `<ol>`s.\n\n.nav {\n  display: flex;\n  flex-wrap: wrap;\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n\n.nav-link {\n  display: block;\n  padding: $nav-link-padding-y $nav-link-padding-x;\n  @include font-size($nav-link-font-size);\n  font-weight: $nav-link-font-weight;\n  color: $nav-link-color;\n  text-decoration: if($link-decoration == none, null, none);\n  @include transition($nav-link-transition);\n\n  &:hover,\n  &:focus {\n    color: $nav-link-hover-color;\n    text-decoration: if($link-hover-decoration == underline, none, null);\n  }\n\n  // Disabled state lightens text\n  &.disabled {\n    color: $nav-link-disabled-color;\n    pointer-events: none;\n    cursor: default;\n  }\n}\n\n//\n// Tabs\n//\n\n.nav-tabs {\n  border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;\n\n  .nav-link {\n    margin-bottom: -$nav-tabs-border-width;\n    background: none;\n    border: $nav-tabs-border-width solid transparent;\n    @include border-top-radius($nav-tabs-border-radius);\n\n    &:hover,\n    &:focus {\n      border-color: $nav-tabs-link-hover-border-color;\n      // Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link\n      isolation: isolate;\n    }\n\n    &.disabled {\n      color: $nav-link-disabled-color;\n      background-color: transparent;\n      border-color: transparent;\n    }\n  }\n\n  .nav-link.active,\n  .nav-item.show .nav-link {\n    color: $nav-tabs-link-active-color;\n    background-color: $nav-tabs-link-active-bg;\n    border-color: $nav-tabs-link-active-border-color;\n  }\n\n  .dropdown-menu {\n    // Make dropdown border overlap tab border\n    margin-top: -$nav-tabs-border-width;\n    // Remove the top rounded corners here since there is a hard edge above the menu\n    @include border-top-radius(0);\n  }\n}\n\n\n//\n// Pills\n//\n\n.nav-pills {\n  .nav-link {\n    background: none;\n    border: 0;\n    @include border-radius($nav-pills-border-radius);\n  }\n\n  .nav-link.active,\n  .show > .nav-link {\n    color: $nav-pills-link-active-color;\n    @include gradient-bg($nav-pills-link-active-bg);\n  }\n}\n\n\n//\n// Justified variants\n//\n\n.nav-fill {\n  > .nav-link,\n  .nav-item {\n    flex: 1 1 auto;\n    text-align: center;\n  }\n}\n\n.nav-justified {\n  > .nav-link,\n  .nav-item {\n    flex-basis: 0;\n    flex-grow: 1;\n    text-align: center;\n  }\n}\n\n.nav-fill,\n.nav-justified {\n  .nav-item .nav-link {\n    width: 100%; // Make sure button will grow\n  }\n}\n\n\n// Tabbable tabs\n//\n// Hide tabbable panes to start, show them when `.active`\n\n.tab-content {\n  > .tab-pane {\n    display: none;\n  }\n  > .active {\n    display: block;\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_navbar.scss",
    "content": "// Contents\n//\n// Navbar\n// Navbar brand\n// Navbar nav\n// Navbar text\n// Responsive navbar\n// Navbar position\n// Navbar themes\n\n\n// Navbar\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap; // allow us to do the line break for collapsing content\n  align-items: center;\n  justify-content: space-between; // space out brand from logo\n  padding-top: $navbar-padding-y;\n  padding-right: $navbar-padding-x; // default: null\n  padding-bottom: $navbar-padding-y;\n  padding-left: $navbar-padding-x; // default: null\n  @include gradient-bg();\n\n  // Because flex properties aren't inherited, we need to redeclare these first\n  // few properties so that content nested within behave properly.\n  // The `flex-wrap` property is inherited to simplify the expanded navbars\n  %container-flex-properties {\n    display: flex;\n    flex-wrap: inherit;\n    align-items: center;\n    justify-content: space-between;\n  }\n\n  > .container,\n  > .container-fluid {\n    @extend %container-flex-properties;\n  }\n\n  @each $breakpoint, $container-max-width in $container-max-widths {\n    > .container#{breakpoint-infix($breakpoint, $container-max-widths)} {\n      @extend %container-flex-properties;\n    }\n  }\n}\n\n\n// Navbar brand\n//\n// Used for brand, project, or site names.\n\n.navbar-brand {\n  padding-top: $navbar-brand-padding-y;\n  padding-bottom: $navbar-brand-padding-y;\n  margin-right: $navbar-brand-margin-end;\n  @include font-size($navbar-brand-font-size);\n  text-decoration: if($link-decoration == none, null, none);\n  white-space: nowrap;\n\n  &:hover,\n  &:focus {\n    text-decoration: if($link-hover-decoration == underline, none, null);\n  }\n}\n\n\n// Navbar nav\n//\n// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).\n\n.navbar-nav {\n  display: flex;\n  flex-direction: column; // cannot use `inherit` to get the `.navbar`s value\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n\n  .nav-link {\n    padding-right: 0;\n    padding-left: 0;\n  }\n\n  .dropdown-menu {\n    position: static;\n  }\n}\n\n\n// Navbar text\n//\n//\n\n.navbar-text {\n  padding-top: $nav-link-padding-y;\n  padding-bottom: $nav-link-padding-y;\n}\n\n\n// Responsive navbar\n//\n// Custom styles for responsive collapsing and toggling of navbar contents.\n// Powered by the collapse Bootstrap JavaScript plugin.\n\n// When collapsed, prevent the toggleable navbar contents from appearing in\n// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`\n// on the `.navbar` parent.\n.navbar-collapse {\n  flex-basis: 100%;\n  flex-grow: 1;\n  // For always expanded or extra full navbars, ensure content aligns itself\n  // properly vertically. Can be easily overridden with flex utilities.\n  align-items: center;\n}\n\n// Button for toggling the navbar when in its collapsed state\n.navbar-toggler {\n  padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;\n  @include font-size($navbar-toggler-font-size);\n  line-height: 1;\n  background-color: transparent; // remove default button style\n  border: $border-width solid transparent; // remove default button style\n  @include border-radius($navbar-toggler-border-radius);\n  @include transition($navbar-toggler-transition);\n\n  &:hover {\n    text-decoration: none;\n  }\n\n  &:focus {\n    text-decoration: none;\n    outline: 0;\n    box-shadow: 0 0 0 $navbar-toggler-focus-width;\n  }\n}\n\n// Keep as a separate element so folks can easily override it with another icon\n// or image file as needed.\n.navbar-toggler-icon {\n  display: inline-block;\n  width: 1.5em;\n  height: 1.5em;\n  vertical-align: middle;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: 100%;\n}\n\n.navbar-nav-scroll {\n  max-height: var(--#{$variable-prefix}scroll-height, 75vh);\n  overflow-y: auto;\n}\n\n// scss-docs-start navbar-expand-loop\n// Generate series of `.navbar-expand-*` responsive classes for configuring\n// where your navbar collapses.\n.navbar-expand {\n  @each $breakpoint in map-keys($grid-breakpoints) {\n    $next: breakpoint-next($breakpoint, $grid-breakpoints);\n    $infix: breakpoint-infix($next, $grid-breakpoints);\n\n    // stylelint-disable-next-line scss/selector-no-union-class-name\n    &#{$infix} {\n      @include media-breakpoint-up($next) {\n        flex-wrap: nowrap;\n        justify-content: flex-start;\n\n        .navbar-nav {\n          flex-direction: row;\n\n          .dropdown-menu {\n            position: absolute;\n          }\n\n          .nav-link {\n            padding-right: $navbar-nav-link-padding-x;\n            padding-left: $navbar-nav-link-padding-x;\n          }\n        }\n\n        .navbar-nav-scroll {\n          overflow: visible;\n        }\n\n        .navbar-collapse {\n          display: flex !important; // stylelint-disable-line declaration-no-important\n          flex-basis: auto;\n        }\n\n        .navbar-toggler {\n          display: none;\n        }\n\n        .offcanvas-header {\n          display: none;\n        }\n\n        .offcanvas {\n          position: inherit;\n          bottom: 0;\n          z-index: 1000;\n          flex-grow: 1;\n          visibility: visible !important; // stylelint-disable-line declaration-no-important\n          background-color: transparent;\n          border-right: 0;\n          border-left: 0;\n          @include transition(none);\n          transform: none;\n        }\n        .offcanvas-top,\n        .offcanvas-bottom {\n          height: auto;\n          border-top: 0;\n          border-bottom: 0;\n        }\n\n        .offcanvas-body {\n          display: flex;\n          flex-grow: 0;\n          padding: 0;\n          overflow-y: visible;\n        }\n      }\n    }\n  }\n}\n// scss-docs-end navbar-expand-loop\n\n// Navbar themes\n//\n// Styles for switching between navbars with light or dark background.\n\n// Dark links against a light background\n.navbar-light {\n  .navbar-brand {\n    color: $navbar-light-brand-color;\n\n    &:hover,\n    &:focus {\n      color: $navbar-light-brand-hover-color;\n    }\n  }\n\n  .navbar-nav {\n    .nav-link {\n      color: $navbar-light-color;\n\n      &:hover,\n      &:focus {\n        color: $navbar-light-hover-color;\n      }\n\n      &.disabled {\n        color: $navbar-light-disabled-color;\n      }\n    }\n\n    .show > .nav-link,\n    .nav-link.active {\n      color: $navbar-light-active-color;\n    }\n  }\n\n  .navbar-toggler {\n    color: $navbar-light-color;\n    border-color: $navbar-light-toggler-border-color;\n  }\n\n  .navbar-toggler-icon {\n    background-image: escape-svg($navbar-light-toggler-icon-bg);\n  }\n\n  .navbar-text {\n    color: $navbar-light-color;\n\n    a,\n    a:hover,\n    a:focus  {\n      color: $navbar-light-active-color;\n    }\n  }\n}\n\n// White links against a dark background\n.navbar-dark {\n  .navbar-brand {\n    color: $navbar-dark-brand-color;\n\n    &:hover,\n    &:focus {\n      color: $navbar-dark-brand-hover-color;\n    }\n  }\n\n  .navbar-nav {\n    .nav-link {\n      color: $navbar-dark-color;\n\n      &:hover,\n      &:focus {\n        color: $navbar-dark-hover-color;\n      }\n\n      &.disabled {\n        color: $navbar-dark-disabled-color;\n      }\n    }\n\n    .show > .nav-link,\n    .nav-link.active {\n      color: $navbar-dark-active-color;\n    }\n  }\n\n  .navbar-toggler {\n    color: $navbar-dark-color;\n    border-color: $navbar-dark-toggler-border-color;\n  }\n\n  .navbar-toggler-icon {\n    background-image: escape-svg($navbar-dark-toggler-icon-bg);\n  }\n\n  .navbar-text {\n    color: $navbar-dark-color;\n    a,\n    a:hover,\n    a:focus {\n      color: $navbar-dark-active-color;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_offcanvas.scss",
    "content": ".offcanvas {\n  position: fixed;\n  bottom: 0;\n  z-index: $zindex-offcanvas;\n  display: flex;\n  flex-direction: column;\n  max-width: 100%;\n  color: $offcanvas-color;\n  visibility: hidden;\n  background-color: $offcanvas-bg-color;\n  background-clip: padding-box;\n  outline: 0;\n  @include box-shadow($offcanvas-box-shadow);\n  @include transition(transform $offcanvas-transition-duration ease-in-out);\n}\n\n.offcanvas-backdrop {\n  @include overlay-backdrop($zindex-offcanvas-backdrop, $offcanvas-backdrop-bg, $offcanvas-backdrop-opacity);\n}\n\n.offcanvas-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: $offcanvas-padding-y $offcanvas-padding-x;\n\n  .btn-close {\n    padding: ($offcanvas-padding-y * .5) ($offcanvas-padding-x * .5);\n    margin-top: $offcanvas-padding-y * -.5;\n    margin-right: $offcanvas-padding-x * -.5;\n    margin-bottom: $offcanvas-padding-y * -.5;\n  }\n}\n\n.offcanvas-title {\n  margin-bottom: 0;\n  line-height: $offcanvas-title-line-height;\n}\n\n.offcanvas-body {\n  flex-grow: 1;\n  padding: $offcanvas-padding-y $offcanvas-padding-x;\n  overflow-y: auto;\n}\n\n.offcanvas-start {\n  top: 0;\n  left: 0;\n  width: $offcanvas-horizontal-width;\n  border-right: $offcanvas-border-width solid $offcanvas-border-color;\n  transform: translateX(-100%);\n}\n\n.offcanvas-end {\n  top: 0;\n  right: 0;\n  width: $offcanvas-horizontal-width;\n  border-left: $offcanvas-border-width solid $offcanvas-border-color;\n  transform: translateX(100%);\n}\n\n.offcanvas-top {\n  top: 0;\n  right: 0;\n  left: 0;\n  height: $offcanvas-vertical-height;\n  max-height: 100%;\n  border-bottom: $offcanvas-border-width solid $offcanvas-border-color;\n  transform: translateY(-100%);\n}\n\n.offcanvas-bottom {\n  right: 0;\n  left: 0;\n  height: $offcanvas-vertical-height;\n  max-height: 100%;\n  border-top: $offcanvas-border-width solid $offcanvas-border-color;\n  transform: translateY(100%);\n}\n\n.offcanvas.show {\n  transform: none;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_pagination.scss",
    "content": ".pagination {\n  display: flex;\n  @include list-unstyled();\n}\n\n.page-link {\n  position: relative;\n  display: block;\n  color: $pagination-color;\n  text-decoration: if($link-decoration == none, null, none);\n  background-color: $pagination-bg;\n  border: $pagination-border-width solid $pagination-border-color;\n  @include transition($pagination-transition);\n\n  &:hover {\n    z-index: 2;\n    color: $pagination-hover-color;\n    text-decoration: if($link-hover-decoration == underline, none, null);\n    background-color: $pagination-hover-bg;\n    border-color: $pagination-hover-border-color;\n  }\n\n  &:focus {\n    z-index: 3;\n    color: $pagination-focus-color;\n    background-color: $pagination-focus-bg;\n    outline: $pagination-focus-outline;\n    box-shadow: $pagination-focus-box-shadow;\n  }\n}\n\n.page-item {\n  &:not(:first-child) .page-link {\n    margin-left: $pagination-margin-start;\n  }\n\n  &.active .page-link {\n    z-index: 3;\n    color: $pagination-active-color;\n    @include gradient-bg($pagination-active-bg);\n    border-color: $pagination-active-border-color;\n  }\n\n  &.disabled .page-link {\n    color: $pagination-disabled-color;\n    pointer-events: none;\n    background-color: $pagination-disabled-bg;\n    border-color: $pagination-disabled-border-color;\n  }\n}\n\n\n//\n// Sizing\n//\n@include pagination-size($pagination-padding-y, $pagination-padding-x, null, $pagination-border-radius);\n\n.pagination-lg {\n  @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $pagination-border-radius-lg);\n}\n\n.pagination-sm {\n  @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $pagination-border-radius-sm);\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_placeholders.scss",
    "content": ".placeholder {\n  display: inline-block;\n  min-height: 1em;\n  vertical-align: middle;\n  cursor: wait;\n  background-color: currentColor;\n  opacity: $placeholder-opacity-max;\n\n  &.btn::before {\n    display: inline-block;\n    content: \"\";\n  }\n}\n\n// Sizing\n.placeholder-xs {\n  min-height: .6em;\n}\n\n.placeholder-sm {\n  min-height: .8em;\n}\n\n.placeholder-lg {\n  min-height: 1.2em;\n}\n\n// Animation\n.placeholder-glow {\n  .placeholder {\n    animation: placeholder-glow 2s ease-in-out infinite;\n  }\n}\n\n@keyframes placeholder-glow {\n  50% {\n    opacity: $placeholder-opacity-min;\n  }\n}\n\n.placeholder-wave {\n  mask-image: linear-gradient(130deg, $black 55%, rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, $black 95%);\n  mask-size: 200% 100%;\n  animation: placeholder-wave 2s linear infinite;\n}\n\n@keyframes placeholder-wave {\n  100% {\n    mask-position: -200% 0%;\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_popover.scss",
    "content": ".popover {\n  position: absolute;\n  top: 0;\n  left: 0 #{\"/* rtl:ignore */\"};\n  z-index: $zindex-popover;\n  display: block;\n  max-width: $popover-max-width;\n  // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n  // So reset our font and text properties to avoid inheriting weird values.\n  @include reset-text();\n  @include font-size($popover-font-size);\n  // Allow breaking very long words so they don't overflow the popover's bounds\n  word-wrap: break-word;\n  background-color: $popover-bg;\n  background-clip: padding-box;\n  border: $popover-border-width solid $popover-border-color;\n  @include border-radius($popover-border-radius);\n  @include box-shadow($popover-box-shadow);\n\n  .popover-arrow {\n    position: absolute;\n    display: block;\n    width: $popover-arrow-width;\n    height: $popover-arrow-height;\n\n    &::before,\n    &::after {\n      position: absolute;\n      display: block;\n      content: \"\";\n      border-color: transparent;\n      border-style: solid;\n    }\n  }\n}\n\n.bs-popover-top {\n  > .popover-arrow {\n    bottom: subtract(-$popover-arrow-height, $popover-border-width);\n\n    &::before {\n      bottom: 0;\n      border-width: $popover-arrow-height ($popover-arrow-width * .5) 0;\n      border-top-color: $popover-arrow-outer-color;\n    }\n\n    &::after {\n      bottom: $popover-border-width;\n      border-width: $popover-arrow-height ($popover-arrow-width * .5) 0;\n      border-top-color: $popover-arrow-color;\n    }\n  }\n}\n\n.bs-popover-end {\n  > .popover-arrow {\n    left: subtract(-$popover-arrow-height, $popover-border-width);\n    width: $popover-arrow-height;\n    height: $popover-arrow-width;\n\n    &::before {\n      left: 0;\n      border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0;\n      border-right-color: $popover-arrow-outer-color;\n    }\n\n    &::after {\n      left: $popover-border-width;\n      border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0;\n      border-right-color: $popover-arrow-color;\n    }\n  }\n}\n\n.bs-popover-bottom {\n  > .popover-arrow {\n    top: subtract(-$popover-arrow-height, $popover-border-width);\n\n    &::before {\n      top: 0;\n      border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5);\n      border-bottom-color: $popover-arrow-outer-color;\n    }\n\n    &::after {\n      top: $popover-border-width;\n      border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5);\n      border-bottom-color: $popover-arrow-color;\n    }\n  }\n\n  // This will remove the popover-header's border just below the arrow\n  .popover-header::before {\n    position: absolute;\n    top: 0;\n    left: 50%;\n    display: block;\n    width: $popover-arrow-width;\n    margin-left: -$popover-arrow-width * .5;\n    content: \"\";\n    border-bottom: $popover-border-width solid $popover-header-bg;\n  }\n}\n\n.bs-popover-start {\n  > .popover-arrow {\n    right: subtract(-$popover-arrow-height, $popover-border-width);\n    width: $popover-arrow-height;\n    height: $popover-arrow-width;\n\n    &::before {\n      right: 0;\n      border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height;\n      border-left-color: $popover-arrow-outer-color;\n    }\n\n    &::after {\n      right: $popover-border-width;\n      border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height;\n      border-left-color: $popover-arrow-color;\n    }\n  }\n}\n\n.bs-popover-auto {\n  &[data-popper-placement^=\"top\"] {\n    @extend .bs-popover-top;\n  }\n  &[data-popper-placement^=\"right\"] {\n    @extend .bs-popover-end;\n  }\n  &[data-popper-placement^=\"bottom\"] {\n    @extend .bs-popover-bottom;\n  }\n  &[data-popper-placement^=\"left\"] {\n    @extend .bs-popover-start;\n  }\n}\n\n// Offset the popover to account for the popover arrow\n.popover-header {\n  padding: $popover-header-padding-y $popover-header-padding-x;\n  margin-bottom: 0; // Reset the default from Reboot\n  @include font-size($font-size-base);\n  color: $popover-header-color;\n  background-color: $popover-header-bg;\n  border-bottom: $popover-border-width solid $popover-border-color;\n  @include border-top-radius($popover-inner-border-radius);\n\n  &:empty {\n    display: none;\n  }\n}\n\n.popover-body {\n  padding: $popover-body-padding-y $popover-body-padding-x;\n  color: $popover-body-color;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_progress.scss",
    "content": "// Disable animation if transitions are disabled\n\n// scss-docs-start progress-keyframes\n@if $enable-transitions {\n  @keyframes progress-bar-stripes {\n    0% { background-position-x: $progress-height; }\n  }\n}\n// scss-docs-end progress-keyframes\n\n.progress {\n  display: flex;\n  height: $progress-height;\n  overflow: hidden; // force rounded corners by cropping it\n  @include font-size($progress-font-size);\n  background-color: $progress-bg;\n  @include border-radius($progress-border-radius);\n  @include box-shadow($progress-box-shadow);\n}\n\n.progress-bar {\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  overflow: hidden;\n  color: $progress-bar-color;\n  text-align: center;\n  white-space: nowrap;\n  background-color: $progress-bar-bg;\n  @include transition($progress-bar-transition);\n}\n\n.progress-bar-striped {\n  @include gradient-striped();\n  background-size: $progress-height $progress-height;\n}\n\n@if $enable-transitions {\n  .progress-bar-animated {\n    animation: $progress-bar-animation-timing progress-bar-stripes;\n\n    @if $enable-reduced-motion {\n      @media (prefers-reduced-motion: reduce) {\n        animation: none;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_reboot.scss",
    "content": "// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n\n// Root\n//\n// Ability to the value of the root font sizes, affecting the value of `rem`.\n// null by default, thus nothing is generated.\n\n:root {\n  @if $font-size-root != null {\n    font-size: var(--#{$variable-prefix}root-font-size);\n  }\n\n  @if $enable-smooth-scroll {\n    @media (prefers-reduced-motion: no-preference) {\n      scroll-behavior: smooth;\n    }\n  }\n}\n\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Prevent adjustments of font size after orientation changes in iOS.\n// 4. Change the default tap highlight to be completely transparent in iOS.\n\n// scss-docs-start reboot-body-rules\nbody {\n  margin: 0; // 1\n  font-family: var(--#{$variable-prefix}body-font-family);\n  @include font-size(var(--#{$variable-prefix}body-font-size));\n  font-weight: var(--#{$variable-prefix}body-font-weight);\n  line-height: var(--#{$variable-prefix}body-line-height);\n  color: var(--#{$variable-prefix}body-color);\n  text-align: var(--#{$variable-prefix}body-text-align);\n  background-color: var(--#{$variable-prefix}body-bg); // 2\n  -webkit-text-size-adjust: 100%; // 3\n  -webkit-tap-highlight-color: rgba($black, 0); // 4\n}\n// scss-docs-end reboot-body-rules\n\n\n// Content grouping\n//\n// 1. Reset Firefox's gray color\n// 2. Set correct height and prevent the `size` attribute to make the `hr` look like an input field\n\nhr {\n  margin: $hr-margin-y 0;\n  color: $hr-color; // 1\n  background-color: currentColor;\n  border: 0;\n  opacity: $hr-opacity;\n}\n\nhr:not([size]) {\n  height: $hr-height; // 2\n}\n\n\n// Typography\n//\n// 1. Remove top margins from headings\n//    By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n//    margin for easier control within type scales as it avoids margin collapsing.\n\n%heading {\n  margin-top: 0; // 1\n  margin-bottom: $headings-margin-bottom;\n  font-family: $headings-font-family;\n  font-style: $headings-font-style;\n  font-weight: $headings-font-weight;\n  line-height: $headings-line-height;\n  color: $headings-color;\n}\n\nh1 {\n  @extend %heading;\n  @include font-size($h1-font-size);\n}\n\nh2 {\n  @extend %heading;\n  @include font-size($h2-font-size);\n}\n\nh3 {\n  @extend %heading;\n  @include font-size($h3-font-size);\n}\n\nh4 {\n  @extend %heading;\n  @include font-size($h4-font-size);\n}\n\nh5 {\n  @extend %heading;\n  @include font-size($h5-font-size);\n}\n\nh6 {\n  @extend %heading;\n  @include font-size($h6-font-size);\n}\n\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\n\np {\n  margin-top: 0;\n  margin-bottom: $paragraph-margin-bottom;\n}\n\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-bs-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-bs-original-title] { // 1\n  text-decoration: underline dotted; // 2\n  cursor: help; // 3\n  text-decoration-skip-ink: none; // 4\n}\n\n\n// Address\n\naddress {\n  margin-bottom: 1rem;\n  font-style: normal;\n  line-height: inherit;\n}\n\n\n// Lists\n\nol,\nul {\n  padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n  margin-bottom: 0;\n}\n\ndt {\n  font-weight: $dt-font-weight;\n}\n\n// 1. Undo browser default\n\ndd {\n  margin-bottom: .5rem;\n  margin-left: 0; // 1\n}\n\n\n// Blockquote\n\nblockquote {\n  margin: 0 0 1rem;\n}\n\n\n// Strong\n//\n// Add the correct font weight in Chrome, Edge, and Safari\n\nb,\nstrong {\n  font-weight: $font-weight-bolder;\n}\n\n\n// Small\n//\n// Add the correct font size in all browsers\n\nsmall {\n  @include font-size($small-font-size);\n}\n\n\n// Mark\n\nmark {\n  padding: $mark-padding;\n  background-color: $mark-bg;\n}\n\n\n// Sub and Sup\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n\nsub,\nsup {\n  position: relative;\n  @include font-size($sub-sup-font-size);\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n// Links\n\na {\n  color: $link-color;\n  text-decoration: $link-decoration;\n\n  &:hover {\n    color: $link-hover-color;\n    text-decoration: $link-hover-decoration;\n  }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n  &,\n  &:hover {\n    color: inherit;\n    text-decoration: none;\n  }\n}\n\n\n// Code\n\npre,\ncode,\nkbd,\nsamp {\n  font-family: $font-family-code;\n  @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n  direction: ltr #{\"/* rtl:ignore */\"};\n  unicode-bidi: bidi-override;\n}\n\n// 1. Remove browser default top margin\n// 2. Reset browser default of `1em` to use `rem`s\n// 3. Don't allow content to break outside\n\npre {\n  display: block;\n  margin-top: 0; // 1\n  margin-bottom: 1rem; // 2\n  overflow: auto; // 3\n  @include font-size($code-font-size);\n  color: $pre-color;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    @include font-size(inherit);\n    color: inherit;\n    word-break: normal;\n  }\n}\n\ncode {\n  @include font-size($code-font-size);\n  color: $code-color;\n  word-wrap: break-word;\n\n  // Streamline the style when inside anchors to avoid broken underline and more\n  a > & {\n    color: inherit;\n  }\n}\n\nkbd {\n  padding: $kbd-padding-y $kbd-padding-x;\n  @include font-size($kbd-font-size);\n  color: $kbd-color;\n  background-color: $kbd-bg;\n  @include border-radius($border-radius-sm);\n\n  kbd {\n    padding: 0;\n    @include font-size(1em);\n    font-weight: $nested-kbd-font-weight;\n  }\n}\n\n\n// Figures\n//\n// Apply a consistent margin strategy (matches our type styles).\n\nfigure {\n  margin: 0 0 1rem;\n}\n\n\n// Images and content\n\nimg,\nsvg {\n  vertical-align: middle;\n}\n\n\n// Tables\n//\n// Prevent double borders\n\ntable {\n  caption-side: bottom;\n  border-collapse: collapse;\n}\n\ncaption {\n  padding-top: $table-cell-padding-y;\n  padding-bottom: $table-cell-padding-y;\n  color: $table-caption-color;\n  text-align: left;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `<td>` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n  font-weight: $table-th-font-weight; // 1\n  text-align: inherit; // 2\n  text-align: -webkit-match-parent; // 3\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n}\n\n\n// Forms\n//\n// 1. Allow labels to use `margin` for spacing.\n\nlabel {\n  display: inline-block; // 1\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n// See https://github.com/twbs/bootstrap/issues/24093\n\nbutton {\n  // stylelint-disable-next-line property-disallowed-list\n  border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n  outline: 0;\n}\n\n// 1. Remove the margin in Firefox and Safari\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n  margin: 0; // 1\n  font-family: inherit;\n  @include font-size(inherit);\n  line-height: inherit;\n}\n\n// Remove the inheritance of text transform in Firefox\nbutton,\nselect {\n  text-transform: none;\n}\n// Set the cursor for non-`<button>` buttons\n//\n// Details at https://github.com/twbs/bootstrap/pull/30562\n[role=\"button\"] {\n  cursor: pointer;\n}\n\nselect {\n  // Remove the inheritance of word-wrap in Safari.\n  // See https://github.com/twbs/bootstrap/issues/24990\n  word-wrap: normal;\n\n  // Undo the opacity change from Chrome\n  &:disabled {\n    opacity: 1;\n  }\n}\n\n// Remove the dropdown arrow in Chrome from inputs built with datalists.\n// See https://stackoverflow.com/a/54997118\n\n[list]::-webkit-calendar-picker-indicator {\n  display: none;\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n//    controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\n// 3. Opinionated: add \"hand\" cursor to non-disabled button elements.\n\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n  -webkit-appearance: button; // 2\n\n  @if $enable-button-pointers {\n    &:not(:disabled) {\n      cursor: pointer; // 3\n    }\n  }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\n\n::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\n// 1. Textareas should really only resize vertically so they don't break their (horizontal) containers.\n\ntextarea {\n  resize: vertical; // 1\n}\n\n// 1. Browsers set a default `min-width: min-content;` on fieldsets,\n//    unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n//    So we reset that to ensure fieldsets behave more like a standard block element.\n//    See https://github.com/twbs/bootstrap/issues/12359\n//    and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n// 2. Reset the default outline behavior of fieldsets so they don't affect page layout.\n\nfieldset {\n  min-width: 0; // 1\n  padding: 0; // 2\n  margin: 0; // 2\n  border: 0; // 2\n}\n\n// 1. By using `float: left`, the legend will behave like a block element.\n//    This way the border of a fieldset wraps around the legend if present.\n// 2. Fix wrapping bug.\n//    See https://github.com/twbs/bootstrap/issues/29712\n\nlegend {\n  float: left; // 1\n  width: 100%;\n  padding: 0;\n  margin-bottom: $legend-margin-bottom;\n  @include font-size($legend-font-size);\n  font-weight: $legend-font-weight;\n  line-height: inherit;\n\n  + * {\n    clear: left; // 2\n  }\n}\n\n// Fix height of inputs with a type of datetime-local, date, month, week, or time\n// See https://github.com/twbs/bootstrap/issues/18842\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n  padding: 0;\n}\n\n::-webkit-inner-spin-button {\n  height: auto;\n}\n\n// 1. Correct the outline style in Safari.\n// 2. This overrides the extra rounded corners on search inputs in iOS so that our\n//    `.form-control` class can properly style them. Note that this cannot simply\n//    be added to `.form-control` as it's not specific enough. For details, see\n//    https://github.com/twbs/bootstrap/issues/11586.\n\n[type=\"search\"] {\n  outline-offset: -2px; // 1\n  -webkit-appearance: textfield; // 2\n}\n\n// 1. A few input types should stay LTR\n// See https://rtlstyling.com/posts/rtl-styling#form-inputs\n// 2. RTL only output\n// See https://rtlcss.com/learn/usage-guide/control-directives/#raw\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n  direction: ltr;\n}\n*/\n\n// Remove the inner padding in Chrome and Safari on macOS.\n\n::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n// Remove padding around color pickers in webkit browsers\n\n::-webkit-color-swatch-wrapper {\n  padding: 0;\n}\n\n\n// Inherit font family and line height for file input buttons\n\n::file-selector-button {\n  font: inherit;\n}\n\n// 1. Change font properties to `inherit`\n// 2. Correct the inability to style clickable types in iOS and Safari.\n\n::-webkit-file-upload-button {\n  font: inherit; // 1\n  -webkit-appearance: button; // 2\n}\n\n// Correct element displays\n\noutput {\n  display: inline-block;\n}\n\n// Remove border from iframe\n\niframe {\n  border: 0;\n}\n\n// Summary\n//\n// 1. Add the correct display in all browsers\n\nsummary {\n  display: list-item; // 1\n  cursor: pointer;\n}\n\n\n// Progress\n//\n// Add the correct vertical alignment in Chrome, Firefox, and Opera.\n\nprogress {\n  vertical-align: baseline;\n}\n\n\n// Hidden attribute\n//\n// Always hide an element with the `hidden` HTML attribute.\n\n[hidden] {\n  display: none !important;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_root.scss",
    "content": ":root {\n  // Note: Custom variable values only support SassScript inside `#{}`.\n\n  // Colors\n  //\n  // Generate palettes for full colors, grays, and theme colors.\n\n  @each $color, $value in $colors {\n    --#{$variable-prefix}#{$color}: #{$value};\n  }\n\n  @each $color, $value in $grays {\n    --#{$variable-prefix}gray-#{$color}: #{$value};\n  }\n\n  @each $color, $value in $theme-colors {\n    --#{$variable-prefix}#{$color}: #{$value};\n  }\n\n  @each $color, $value in $theme-colors-rgb {\n    --#{$variable-prefix}#{$color}-rgb: #{$value};\n  }\n\n  --#{$variable-prefix}white-rgb: #{to-rgb($white)};\n  --#{$variable-prefix}black-rgb: #{to-rgb($black)};\n  --#{$variable-prefix}body-color-rgb: #{to-rgb($body-color)};\n  --#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg)};\n\n  // Fonts\n\n  // Note: Use `inspect` for lists so that quoted items keep the quotes.\n  // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n  --#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)};\n  --#{$variable-prefix}font-monospace: #{inspect($font-family-monospace)};\n  --#{$variable-prefix}gradient: #{$gradient};\n\n  // Root and body\n  // stylelint-disable custom-property-empty-line-before\n  // scss-docs-start root-body-variables\n  @if $font-size-root != null {\n    --#{$variable-prefix}root-font-size: #{$font-size-root};\n  }\n  --#{$variable-prefix}body-font-family: #{$font-family-base};\n  --#{$variable-prefix}body-font-size: #{$font-size-base};\n  --#{$variable-prefix}body-font-weight: #{$font-weight-base};\n  --#{$variable-prefix}body-line-height: #{$line-height-base};\n  --#{$variable-prefix}body-color: #{$body-color};\n  @if $body-text-align != null {\n    --#{$variable-prefix}body-text-align: #{$body-text-align};\n  }\n  --#{$variable-prefix}body-bg: #{$body-bg};\n  // scss-docs-end root-body-variables\n  // stylelint-enable custom-property-empty-line-before\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_spinners.scss",
    "content": "//\n// Rotating border\n//\n\n// scss-docs-start spinner-border-keyframes\n@keyframes spinner-border {\n  to { transform: rotate(360deg) #{\"/* rtl:ignore */\"}; }\n}\n// scss-docs-end spinner-border-keyframes\n\n.spinner-border {\n  display: inline-block;\n  width: $spinner-width;\n  height: $spinner-height;\n  vertical-align: $spinner-vertical-align;\n  border: $spinner-border-width solid currentColor;\n  border-right-color: transparent;\n  // stylelint-disable-next-line property-disallowed-list\n  border-radius: 50%;\n  animation: $spinner-animation-speed linear infinite spinner-border;\n}\n\n.spinner-border-sm {\n  width: $spinner-width-sm;\n  height: $spinner-height-sm;\n  border-width: $spinner-border-width-sm;\n}\n\n//\n// Growing circle\n//\n\n// scss-docs-start spinner-grow-keyframes\n@keyframes spinner-grow {\n  0% {\n    transform: scale(0);\n  }\n  50% {\n    opacity: 1;\n    transform: none;\n  }\n}\n// scss-docs-end spinner-grow-keyframes\n\n.spinner-grow {\n  display: inline-block;\n  width: $spinner-width;\n  height: $spinner-height;\n  vertical-align: $spinner-vertical-align;\n  background-color: currentColor;\n  // stylelint-disable-next-line property-disallowed-list\n  border-radius: 50%;\n  opacity: 0;\n  animation: $spinner-animation-speed linear infinite spinner-grow;\n}\n\n.spinner-grow-sm {\n  width: $spinner-width-sm;\n  height: $spinner-height-sm;\n}\n\n@if $enable-reduced-motion {\n  @media (prefers-reduced-motion: reduce) {\n    .spinner-border,\n    .spinner-grow {\n      animation-duration: $spinner-animation-speed * 2;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_tables.scss",
    "content": "//\n// Basic Bootstrap table\n//\n\n.table {\n  --#{$variable-prefix}table-bg: #{$table-bg};\n  --#{$variable-prefix}table-accent-bg: #{$table-accent-bg};\n  --#{$variable-prefix}table-striped-color: #{$table-striped-color};\n  --#{$variable-prefix}table-striped-bg: #{$table-striped-bg};\n  --#{$variable-prefix}table-active-color: #{$table-active-color};\n  --#{$variable-prefix}table-active-bg: #{$table-active-bg};\n  --#{$variable-prefix}table-hover-color: #{$table-hover-color};\n  --#{$variable-prefix}table-hover-bg: #{$table-hover-bg};\n\n  width: 100%;\n  margin-bottom: $spacer;\n  color: $table-color;\n  vertical-align: $table-cell-vertical-align;\n  border-color: $table-border-color;\n\n  // Target th & td\n  // We need the child combinator to prevent styles leaking to nested tables which doesn't have a `.table` class.\n  // We use the universal selectors here to simplify the selector (else we would need 6 different selectors).\n  // Another advantage is that this generates less code and makes the selector less specific making it easier to override.\n  // stylelint-disable-next-line selector-max-universal\n  > :not(caption) > * > * {\n    padding: $table-cell-padding-y $table-cell-padding-x;\n    background-color: var(--#{$variable-prefix}table-bg);\n    border-bottom-width: $table-border-width;\n    box-shadow: inset 0 0 0 9999px var(--#{$variable-prefix}table-accent-bg);\n  }\n\n  > tbody {\n    vertical-align: inherit;\n  }\n\n  > thead {\n    vertical-align: bottom;\n  }\n\n  // Highlight border color between thead, tbody and tfoot.\n  > :not(:first-child) {\n    border-top: (2 * $table-border-width) solid $table-group-separator-color;\n  }\n}\n\n\n//\n// Change placement of captions with a class\n//\n\n.caption-top {\n  caption-side: top;\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n  // stylelint-disable-next-line selector-max-universal\n  > :not(caption) > * > * {\n    padding: $table-cell-padding-y-sm $table-cell-padding-x-sm;\n  }\n}\n\n\n// Border versions\n//\n// Add or remove borders all around the table and between all the columns.\n//\n// When borders are added on all sides of the cells, the corners can render odd when\n// these borders do not have the same color or if they are semi-transparent.\n// Therefor we add top and border bottoms to the `tr`s and left and right borders\n// to the `td`s or `th`s\n\n.table-bordered {\n  > :not(caption) > * {\n    border-width: $table-border-width 0;\n\n    // stylelint-disable-next-line selector-max-universal\n    > * {\n      border-width: 0 $table-border-width;\n    }\n  }\n}\n\n.table-borderless {\n  // stylelint-disable-next-line selector-max-universal\n  > :not(caption) > * > * {\n    border-bottom-width: 0;\n  }\n\n  > :not(:first-child) {\n    border-top-width: 0;\n  }\n}\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n  > tbody > tr:nth-of-type(#{$table-striped-order}) > * {\n    --#{$variable-prefix}table-accent-bg: var(--#{$variable-prefix}table-striped-bg);\n    color: var(--#{$variable-prefix}table-striped-color);\n  }\n}\n\n// Active table\n//\n// The `.table-active` class can be added to highlight rows or cells\n\n.table-active {\n  --#{$variable-prefix}table-accent-bg: var(--#{$variable-prefix}table-active-bg);\n  color: var(--#{$variable-prefix}table-active-color);\n}\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover > * {\n    --#{$variable-prefix}table-accent-bg: var(--#{$variable-prefix}table-hover-bg);\n    color: var(--#{$variable-prefix}table-hover-color);\n  }\n}\n\n\n// Table variants\n//\n// Table variants set the table cell backgrounds, border colors\n// and the colors of the striped, hovered & active tables\n\n@each $color, $value in $table-variants {\n  @include table-variant($color, $value);\n}\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n  $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n  @include media-breakpoint-down($breakpoint) {\n    .table-responsive#{$infix} {\n      overflow-x: auto;\n      -webkit-overflow-scrolling: touch;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_toasts.scss",
    "content": ".toast {\n  width: $toast-max-width;\n  max-width: 100%;\n  @include font-size($toast-font-size);\n  color: $toast-color;\n  pointer-events: auto;\n  background-color: $toast-background-color;\n  background-clip: padding-box;\n  border: $toast-border-width solid $toast-border-color;\n  box-shadow: $toast-box-shadow;\n  @include border-radius($toast-border-radius);\n\n  &.showing {\n    opacity: 0;\n  }\n\n  &:not(.show) {\n    display: none;\n  }\n}\n\n.toast-container {\n  width: max-content;\n  max-width: 100%;\n  pointer-events: none;\n\n  > :not(:last-child) {\n    margin-bottom: $toast-spacing;\n  }\n}\n\n.toast-header {\n  display: flex;\n  align-items: center;\n  padding: $toast-padding-y $toast-padding-x;\n  color: $toast-header-color;\n  background-color: $toast-header-background-color;\n  background-clip: padding-box;\n  border-bottom: $toast-border-width solid $toast-header-border-color;\n  @include border-top-radius(subtract($toast-border-radius, $toast-border-width));\n\n  .btn-close {\n    margin-right: $toast-padding-x * -.5;\n    margin-left: $toast-padding-x;\n  }\n}\n\n.toast-body {\n  padding: $toast-padding-x; // apply to both vertical and horizontal\n  word-wrap: break-word;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_tooltip.scss",
    "content": "// Base class\n.tooltip {\n  position: absolute;\n  z-index: $zindex-tooltip;\n  display: block;\n  margin: $tooltip-margin;\n  // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n  // So reset our font and text properties to avoid inheriting weird values.\n  @include reset-text();\n  @include font-size($tooltip-font-size);\n  // Allow breaking very long words so they don't overflow the tooltip's bounds\n  word-wrap: break-word;\n  opacity: 0;\n\n  &.show { opacity: $tooltip-opacity; }\n\n  .tooltip-arrow {\n    position: absolute;\n    display: block;\n    width: $tooltip-arrow-width;\n    height: $tooltip-arrow-height;\n\n    &::before {\n      position: absolute;\n      content: \"\";\n      border-color: transparent;\n      border-style: solid;\n    }\n  }\n}\n\n.bs-tooltip-top {\n  padding: $tooltip-arrow-height 0;\n\n  .tooltip-arrow {\n    bottom: 0;\n\n    &::before {\n      top: -1px;\n      border-width: $tooltip-arrow-height ($tooltip-arrow-width * .5) 0;\n      border-top-color: $tooltip-arrow-color;\n    }\n  }\n}\n\n.bs-tooltip-end {\n  padding: 0 $tooltip-arrow-height;\n\n  .tooltip-arrow {\n    left: 0;\n    width: $tooltip-arrow-height;\n    height: $tooltip-arrow-width;\n\n    &::before {\n      right: -1px;\n      border-width: ($tooltip-arrow-width * .5) $tooltip-arrow-height ($tooltip-arrow-width * .5) 0;\n      border-right-color: $tooltip-arrow-color;\n    }\n  }\n}\n\n.bs-tooltip-bottom {\n  padding: $tooltip-arrow-height 0;\n\n  .tooltip-arrow {\n    top: 0;\n\n    &::before {\n      bottom: -1px;\n      border-width: 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height;\n      border-bottom-color: $tooltip-arrow-color;\n    }\n  }\n}\n\n.bs-tooltip-start {\n  padding: 0 $tooltip-arrow-height;\n\n  .tooltip-arrow {\n    right: 0;\n    width: $tooltip-arrow-height;\n    height: $tooltip-arrow-width;\n\n    &::before {\n      left: -1px;\n      border-width: ($tooltip-arrow-width * .5) 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height;\n      border-left-color: $tooltip-arrow-color;\n    }\n  }\n}\n\n.bs-tooltip-auto {\n  &[data-popper-placement^=\"top\"] {\n    @extend .bs-tooltip-top;\n  }\n  &[data-popper-placement^=\"right\"] {\n    @extend .bs-tooltip-end;\n  }\n  &[data-popper-placement^=\"bottom\"] {\n    @extend .bs-tooltip-bottom;\n  }\n  &[data-popper-placement^=\"left\"] {\n    @extend .bs-tooltip-start;\n  }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n  max-width: $tooltip-max-width;\n  padding: $tooltip-padding-y $tooltip-padding-x;\n  color: $tooltip-color;\n  text-align: center;\n  background-color: $tooltip-bg;\n  @include border-radius($tooltip-border-radius);\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_transitions.scss",
    "content": ".fade {\n  @include transition($transition-fade);\n\n  &:not(.show) {\n    opacity: 0;\n  }\n}\n\n// scss-docs-start collapse-classes\n.collapse {\n  &:not(.show) {\n    display: none;\n  }\n}\n\n.collapsing {\n  height: 0;\n  overflow: hidden;\n  @include transition($transition-collapse);\n\n  &.collapse-horizontal {\n    width: 0;\n    height: auto;\n    @include transition($transition-collapse-width);\n  }\n}\n// scss-docs-end collapse-classes\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_type.scss",
    "content": "//\n// Headings\n//\n.h1 {\n  @extend h1;\n}\n\n.h2 {\n  @extend h2;\n}\n\n.h3 {\n  @extend h3;\n}\n\n.h4 {\n  @extend h4;\n}\n\n.h5 {\n  @extend h5;\n}\n\n.h6 {\n  @extend h6;\n}\n\n\n.lead {\n  @include font-size($lead-font-size);\n  font-weight: $lead-font-weight;\n}\n\n// Type display classes\n@each $display, $font-size in $display-font-sizes {\n  .display-#{$display} {\n    @include font-size($font-size);\n    font-weight: $display-font-weight;\n    line-height: $display-line-height;\n  }\n}\n\n//\n// Emphasis\n//\n.small {\n  @extend small;\n}\n\n.mark {\n  @extend mark;\n}\n\n//\n// Lists\n//\n\n.list-unstyled {\n  @include list-unstyled();\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  @include list-unstyled();\n}\n.list-inline-item {\n  display: inline-block;\n\n  &:not(:last-child) {\n    margin-right: $list-inline-padding;\n  }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n  @include font-size($initialism-font-size);\n  text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n  margin-bottom: $blockquote-margin-y;\n  @include font-size($blockquote-font-size);\n\n  > :last-child {\n    margin-bottom: 0;\n  }\n}\n\n.blockquote-footer {\n  margin-top: -$blockquote-margin-y;\n  margin-bottom: $blockquote-margin-y;\n  @include font-size($blockquote-footer-font-size);\n  color: $blockquote-footer-color;\n\n  &::before {\n    content: \"\\2014\\00A0\"; // em dash, nbsp\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_utilities.scss",
    "content": "// stylelint-disable indentation\n\n// Utilities\n\n$utilities: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$utilities: map-merge(\n  (\n    // scss-docs-start utils-vertical-align\n    \"align\": (\n      property: vertical-align,\n      class: align,\n      values: baseline top middle bottom text-bottom text-top\n    ),\n    // scss-docs-end utils-vertical-align\n    // scss-docs-start utils-float\n    \"float\": (\n      responsive: true,\n      property: float,\n      values: (\n        start: left,\n        end: right,\n        none: none,\n      )\n    ),\n    // scss-docs-end utils-float\n    // Opacity utilities\n    // scss-docs-start utils-opacity\n    \"opacity\": (\n      property: opacity,\n      values: (\n        0: 0,\n        25: .25,\n        50: .5,\n        75: .75,\n        100: 1,\n      )\n    ),\n    // scss-docs-end utils-opacity\n    // scss-docs-start utils-overflow\n    \"overflow\": (\n      property: overflow,\n      values: auto hidden visible scroll,\n    ),\n    // scss-docs-end utils-overflow\n    // scss-docs-start utils-display\n    \"display\": (\n      responsive: true,\n      print: true,\n      property: display,\n      class: d,\n      values: inline inline-block block grid table table-row table-cell flex inline-flex none\n    ),\n    // scss-docs-end utils-display\n    // scss-docs-start utils-shadow\n    \"shadow\": (\n      property: box-shadow,\n      class: shadow,\n      values: (\n        null: $box-shadow,\n        sm: $box-shadow-sm,\n        lg: $box-shadow-lg,\n        none: none,\n      )\n    ),\n    // scss-docs-end utils-shadow\n    // scss-docs-start utils-position\n    \"position\": (\n      property: position,\n      values: static relative absolute fixed sticky\n    ),\n    \"top\": (\n      property: top,\n      values: $position-values\n    ),\n    \"bottom\": (\n      property: bottom,\n      values: $position-values\n    ),\n    \"start\": (\n      property: left,\n      class: start,\n      values: $position-values\n    ),\n    \"end\": (\n      property: right,\n      class: end,\n      values: $position-values\n    ),\n    \"translate-middle\": (\n      property: transform,\n      class: translate-middle,\n      values: (\n        null: translate(-50%, -50%),\n        x: translateX(-50%),\n        y: translateY(-50%),\n      )\n    ),\n    // scss-docs-end utils-position\n    // scss-docs-start utils-borders\n    \"border\": (\n      property: border,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-top\": (\n      property: border-top,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-end\": (\n      property: border-right,\n      class: border-end,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-bottom\": (\n      property: border-bottom,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-start\": (\n      property: border-left,\n      class: border-start,\n      values: (\n        null: $border-width solid $border-color,\n        0: 0,\n      )\n    ),\n    \"border-color\": (\n      property: border-color,\n      class: border,\n      values: map-merge($theme-colors, (\"white\": $white))\n    ),\n    \"border-width\": (\n      property: border-width,\n      class: border,\n      values: $border-widths\n    ),\n    // scss-docs-end utils-borders\n    // Sizing utilities\n    // scss-docs-start utils-sizing\n    \"width\": (\n      property: width,\n      class: w,\n      values: (\n        25: 25%,\n        50: 50%,\n        75: 75%,\n        100: 100%,\n        auto: auto\n      )\n    ),\n    \"max-width\": (\n      property: max-width,\n      class: mw,\n      values: (100: 100%)\n    ),\n    \"viewport-width\": (\n      property: width,\n      class: vw,\n      values: (100: 100vw)\n    ),\n    \"min-viewport-width\": (\n      property: min-width,\n      class: min-vw,\n      values: (100: 100vw)\n    ),\n    \"height\": (\n      property: height,\n      class: h,\n      values: (\n        25: 25%,\n        50: 50%,\n        75: 75%,\n        100: 100%,\n        auto: auto\n      )\n    ),\n    \"max-height\": (\n      property: max-height,\n      class: mh,\n      values: (100: 100%)\n    ),\n    \"viewport-height\": (\n      property: height,\n      class: vh,\n      values: (100: 100vh)\n    ),\n    \"min-viewport-height\": (\n      property: min-height,\n      class: min-vh,\n      values: (100: 100vh)\n    ),\n    // scss-docs-end utils-sizing\n    // Flex utilities\n    // scss-docs-start utils-flex\n    \"flex\": (\n      responsive: true,\n      property: flex,\n      values: (fill: 1 1 auto)\n    ),\n    \"flex-direction\": (\n      responsive: true,\n      property: flex-direction,\n      class: flex,\n      values: row column row-reverse column-reverse\n    ),\n    \"flex-grow\": (\n      responsive: true,\n      property: flex-grow,\n      class: flex,\n      values: (\n        grow-0: 0,\n        grow-1: 1,\n      )\n    ),\n    \"flex-shrink\": (\n      responsive: true,\n      property: flex-shrink,\n      class: flex,\n      values: (\n        shrink-0: 0,\n        shrink-1: 1,\n      )\n    ),\n    \"flex-wrap\": (\n      responsive: true,\n      property: flex-wrap,\n      class: flex,\n      values: wrap nowrap wrap-reverse\n    ),\n    \"gap\": (\n      responsive: true,\n      property: gap,\n      class: gap,\n      values: $spacers\n    ),\n    \"justify-content\": (\n      responsive: true,\n      property: justify-content,\n      values: (\n        start: flex-start,\n        end: flex-end,\n        center: center,\n        between: space-between,\n        around: space-around,\n        evenly: space-evenly,\n      )\n    ),\n    \"align-items\": (\n      responsive: true,\n      property: align-items,\n      values: (\n        start: flex-start,\n        end: flex-end,\n        center: center,\n        baseline: baseline,\n        stretch: stretch,\n      )\n    ),\n    \"align-content\": (\n      responsive: true,\n      property: align-content,\n      values: (\n        start: flex-start,\n        end: flex-end,\n        center: center,\n        between: space-between,\n        around: space-around,\n        stretch: stretch,\n      )\n    ),\n    \"align-self\": (\n      responsive: true,\n      property: align-self,\n      values: (\n        auto: auto,\n        start: flex-start,\n        end: flex-end,\n        center: center,\n        baseline: baseline,\n        stretch: stretch,\n      )\n    ),\n    \"order\": (\n      responsive: true,\n      property: order,\n      values: (\n        first: -1,\n        0: 0,\n        1: 1,\n        2: 2,\n        3: 3,\n        4: 4,\n        5: 5,\n        last: 6,\n      ),\n    ),\n    // scss-docs-end utils-flex\n    // Margin utilities\n    // scss-docs-start utils-spacing\n    \"margin\": (\n      responsive: true,\n      property: margin,\n      class: m,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-x\": (\n      responsive: true,\n      property: margin-right margin-left,\n      class: mx,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-y\": (\n      responsive: true,\n      property: margin-top margin-bottom,\n      class: my,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-top\": (\n      responsive: true,\n      property: margin-top,\n      class: mt,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-end\": (\n      responsive: true,\n      property: margin-right,\n      class: me,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-bottom\": (\n      responsive: true,\n      property: margin-bottom,\n      class: mb,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    \"margin-start\": (\n      responsive: true,\n      property: margin-left,\n      class: ms,\n      values: map-merge($spacers, (auto: auto))\n    ),\n    // Negative margin utilities\n    \"negative-margin\": (\n      responsive: true,\n      property: margin,\n      class: m,\n      values: $negative-spacers\n    ),\n    \"negative-margin-x\": (\n      responsive: true,\n      property: margin-right margin-left,\n      class: mx,\n      values: $negative-spacers\n    ),\n    \"negative-margin-y\": (\n      responsive: true,\n      property: margin-top margin-bottom,\n      class: my,\n      values: $negative-spacers\n    ),\n    \"negative-margin-top\": (\n      responsive: true,\n      property: margin-top,\n      class: mt,\n      values: $negative-spacers\n    ),\n    \"negative-margin-end\": (\n      responsive: true,\n      property: margin-right,\n      class: me,\n      values: $negative-spacers\n    ),\n    \"negative-margin-bottom\": (\n      responsive: true,\n      property: margin-bottom,\n      class: mb,\n      values: $negative-spacers\n    ),\n    \"negative-margin-start\": (\n      responsive: true,\n      property: margin-left,\n      class: ms,\n      values: $negative-spacers\n    ),\n    // Padding utilities\n    \"padding\": (\n      responsive: true,\n      property: padding,\n      class: p,\n      values: $spacers\n    ),\n    \"padding-x\": (\n      responsive: true,\n      property: padding-right padding-left,\n      class: px,\n      values: $spacers\n    ),\n    \"padding-y\": (\n      responsive: true,\n      property: padding-top padding-bottom,\n      class: py,\n      values: $spacers\n    ),\n    \"padding-top\": (\n      responsive: true,\n      property: padding-top,\n      class: pt,\n      values: $spacers\n    ),\n    \"padding-end\": (\n      responsive: true,\n      property: padding-right,\n      class: pe,\n      values: $spacers\n    ),\n    \"padding-bottom\": (\n      responsive: true,\n      property: padding-bottom,\n      class: pb,\n      values: $spacers\n    ),\n    \"padding-start\": (\n      responsive: true,\n      property: padding-left,\n      class: ps,\n      values: $spacers\n    ),\n    // scss-docs-end utils-spacing\n    // Text\n    // scss-docs-start utils-text\n    \"font-family\": (\n      property: font-family,\n      class: font,\n      values: (monospace: var(--#{$variable-prefix}font-monospace))\n    ),\n    \"font-size\": (\n      rfs: true,\n      property: font-size,\n      class: fs,\n      values: $font-sizes\n    ),\n    \"font-style\": (\n      property: font-style,\n      class: fst,\n      values: italic normal\n    ),\n    \"font-weight\": (\n      property: font-weight,\n      class: fw,\n      values: (\n        light: $font-weight-light,\n        lighter: $font-weight-lighter,\n        normal: $font-weight-normal,\n        bold: $font-weight-bold,\n        bolder: $font-weight-bolder\n      )\n    ),\n    \"line-height\": (\n      property: line-height,\n      class: lh,\n      values: (\n        1: 1,\n        sm: $line-height-sm,\n        base: $line-height-base,\n        lg: $line-height-lg,\n      )\n    ),\n    \"text-align\": (\n      responsive: true,\n      property: text-align,\n      class: text,\n      values: (\n        start: left,\n        end: right,\n        center: center,\n      )\n    ),\n    \"text-decoration\": (\n      property: text-decoration,\n      values: none underline line-through\n    ),\n    \"text-transform\": (\n      property: text-transform,\n      class: text,\n      values: lowercase uppercase capitalize\n    ),\n    \"white-space\": (\n      property: white-space,\n      class: text,\n      values: (\n        wrap: normal,\n        nowrap: nowrap,\n      )\n    ),\n    \"word-wrap\": (\n      property: word-wrap word-break,\n      class: text,\n      values: (break: break-word),\n      rtl: false\n    ),\n    // scss-docs-end utils-text\n    // scss-docs-start utils-color\n    \"color\": (\n      property: color,\n      class: text,\n      local-vars: (\n        \"text-opacity\": 1\n      ),\n      values: map-merge(\n        $utilities-text-colors,\n        (\n          \"muted\": $text-muted,\n          \"black-50\": rgba($black, .5), // deprecated\n          \"white-50\": rgba($white, .5), // deprecated\n          \"reset\": inherit,\n        )\n      )\n    ),\n    \"text-opacity\": (\n      css-var: true,\n      class: text-opacity,\n      values: (\n        25: .25,\n        50: .5,\n        75: .75,\n        100: 1\n      )\n    ),\n    // scss-docs-end utils-color\n    // scss-docs-start utils-bg-color\n    \"background-color\": (\n      property: background-color,\n      class: bg,\n      local-vars: (\n        \"bg-opacity\": 1\n      ),\n      values: map-merge(\n        $utilities-bg-colors,\n        (\n          \"transparent\": transparent\n        )\n      )\n    ),\n    \"bg-opacity\": (\n      css-var: true,\n      class: bg-opacity,\n      values: (\n        10: .1,\n        25: .25,\n        50: .5,\n        75: .75,\n        100: 1\n      )\n    ),\n    // scss-docs-end utils-bg-color\n    \"gradient\": (\n      property: background-image,\n      class: bg,\n      values: (gradient: var(--#{$variable-prefix}gradient))\n    ),\n    // scss-docs-start utils-interaction\n    \"user-select\": (\n      property: user-select,\n      values: all auto none\n    ),\n    \"pointer-events\": (\n      property: pointer-events,\n      class: pe,\n      values: none auto,\n    ),\n    // scss-docs-end utils-interaction\n    // scss-docs-start utils-border-radius\n    \"rounded\": (\n      property: border-radius,\n      class: rounded,\n      values: (\n        null: $border-radius,\n        0: 0,\n        1: $border-radius-sm,\n        2: $border-radius,\n        3: $border-radius-lg,\n        circle: 50%,\n        pill: $border-radius-pill\n      )\n    ),\n    \"rounded-top\": (\n      property: border-top-left-radius border-top-right-radius,\n      class: rounded-top,\n      values: (null: $border-radius)\n    ),\n    \"rounded-end\": (\n      property: border-top-right-radius border-bottom-right-radius,\n      class: rounded-end,\n      values: (null: $border-radius)\n    ),\n    \"rounded-bottom\": (\n      property: border-bottom-right-radius border-bottom-left-radius,\n      class: rounded-bottom,\n      values: (null: $border-radius)\n    ),\n    \"rounded-start\": (\n      property: border-bottom-left-radius border-top-left-radius,\n      class: rounded-start,\n      values: (null: $border-radius)\n    ),\n    // scss-docs-end utils-border-radius\n    // scss-docs-start utils-visibility\n    \"visibility\": (\n      property: visibility,\n      class: null,\n      values: (\n        visible: visible,\n        invisible: hidden,\n      )\n    )\n    // scss-docs-end utils-visibility\n  ),\n  $utilities\n);\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/_variables.scss",
    "content": "// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n// scss-docs-start gray-color-variables\n$white:    #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black:    #000 !default;\n// scss-docs-end gray-color-variables\n\n// fusv-disable\n// scss-docs-start gray-colors-map\n$grays: (\n  \"100\": $gray-100,\n  \"200\": $gray-200,\n  \"300\": $gray-300,\n  \"400\": $gray-400,\n  \"500\": $gray-500,\n  \"600\": $gray-600,\n  \"700\": $gray-700,\n  \"800\": $gray-800,\n  \"900\": $gray-900\n) !default;\n// scss-docs-end gray-colors-map\n// fusv-enable\n\n// scss-docs-start color-variables\n$blue:    #0d6efd !default;\n$indigo:  #6610f2 !default;\n$purple:  #6f42c1 !default;\n$pink:    #d63384 !default;\n$red:     #dc3545 !default;\n$orange:  #fd7e14 !default;\n$yellow:  #ffc107 !default;\n$green:   #198754 !default;\n$teal:    #20c997 !default;\n$cyan:    #0dcaf0 !default;\n// scss-docs-end color-variables\n\n// scss-docs-start colors-map\n$colors: (\n  \"blue\":       $blue,\n  \"indigo\":     $indigo,\n  \"purple\":     $purple,\n  \"pink\":       $pink,\n  \"red\":        $red,\n  \"orange\":     $orange,\n  \"yellow\":     $yellow,\n  \"green\":      $green,\n  \"teal\":       $teal,\n  \"cyan\":       $cyan,\n  \"white\":      $white,\n  \"gray\":       $gray-600,\n  \"gray-dark\":  $gray-800\n) !default;\n// scss-docs-end colors-map\n\n// scss-docs-start theme-color-variables\n$primary:       $blue !default;\n$secondary:     $gray-600 !default;\n$success:       $green !default;\n$info:          $cyan !default;\n$warning:       $yellow !default;\n$danger:        $red !default;\n$light:         $gray-100 !default;\n$dark:          $gray-900 !default;\n// scss-docs-end theme-color-variables\n\n// scss-docs-start theme-colors-map\n$theme-colors: (\n  \"primary\":    $primary,\n  \"secondary\":  $secondary,\n  \"success\":    $success,\n  \"info\":       $info,\n  \"warning\":    $warning,\n  \"danger\":     $danger,\n  \"light\":      $light,\n  \"dark\":       $dark\n) !default;\n// scss-docs-end theme-colors-map\n\n// scss-docs-start theme-colors-rgb\n$theme-colors-rgb: map-loop($theme-colors, to-rgb, \"$value\") !default;\n// scss-docs-end theme-colors-rgb\n\n// The contrast ratio to reach against white, to determine if color changes from \"light\" to \"dark\". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.\n// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast\n$min-contrast-ratio:   4.5 !default;\n\n// Customize the light and dark text colors for use in our color contrast function.\n$color-contrast-dark:      $black !default;\n$color-contrast-light:     $white !default;\n\n// fusv-disable\n$blue-100: tint-color($blue, 80%) !default;\n$blue-200: tint-color($blue, 60%) !default;\n$blue-300: tint-color($blue, 40%) !default;\n$blue-400: tint-color($blue, 20%) !default;\n$blue-500: $blue !default;\n$blue-600: shade-color($blue, 20%) !default;\n$blue-700: shade-color($blue, 40%) !default;\n$blue-800: shade-color($blue, 60%) !default;\n$blue-900: shade-color($blue, 80%) !default;\n\n$indigo-100: tint-color($indigo, 80%) !default;\n$indigo-200: tint-color($indigo, 60%) !default;\n$indigo-300: tint-color($indigo, 40%) !default;\n$indigo-400: tint-color($indigo, 20%) !default;\n$indigo-500: $indigo !default;\n$indigo-600: shade-color($indigo, 20%) !default;\n$indigo-700: shade-color($indigo, 40%) !default;\n$indigo-800: shade-color($indigo, 60%) !default;\n$indigo-900: shade-color($indigo, 80%) !default;\n\n$purple-100: tint-color($purple, 80%) !default;\n$purple-200: tint-color($purple, 60%) !default;\n$purple-300: tint-color($purple, 40%) !default;\n$purple-400: tint-color($purple, 20%) !default;\n$purple-500: $purple !default;\n$purple-600: shade-color($purple, 20%) !default;\n$purple-700: shade-color($purple, 40%) !default;\n$purple-800: shade-color($purple, 60%) !default;\n$purple-900: shade-color($purple, 80%) !default;\n\n$pink-100: tint-color($pink, 80%) !default;\n$pink-200: tint-color($pink, 60%) !default;\n$pink-300: tint-color($pink, 40%) !default;\n$pink-400: tint-color($pink, 20%) !default;\n$pink-500: $pink !default;\n$pink-600: shade-color($pink, 20%) !default;\n$pink-700: shade-color($pink, 40%) !default;\n$pink-800: shade-color($pink, 60%) !default;\n$pink-900: shade-color($pink, 80%) !default;\n\n$red-100: tint-color($red, 80%) !default;\n$red-200: tint-color($red, 60%) !default;\n$red-300: tint-color($red, 40%) !default;\n$red-400: tint-color($red, 20%) !default;\n$red-500: $red !default;\n$red-600: shade-color($red, 20%) !default;\n$red-700: shade-color($red, 40%) !default;\n$red-800: shade-color($red, 60%) !default;\n$red-900: shade-color($red, 80%) !default;\n\n$orange-100: tint-color($orange, 80%) !default;\n$orange-200: tint-color($orange, 60%) !default;\n$orange-300: tint-color($orange, 40%) !default;\n$orange-400: tint-color($orange, 20%) !default;\n$orange-500: $orange !default;\n$orange-600: shade-color($orange, 20%) !default;\n$orange-700: shade-color($orange, 40%) !default;\n$orange-800: shade-color($orange, 60%) !default;\n$orange-900: shade-color($orange, 80%) !default;\n\n$yellow-100: tint-color($yellow, 80%) !default;\n$yellow-200: tint-color($yellow, 60%) !default;\n$yellow-300: tint-color($yellow, 40%) !default;\n$yellow-400: tint-color($yellow, 20%) !default;\n$yellow-500: $yellow !default;\n$yellow-600: shade-color($yellow, 20%) !default;\n$yellow-700: shade-color($yellow, 40%) !default;\n$yellow-800: shade-color($yellow, 60%) !default;\n$yellow-900: shade-color($yellow, 80%) !default;\n\n$green-100: tint-color($green, 80%) !default;\n$green-200: tint-color($green, 60%) !default;\n$green-300: tint-color($green, 40%) !default;\n$green-400: tint-color($green, 20%) !default;\n$green-500: $green !default;\n$green-600: shade-color($green, 20%) !default;\n$green-700: shade-color($green, 40%) !default;\n$green-800: shade-color($green, 60%) !default;\n$green-900: shade-color($green, 80%) !default;\n\n$teal-100: tint-color($teal, 80%) !default;\n$teal-200: tint-color($teal, 60%) !default;\n$teal-300: tint-color($teal, 40%) !default;\n$teal-400: tint-color($teal, 20%) !default;\n$teal-500: $teal !default;\n$teal-600: shade-color($teal, 20%) !default;\n$teal-700: shade-color($teal, 40%) !default;\n$teal-800: shade-color($teal, 60%) !default;\n$teal-900: shade-color($teal, 80%) !default;\n\n$cyan-100: tint-color($cyan, 80%) !default;\n$cyan-200: tint-color($cyan, 60%) !default;\n$cyan-300: tint-color($cyan, 40%) !default;\n$cyan-400: tint-color($cyan, 20%) !default;\n$cyan-500: $cyan !default;\n$cyan-600: shade-color($cyan, 20%) !default;\n$cyan-700: shade-color($cyan, 40%) !default;\n$cyan-800: shade-color($cyan, 60%) !default;\n$cyan-900: shade-color($cyan, 80%) !default;\n\n$blues: (\n  \"blue-100\": $blue-100,\n  \"blue-200\": $blue-200,\n  \"blue-300\": $blue-300,\n  \"blue-400\": $blue-400,\n  \"blue-500\": $blue-500,\n  \"blue-600\": $blue-600,\n  \"blue-700\": $blue-700,\n  \"blue-800\": $blue-800,\n  \"blue-900\": $blue-900\n) !default;\n\n$indigos: (\n  \"indigo-100\": $indigo-100,\n  \"indigo-200\": $indigo-200,\n  \"indigo-300\": $indigo-300,\n  \"indigo-400\": $indigo-400,\n  \"indigo-500\": $indigo-500,\n  \"indigo-600\": $indigo-600,\n  \"indigo-700\": $indigo-700,\n  \"indigo-800\": $indigo-800,\n  \"indigo-900\": $indigo-900\n) !default;\n\n$purples: (\n  \"purple-100\": $purple-200,\n  \"purple-200\": $purple-100,\n  \"purple-300\": $purple-300,\n  \"purple-400\": $purple-400,\n  \"purple-500\": $purple-500,\n  \"purple-600\": $purple-600,\n  \"purple-700\": $purple-700,\n  \"purple-800\": $purple-800,\n  \"purple-900\": $purple-900\n) !default;\n\n$pinks: (\n  \"pink-100\": $pink-100,\n  \"pink-200\": $pink-200,\n  \"pink-300\": $pink-300,\n  \"pink-400\": $pink-400,\n  \"pink-500\": $pink-500,\n  \"pink-600\": $pink-600,\n  \"pink-700\": $pink-700,\n  \"pink-800\": $pink-800,\n  \"pink-900\": $pink-900\n) !default;\n\n$reds: (\n  \"red-100\": $red-100,\n  \"red-200\": $red-200,\n  \"red-300\": $red-300,\n  \"red-400\": $red-400,\n  \"red-500\": $red-500,\n  \"red-600\": $red-600,\n  \"red-700\": $red-700,\n  \"red-800\": $red-800,\n  \"red-900\": $red-900\n) !default;\n\n$oranges: (\n  \"orange-100\": $orange-100,\n  \"orange-200\": $orange-200,\n  \"orange-300\": $orange-300,\n  \"orange-400\": $orange-400,\n  \"orange-500\": $orange-500,\n  \"orange-600\": $orange-600,\n  \"orange-700\": $orange-700,\n  \"orange-800\": $orange-800,\n  \"orange-900\": $orange-900\n) !default;\n\n$yellows: (\n  \"yellow-100\": $yellow-100,\n  \"yellow-200\": $yellow-200,\n  \"yellow-300\": $yellow-300,\n  \"yellow-400\": $yellow-400,\n  \"yellow-500\": $yellow-500,\n  \"yellow-600\": $yellow-600,\n  \"yellow-700\": $yellow-700,\n  \"yellow-800\": $yellow-800,\n  \"yellow-900\": $yellow-900\n) !default;\n\n$greens: (\n  \"green-100\": $green-100,\n  \"green-200\": $green-200,\n  \"green-300\": $green-300,\n  \"green-400\": $green-400,\n  \"green-500\": $green-500,\n  \"green-600\": $green-600,\n  \"green-700\": $green-700,\n  \"green-800\": $green-800,\n  \"green-900\": $green-900\n) !default;\n\n$teals: (\n  \"teal-100\": $teal-100,\n  \"teal-200\": $teal-200,\n  \"teal-300\": $teal-300,\n  \"teal-400\": $teal-400,\n  \"teal-500\": $teal-500,\n  \"teal-600\": $teal-600,\n  \"teal-700\": $teal-700,\n  \"teal-800\": $teal-800,\n  \"teal-900\": $teal-900\n) !default;\n\n$cyans: (\n  \"cyan-100\": $cyan-100,\n  \"cyan-200\": $cyan-200,\n  \"cyan-300\": $cyan-300,\n  \"cyan-400\": $cyan-400,\n  \"cyan-500\": $cyan-500,\n  \"cyan-600\": $cyan-600,\n  \"cyan-700\": $cyan-700,\n  \"cyan-800\": $cyan-800,\n  \"cyan-900\": $cyan-900\n) !default;\n// fusv-enable\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n  (\"<\", \"%3c\"),\n  (\">\", \"%3e\"),\n  (\"#\", \"%23\"),\n  (\"(\", \"%28\"),\n  (\")\", \"%29\"),\n) !default;\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret:                true !default;\n$enable-rounded:              true !default;\n$enable-shadows:              false !default;\n$enable-gradients:            false !default;\n$enable-transitions:          true !default;\n$enable-reduced-motion:       true !default;\n$enable-smooth-scroll:        true !default;\n$enable-grid-classes:         true !default;\n$enable-cssgrid:              false !default;\n$enable-button-pointers:      true !default;\n$enable-rfs:                  true !default;\n$enable-validation-icons:     true !default;\n$enable-negative-margins:     false !default;\n$enable-deprecation-messages: true !default;\n$enable-important-utilities:  true !default;\n\n// Prefix for :root CSS variables\n\n$variable-prefix:             bs- !default;\n\n// Gradient\n//\n// The gradient which is added to components if `$enable-gradients` is `true`\n// This gradient is also added to elements with `.bg-gradient`\n// scss-docs-start variable-gradient\n$gradient: linear-gradient(180deg, rgba($white, .15), rgba($white, 0)) !default;\n// scss-docs-end variable-gradient\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n// scss-docs-start spacer-variables-maps\n$spacer: 1rem !default;\n$spacers: (\n  0: 0,\n  1: $spacer * .25,\n  2: $spacer * .5,\n  3: $spacer,\n  4: $spacer * 1.5,\n  5: $spacer * 3,\n) !default;\n\n$negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default;\n// scss-docs-end spacer-variables-maps\n\n// Position\n//\n// Define the edge positioning anchors of the position utilities.\n\n// scss-docs-start position-map\n$position-values: (\n  0: 0,\n  50: 50%,\n  100: 100%\n) !default;\n// scss-docs-end position-map\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg:                   $white !default;\n$body-color:                $gray-900 !default;\n$body-text-align:           null !default;\n\n// Utilities maps\n//\n// Extends the default `$theme-colors` maps to help create our utilities.\n\n// Come v6, we'll de-dupe these variables. Until then, for backward compatibility, we keep them to reassign.\n// scss-docs-start utilities-colors\n$utilities-colors: $theme-colors-rgb !default;\n// scss-docs-end utilities-colors\n\n// scss-docs-start utilities-text-colors\n$utilities-text: map-merge(\n  $utilities-colors,\n  (\n    \"black\": to-rgb($black),\n    \"white\": to-rgb($white),\n    \"body\": to-rgb($body-color)\n  )\n) !default;\n$utilities-text-colors: map-loop($utilities-text, rgba-css-var, \"$key\", \"text\") !default;\n// scss-docs-end utilities-text-colors\n\n// scss-docs-start utilities-bg-colors\n$utilities-bg: map-merge(\n  $utilities-colors,\n  (\n    \"black\": to-rgb($black),\n    \"white\": to-rgb($white),\n    \"body\": to-rgb($body-bg)\n  )\n) !default;\n$utilities-bg-colors: map-loop($utilities-bg, rgba-css-var, \"$key\", \"bg\") !default;\n// scss-docs-end utilities-bg-colors\n\n// Links\n//\n// Style anchor elements.\n\n$link-color:                              $primary !default;\n$link-decoration:                         underline !default;\n$link-shade-percentage:                   20% !default;\n$link-hover-color:                        shift-color($link-color, $link-shade-percentage) !default;\n$link-hover-decoration:                   null !default;\n\n$stretched-link-pseudo-element:           after !default;\n$stretched-link-z-index:                  1 !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom:   1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n// scss-docs-start grid-breakpoints\n$grid-breakpoints: (\n  xs: 0,\n  sm: 576px,\n  md: 768px,\n  lg: 992px,\n  xl: 1200px,\n  xxl: 1400px\n) !default;\n// scss-docs-end grid-breakpoints\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n// scss-docs-start container-max-widths\n$container-max-widths: (\n  sm: 540px,\n  md: 720px,\n  lg: 960px,\n  xl: 1140px,\n  xxl: 1320px\n) !default;\n// scss-docs-end container-max-widths\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns:                12 !default;\n$grid-gutter-width:           1.5rem !default;\n$grid-row-columns:            6 !default;\n\n$gutters: $spacers !default;\n\n// Container padding\n\n$container-padding-x: $grid-gutter-width * .5 !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n// scss-docs-start border-variables\n$border-width:                1px !default;\n$border-widths: (\n  1: 1px,\n  2: 2px,\n  3: 3px,\n  4: 4px,\n  5: 5px\n) !default;\n\n$border-color:                $gray-300 !default;\n// scss-docs-end border-variables\n\n// scss-docs-start border-radius-variables\n$border-radius:               .25rem !default;\n$border-radius-sm:            .2rem !default;\n$border-radius-lg:            .3rem !default;\n$border-radius-pill:          50rem !default;\n// scss-docs-end border-radius-variables\n\n// scss-docs-start box-shadow-variables\n$box-shadow:                  0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-sm:               0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow-lg:               0 1rem 3rem rgba($black, .175) !default;\n$box-shadow-inset:            inset 0 1px 2px rgba($black, .075) !default;\n// scss-docs-end box-shadow-variables\n\n$component-active-color:      $white !default;\n$component-active-bg:         $primary !default;\n\n// scss-docs-start caret-variables\n$caret-width:                 .3em !default;\n$caret-vertical-align:        $caret-width * .85 !default;\n$caret-spacing:               $caret-width * .85 !default;\n// scss-docs-end caret-variables\n\n$transition-base:             all .2s ease-in-out !default;\n$transition-fade:             opacity .15s linear !default;\n// scss-docs-start collapse-transition\n$transition-collapse:         height .35s ease !default;\n$transition-collapse-width:   width .35s ease !default;\n// scss-docs-end collapse-transition\n\n// stylelint-disable function-disallowed-list\n// scss-docs-start aspect-ratios\n$aspect-ratios: (\n  \"1x1\": 100%,\n  \"4x3\": calc(3 / 4 * 100%),\n  \"16x9\": calc(9 / 16 * 100%),\n  \"21x9\": calc(9 / 21 * 100%)\n) !default;\n// scss-docs-end aspect-ratios\n// stylelint-enable function-disallowed-list\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// scss-docs-start font-variables\n// stylelint-disable value-keyword-case\n$font-family-sans-serif:      system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace:       SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n// stylelint-enable value-keyword-case\n$font-family-base:            var(--#{$variable-prefix}font-sans-serif) !default;\n$font-family-code:            var(--#{$variable-prefix}font-monospace) !default;\n\n// $font-size-root affects the value of `rem`, which is used for as well font sizes, paddings, and margins\n// $font-size-base affects the font size of the body text\n$font-size-root:              null !default;\n$font-size-base:              1rem !default; // Assumes the browser default, typically `16px`\n$font-size-sm:                $font-size-base * .875 !default;\n$font-size-lg:                $font-size-base * 1.25 !default;\n\n$font-weight-lighter:         lighter !default;\n$font-weight-light:           300 !default;\n$font-weight-normal:          400 !default;\n$font-weight-bold:            700 !default;\n$font-weight-bolder:          bolder !default;\n\n$font-weight-base:            $font-weight-normal !default;\n\n$line-height-base:            1.5 !default;\n$line-height-sm:              1.25 !default;\n$line-height-lg:              2 !default;\n\n$h1-font-size:                $font-size-base * 2.5 !default;\n$h2-font-size:                $font-size-base * 2 !default;\n$h3-font-size:                $font-size-base * 1.75 !default;\n$h4-font-size:                $font-size-base * 1.5 !default;\n$h5-font-size:                $font-size-base * 1.25 !default;\n$h6-font-size:                $font-size-base !default;\n// scss-docs-end font-variables\n\n// scss-docs-start font-sizes\n$font-sizes: (\n  1: $h1-font-size,\n  2: $h2-font-size,\n  3: $h3-font-size,\n  4: $h4-font-size,\n  5: $h5-font-size,\n  6: $h6-font-size\n) !default;\n// scss-docs-end font-sizes\n\n// scss-docs-start headings-variables\n$headings-margin-bottom:      $spacer * .5 !default;\n$headings-font-family:        null !default;\n$headings-font-style:         null !default;\n$headings-font-weight:        500 !default;\n$headings-line-height:        1.2 !default;\n$headings-color:              null !default;\n// scss-docs-end headings-variables\n\n// scss-docs-start display-headings\n$display-font-sizes: (\n  1: 5rem,\n  2: 4.5rem,\n  3: 4rem,\n  4: 3.5rem,\n  5: 3rem,\n  6: 2.5rem\n) !default;\n\n$display-font-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n// scss-docs-end display-headings\n\n// scss-docs-start type-variables\n$lead-font-size:              $font-size-base * 1.25 !default;\n$lead-font-weight:            300 !default;\n\n$small-font-size:             .875em !default;\n\n$sub-sup-font-size:           .75em !default;\n\n$text-muted:                  $gray-600 !default;\n\n$initialism-font-size:        $small-font-size !default;\n\n$blockquote-margin-y:         $spacer !default;\n$blockquote-font-size:        $font-size-base * 1.25 !default;\n$blockquote-footer-color:     $gray-600 !default;\n$blockquote-footer-font-size: $small-font-size !default;\n\n$hr-margin-y:                 $spacer !default;\n$hr-color:                    inherit !default;\n$hr-height:                   $border-width !default;\n$hr-opacity:                  .25 !default;\n\n$legend-margin-bottom:        .5rem !default;\n$legend-font-size:            1.5rem !default;\n$legend-font-weight:          null !default;\n\n$mark-padding:                .2em !default;\n\n$dt-font-weight:              $font-weight-bold !default;\n\n$nested-kbd-font-weight:      $font-weight-bold !default;\n\n$list-inline-padding:         .5rem !default;\n\n$mark-bg:                     #fcf8e3 !default;\n// scss-docs-end type-variables\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n// scss-docs-start table-variables\n$table-cell-padding-y:        .5rem !default;\n$table-cell-padding-x:        .5rem !default;\n$table-cell-padding-y-sm:     .25rem !default;\n$table-cell-padding-x-sm:     .25rem !default;\n\n$table-cell-vertical-align:   top !default;\n\n$table-color:                 $body-color !default;\n$table-bg:                    transparent !default;\n$table-accent-bg:             transparent !default;\n\n$table-th-font-weight:        null !default;\n\n$table-striped-color:         $table-color !default;\n$table-striped-bg-factor:     .05 !default;\n$table-striped-bg:            rgba($black, $table-striped-bg-factor) !default;\n\n$table-active-color:          $table-color !default;\n$table-active-bg-factor:      .1 !default;\n$table-active-bg:             rgba($black, $table-active-bg-factor) !default;\n\n$table-hover-color:           $table-color !default;\n$table-hover-bg-factor:       .075 !default;\n$table-hover-bg:              rgba($black, $table-hover-bg-factor) !default;\n\n$table-border-factor:         .1 !default;\n$table-border-width:          $border-width !default;\n$table-border-color:          $border-color !default;\n\n$table-striped-order:         odd !default;\n\n$table-group-separator-color: currentColor !default;\n\n$table-caption-color:         $text-muted !default;\n\n$table-bg-scale:              -80% !default;\n// scss-docs-end table-variables\n\n// scss-docs-start table-loop\n$table-variants: (\n  \"primary\":    shift-color($primary, $table-bg-scale),\n  \"secondary\":  shift-color($secondary, $table-bg-scale),\n  \"success\":    shift-color($success, $table-bg-scale),\n  \"info\":       shift-color($info, $table-bg-scale),\n  \"warning\":    shift-color($warning, $table-bg-scale),\n  \"danger\":     shift-color($danger, $table-bg-scale),\n  \"light\":      $light,\n  \"dark\":       $dark,\n) !default;\n// scss-docs-end table-loop\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n// scss-docs-start input-btn-variables\n$input-btn-padding-y:         .375rem !default;\n$input-btn-padding-x:         .75rem !default;\n$input-btn-font-family:       null !default;\n$input-btn-font-size:         $font-size-base !default;\n$input-btn-line-height:       $line-height-base !default;\n\n$input-btn-focus-width:         .25rem !default;\n$input-btn-focus-color-opacity: .25 !default;\n$input-btn-focus-color:         rgba($component-active-bg, $input-btn-focus-color-opacity) !default;\n$input-btn-focus-blur:          0 !default;\n$input-btn-focus-box-shadow:    0 0 $input-btn-focus-blur $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm:      .25rem !default;\n$input-btn-padding-x-sm:      .5rem !default;\n$input-btn-font-size-sm:      $font-size-sm !default;\n\n$input-btn-padding-y-lg:      .5rem !default;\n$input-btn-padding-x-lg:      1rem !default;\n$input-btn-font-size-lg:      $font-size-lg !default;\n\n$input-btn-border-width:      $border-width !default;\n// scss-docs-end input-btn-variables\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n// scss-docs-start btn-variables\n$btn-padding-y:               $input-btn-padding-y !default;\n$btn-padding-x:               $input-btn-padding-x !default;\n$btn-font-family:             $input-btn-font-family !default;\n$btn-font-size:               $input-btn-font-size !default;\n$btn-line-height:             $input-btn-line-height !default;\n$btn-white-space:             null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm:            $input-btn-padding-y-sm !default;\n$btn-padding-x-sm:            $input-btn-padding-x-sm !default;\n$btn-font-size-sm:            $input-btn-font-size-sm !default;\n\n$btn-padding-y-lg:            $input-btn-padding-y-lg !default;\n$btn-padding-x-lg:            $input-btn-padding-x-lg !default;\n$btn-font-size-lg:            $input-btn-font-size-lg !default;\n\n$btn-border-width:            $input-btn-border-width !default;\n\n$btn-font-weight:             $font-weight-normal !default;\n$btn-box-shadow:              inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width:             $input-btn-focus-width !default;\n$btn-focus-box-shadow:        $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity:        .65 !default;\n$btn-active-box-shadow:       inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-color:              $link-color !default;\n$btn-link-hover-color:        $link-hover-color !default;\n$btn-link-disabled-color:     $gray-600 !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius:           $border-radius !default;\n$btn-border-radius-sm:        $border-radius-sm !default;\n$btn-border-radius-lg:        $border-radius-lg !default;\n\n$btn-transition:              color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$btn-hover-bg-shade-amount:       15% !default;\n$btn-hover-bg-tint-amount:        15% !default;\n$btn-hover-border-shade-amount:   20% !default;\n$btn-hover-border-tint-amount:    10% !default;\n$btn-active-bg-shade-amount:      20% !default;\n$btn-active-bg-tint-amount:       20% !default;\n$btn-active-border-shade-amount:  25% !default;\n$btn-active-border-tint-amount:   10% !default;\n// scss-docs-end btn-variables\n\n\n// Forms\n\n// scss-docs-start form-text-variables\n$form-text-margin-top:                  .25rem !default;\n$form-text-font-size:                   $small-font-size !default;\n$form-text-font-style:                  null !default;\n$form-text-font-weight:                 null !default;\n$form-text-color:                       $text-muted !default;\n// scss-docs-end form-text-variables\n\n// scss-docs-start form-label-variables\n$form-label-margin-bottom:              .5rem !default;\n$form-label-font-size:                  null !default;\n$form-label-font-style:                 null !default;\n$form-label-font-weight:                null !default;\n$form-label-color:                      null !default;\n// scss-docs-end form-label-variables\n\n// scss-docs-start form-input-variables\n$input-padding-y:                       $input-btn-padding-y !default;\n$input-padding-x:                       $input-btn-padding-x !default;\n$input-font-family:                     $input-btn-font-family !default;\n$input-font-size:                       $input-btn-font-size !default;\n$input-font-weight:                     $font-weight-base !default;\n$input-line-height:                     $input-btn-line-height !default;\n\n$input-padding-y-sm:                    $input-btn-padding-y-sm !default;\n$input-padding-x-sm:                    $input-btn-padding-x-sm !default;\n$input-font-size-sm:                    $input-btn-font-size-sm !default;\n\n$input-padding-y-lg:                    $input-btn-padding-y-lg !default;\n$input-padding-x-lg:                    $input-btn-padding-x-lg !default;\n$input-font-size-lg:                    $input-btn-font-size-lg !default;\n\n$input-bg:                              $body-bg !default;\n$input-disabled-bg:                     $gray-200 !default;\n$input-disabled-border-color:           null !default;\n\n$input-color:                           $body-color !default;\n$input-border-color:                    $gray-400 !default;\n$input-border-width:                    $input-btn-border-width !default;\n$input-box-shadow:                      $box-shadow-inset !default;\n\n$input-border-radius:                   $border-radius !default;\n$input-border-radius-sm:                $border-radius-sm !default;\n$input-border-radius-lg:                $border-radius-lg !default;\n\n$input-focus-bg:                        $input-bg !default;\n$input-focus-border-color:              tint-color($component-active-bg, 50%) !default;\n$input-focus-color:                     $input-color !default;\n$input-focus-width:                     $input-btn-focus-width !default;\n$input-focus-box-shadow:                $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color:               $gray-600 !default;\n$input-plaintext-color:                 $body-color !default;\n\n$input-height-border:                   $input-border-width * 2 !default;\n\n$input-height-inner:                    add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half:               add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter:            add($input-line-height * .25em, $input-padding-y * .5) !default;\n\n$input-height:                          add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm:                       add($input-line-height * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg:                       add($input-line-height * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition:                      border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-color-width:                      3rem !default;\n// scss-docs-end form-input-variables\n\n// scss-docs-start form-check-variables\n$form-check-input-width:                  1em !default;\n$form-check-min-height:                   $font-size-base * $line-height-base !default;\n$form-check-padding-start:                $form-check-input-width + .5em !default;\n$form-check-margin-bottom:                .125rem !default;\n$form-check-label-color:                  null !default;\n$form-check-label-cursor:                 null !default;\n$form-check-transition:                   null !default;\n\n$form-check-input-active-filter:          brightness(90%) !default;\n\n$form-check-input-bg:                     $input-bg !default;\n$form-check-input-border:                 1px solid rgba($black, .25) !default;\n$form-check-input-border-radius:          .25em !default;\n$form-check-radio-border-radius:          50% !default;\n$form-check-input-focus-border:           $input-focus-border-color !default;\n$form-check-input-focus-box-shadow:       $input-btn-focus-box-shadow !default;\n\n$form-check-input-checked-color:          $component-active-color !default;\n$form-check-input-checked-bg-color:       $component-active-bg !default;\n$form-check-input-checked-border-color:   $form-check-input-checked-bg-color !default;\n$form-check-input-checked-bg-image:       url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path fill='none' stroke='#{$form-check-input-checked-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/></svg>\") !default;\n$form-check-radio-checked-bg-image:       url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='2' fill='#{$form-check-input-checked-color}'/></svg>\") !default;\n\n$form-check-input-indeterminate-color:          $component-active-color !default;\n$form-check-input-indeterminate-bg-color:       $component-active-bg !default;\n$form-check-input-indeterminate-border-color:   $form-check-input-indeterminate-bg-color !default;\n$form-check-input-indeterminate-bg-image:       url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path fill='none' stroke='#{$form-check-input-indeterminate-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/></svg>\") !default;\n\n$form-check-input-disabled-opacity:        .5 !default;\n$form-check-label-disabled-opacity:        $form-check-input-disabled-opacity !default;\n$form-check-btn-check-disabled-opacity:    $btn-disabled-opacity !default;\n\n$form-check-inline-margin-end:    1rem !default;\n// scss-docs-end form-check-variables\n\n// scss-docs-start form-switch-variables\n$form-switch-color:               rgba($black, .25) !default;\n$form-switch-width:               2em !default;\n$form-switch-padding-start:       $form-switch-width + .5em !default;\n$form-switch-bg-image:            url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-color}'/></svg>\") !default;\n$form-switch-border-radius:       $form-switch-width !default;\n$form-switch-transition:          background-position .15s ease-in-out !default;\n\n$form-switch-focus-color:         $input-focus-border-color !default;\n$form-switch-focus-bg-image:      url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-focus-color}'/></svg>\") !default;\n\n$form-switch-checked-color:       $component-active-color !default;\n$form-switch-checked-bg-image:    url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-checked-color}'/></svg>\") !default;\n$form-switch-checked-bg-position: right center !default;\n// scss-docs-end form-switch-variables\n\n// scss-docs-start input-group-variables\n$input-group-addon-padding-y:           $input-padding-y !default;\n$input-group-addon-padding-x:           $input-padding-x !default;\n$input-group-addon-font-weight:         $input-font-weight !default;\n$input-group-addon-color:               $input-color !default;\n$input-group-addon-bg:                  $gray-200 !default;\n$input-group-addon-border-color:        $input-border-color !default;\n// scss-docs-end input-group-variables\n\n// scss-docs-start form-select-variables\n$form-select-padding-y:             $input-padding-y !default;\n$form-select-padding-x:             $input-padding-x !default;\n$form-select-font-family:           $input-font-family !default;\n$form-select-font-size:             $input-font-size !default;\n$form-select-indicator-padding:     $form-select-padding-x * 3 !default; // Extra padding for background-image\n$form-select-font-weight:           $input-font-weight !default;\n$form-select-line-height:           $input-line-height !default;\n$form-select-color:                 $input-color !default;\n$form-select-bg:                    $input-bg !default;\n$form-select-disabled-color:        null !default;\n$form-select-disabled-bg:           $gray-200 !default;\n$form-select-disabled-border-color: $input-disabled-border-color !default;\n$form-select-bg-position:           right $form-select-padding-x center !default;\n$form-select-bg-size:               16px 12px !default; // In pixels because image dimensions\n$form-select-indicator-color:       $gray-800 !default;\n$form-select-indicator:             url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-select-indicator-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/></svg>\") !default;\n\n$form-select-feedback-icon-padding-end: $form-select-padding-x * 2.5 + $form-select-indicator-padding !default;\n$form-select-feedback-icon-position:    center right $form-select-indicator-padding !default;\n$form-select-feedback-icon-size:        $input-height-inner-half $input-height-inner-half !default;\n\n$form-select-border-width:        $input-border-width !default;\n$form-select-border-color:        $input-border-color !default;\n$form-select-border-radius:       $input-border-radius !default;\n$form-select-box-shadow:          $box-shadow-inset !default;\n\n$form-select-focus-border-color:  $input-focus-border-color !default;\n$form-select-focus-width:         $input-focus-width !default;\n$form-select-focus-box-shadow:    0 0 0 $form-select-focus-width $input-btn-focus-color !default;\n\n$form-select-padding-y-sm:        $input-padding-y-sm !default;\n$form-select-padding-x-sm:        $input-padding-x-sm !default;\n$form-select-font-size-sm:        $input-font-size-sm !default;\n$form-select-border-radius-sm:    $input-border-radius-sm !default;\n\n$form-select-padding-y-lg:        $input-padding-y-lg !default;\n$form-select-padding-x-lg:        $input-padding-x-lg !default;\n$form-select-font-size-lg:        $input-font-size-lg !default;\n$form-select-border-radius-lg:    $input-border-radius-lg !default;\n\n$form-select-transition:          $input-transition !default;\n// scss-docs-end form-select-variables\n\n// scss-docs-start form-range-variables\n$form-range-track-width:          100% !default;\n$form-range-track-height:         .5rem !default;\n$form-range-track-cursor:         pointer !default;\n$form-range-track-bg:             $gray-300 !default;\n$form-range-track-border-radius:  1rem !default;\n$form-range-track-box-shadow:     $box-shadow-inset !default;\n\n$form-range-thumb-width:                   1rem !default;\n$form-range-thumb-height:                  $form-range-thumb-width !default;\n$form-range-thumb-bg:                      $component-active-bg !default;\n$form-range-thumb-border:                  0 !default;\n$form-range-thumb-border-radius:           1rem !default;\n$form-range-thumb-box-shadow:              0 .1rem .25rem rgba($black, .1) !default;\n$form-range-thumb-focus-box-shadow:        0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$form-range-thumb-focus-box-shadow-width:  $input-focus-width !default; // For focus box shadow issue in Edge\n$form-range-thumb-active-bg:               tint-color($component-active-bg, 70%) !default;\n$form-range-thumb-disabled-bg:             $gray-500 !default;\n$form-range-thumb-transition:              background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n// scss-docs-end form-range-variables\n\n// scss-docs-start form-file-variables\n$form-file-button-color:          $input-color !default;\n$form-file-button-bg:             $input-group-addon-bg !default;\n$form-file-button-hover-bg:       shade-color($form-file-button-bg, 5%) !default;\n// scss-docs-end form-file-variables\n\n// scss-docs-start form-floating-variables\n$form-floating-height:            add(3.5rem, $input-height-border) !default;\n$form-floating-line-height:       1.25 !default;\n$form-floating-padding-x:         $input-padding-x !default;\n$form-floating-padding-y:         1rem !default;\n$form-floating-input-padding-t:   1.625rem !default;\n$form-floating-input-padding-b:   .625rem !default;\n$form-floating-label-opacity:     .65 !default;\n$form-floating-label-transform:   scale(.85) translateY(-.5rem) translateX(.15rem) !default;\n$form-floating-transition:        opacity .1s ease-in-out, transform .1s ease-in-out !default;\n// scss-docs-end form-floating-variables\n\n// Form validation\n\n// scss-docs-start form-feedback-variables\n$form-feedback-margin-top:          $form-text-margin-top !default;\n$form-feedback-font-size:           $form-text-font-size !default;\n$form-feedback-font-style:          $form-text-font-style !default;\n$form-feedback-valid-color:         $success !default;\n$form-feedback-invalid-color:       $danger !default;\n\n$form-feedback-icon-valid-color:    $form-feedback-valid-color !default;\n$form-feedback-icon-valid:          url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>\") !default;\n$form-feedback-icon-invalid-color:  $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid:        url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>\") !default;\n// scss-docs-end form-feedback-variables\n\n// scss-docs-start form-validation-states\n$form-validation-states: (\n  \"valid\": (\n    \"color\": $form-feedback-valid-color,\n    \"icon\": $form-feedback-icon-valid\n  ),\n  \"invalid\": (\n    \"color\": $form-feedback-invalid-color,\n    \"icon\": $form-feedback-icon-invalid\n  )\n) !default;\n// scss-docs-end form-validation-states\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n// scss-docs-start zindex-stack\n$zindex-dropdown:                   1000 !default;\n$zindex-sticky:                     1020 !default;\n$zindex-fixed:                      1030 !default;\n$zindex-offcanvas-backdrop:         1040 !default;\n$zindex-offcanvas:                  1045 !default;\n$zindex-modal-backdrop:             1050 !default;\n$zindex-modal:                      1055 !default;\n$zindex-popover:                    1070 !default;\n$zindex-tooltip:                    1080 !default;\n// scss-docs-end zindex-stack\n\n\n// Navs\n\n// scss-docs-start nav-variables\n$nav-link-padding-y:                .5rem !default;\n$nav-link-padding-x:                1rem !default;\n$nav-link-font-size:                null !default;\n$nav-link-font-weight:              null !default;\n$nav-link-color:                    $link-color !default;\n$nav-link-hover-color:              $link-hover-color !default;\n$nav-link-transition:               color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default;\n$nav-link-disabled-color:           $gray-600 !default;\n\n$nav-tabs-border-color:             $gray-300 !default;\n$nav-tabs-border-width:             $border-width !default;\n$nav-tabs-border-radius:            $border-radius !default;\n$nav-tabs-link-hover-border-color:  $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color:        $gray-700 !default;\n$nav-tabs-link-active-bg:           $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius:           $border-radius !default;\n$nav-pills-link-active-color:       $component-active-color !default;\n$nav-pills-link-active-bg:          $component-active-bg !default;\n// scss-docs-end nav-variables\n\n\n// Navbar\n\n// scss-docs-start navbar-variables\n$navbar-padding-y:                  $spacer * .5 !default;\n$navbar-padding-x:                  null !default;\n\n$navbar-nav-link-padding-x:         .5rem !default;\n\n$navbar-brand-font-size:            $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height:                   $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height:               $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y:            ($nav-link-height - $navbar-brand-height) * .5 !default;\n$navbar-brand-margin-end:           1rem !default;\n\n$navbar-toggler-padding-y:          .25rem !default;\n$navbar-toggler-padding-x:          .75rem !default;\n$navbar-toggler-font-size:          $font-size-lg !default;\n$navbar-toggler-border-radius:      $btn-border-radius !default;\n$navbar-toggler-focus-width:        $btn-focus-width !default;\n$navbar-toggler-transition:         box-shadow .15s ease-in-out !default;\n// scss-docs-end navbar-variables\n\n// scss-docs-start navbar-theme-variables\n$navbar-dark-color:                 rgba($white, .55) !default;\n$navbar-dark-hover-color:           rgba($white, .75) !default;\n$navbar-dark-active-color:          $white !default;\n$navbar-dark-disabled-color:        rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg:       url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-dark-toggler-border-color:  rgba($white, .1) !default;\n\n$navbar-light-color:                rgba($black, .55) !default;\n$navbar-light-hover-color:          rgba($black, .7) !default;\n$navbar-light-active-color:         rgba($black, .9) !default;\n$navbar-light-disabled-color:       rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg:      url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color:                $navbar-light-active-color !default;\n$navbar-light-brand-hover-color:          $navbar-light-active-color !default;\n$navbar-dark-brand-color:                 $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color:           $navbar-dark-active-color !default;\n// scss-docs-end navbar-theme-variables\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n// scss-docs-start dropdown-variables\n$dropdown-min-width:                10rem !default;\n$dropdown-padding-x:                0 !default;\n$dropdown-padding-y:                .5rem !default;\n$dropdown-spacer:                   .125rem !default;\n$dropdown-font-size:                $font-size-base !default;\n$dropdown-color:                    $body-color !default;\n$dropdown-bg:                       $white !default;\n$dropdown-border-color:             rgba($black, .15) !default;\n$dropdown-border-radius:            $border-radius !default;\n$dropdown-border-width:             $border-width !default;\n$dropdown-inner-border-radius:      subtract($dropdown-border-radius, $dropdown-border-width) !default;\n$dropdown-divider-bg:               $dropdown-border-color !default;\n$dropdown-divider-margin-y:         $spacer * .5 !default;\n$dropdown-box-shadow:               $box-shadow !default;\n\n$dropdown-link-color:               $gray-900 !default;\n$dropdown-link-hover-color:         shade-color($dropdown-link-color, 10%) !default;\n$dropdown-link-hover-bg:            $gray-200 !default;\n\n$dropdown-link-active-color:        $component-active-color !default;\n$dropdown-link-active-bg:           $component-active-bg !default;\n\n$dropdown-link-disabled-color:      $gray-500 !default;\n\n$dropdown-item-padding-y:           $spacer * .25 !default;\n$dropdown-item-padding-x:           $spacer !default;\n\n$dropdown-header-color:             $gray-600 !default;\n$dropdown-header-padding:           $dropdown-padding-y $dropdown-item-padding-x !default;\n// scss-docs-end dropdown-variables\n\n// scss-docs-start dropdown-dark-variables\n$dropdown-dark-color:               $gray-300 !default;\n$dropdown-dark-bg:                  $gray-800 !default;\n$dropdown-dark-border-color:        $dropdown-border-color !default;\n$dropdown-dark-divider-bg:          $dropdown-divider-bg !default;\n$dropdown-dark-box-shadow:          null !default;\n$dropdown-dark-link-color:          $dropdown-dark-color !default;\n$dropdown-dark-link-hover-color:    $white !default;\n$dropdown-dark-link-hover-bg:       rgba($white, .15) !default;\n$dropdown-dark-link-active-color:   $dropdown-link-active-color !default;\n$dropdown-dark-link-active-bg:      $dropdown-link-active-bg !default;\n$dropdown-dark-link-disabled-color: $gray-500 !default;\n$dropdown-dark-header-color:        $gray-500 !default;\n// scss-docs-end dropdown-dark-variables\n\n\n// Pagination\n\n// scss-docs-start pagination-variables\n$pagination-padding-y:              .375rem !default;\n$pagination-padding-x:              .75rem !default;\n$pagination-padding-y-sm:           .25rem !default;\n$pagination-padding-x-sm:           .5rem !default;\n$pagination-padding-y-lg:           .75rem !default;\n$pagination-padding-x-lg:           1.5rem !default;\n\n$pagination-color:                  $link-color !default;\n$pagination-bg:                     $white !default;\n$pagination-border-width:           $border-width !default;\n$pagination-border-radius:          $border-radius !default;\n$pagination-margin-start:           -$pagination-border-width !default;\n$pagination-border-color:           $gray-300 !default;\n\n$pagination-focus-color:            $link-hover-color !default;\n$pagination-focus-bg:               $gray-200 !default;\n$pagination-focus-box-shadow:       $input-btn-focus-box-shadow !default;\n$pagination-focus-outline:          0 !default;\n\n$pagination-hover-color:            $link-hover-color !default;\n$pagination-hover-bg:               $gray-200 !default;\n$pagination-hover-border-color:     $gray-300 !default;\n\n$pagination-active-color:           $component-active-color !default;\n$pagination-active-bg:              $component-active-bg !default;\n$pagination-active-border-color:    $pagination-active-bg !default;\n\n$pagination-disabled-color:         $gray-600 !default;\n$pagination-disabled-bg:            $white !default;\n$pagination-disabled-border-color:  $gray-300 !default;\n\n$pagination-transition:              color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$pagination-border-radius-sm:       $border-radius-sm !default;\n$pagination-border-radius-lg:       $border-radius-lg !default;\n// scss-docs-end pagination-variables\n\n\n// Placeholders\n\n// scss-docs-start placeholders\n$placeholder-opacity-max:           .5 !default;\n$placeholder-opacity-min:           .2 !default;\n// scss-docs-end placeholders\n\n// Cards\n\n// scss-docs-start card-variables\n$card-spacer-y:                     $spacer !default;\n$card-spacer-x:                     $spacer !default;\n$card-title-spacer-y:               $spacer * .5 !default;\n$card-border-width:                 $border-width !default;\n$card-border-color:                 rgba($black, .125) !default;\n$card-border-radius:                $border-radius !default;\n$card-box-shadow:                   null !default;\n$card-inner-border-radius:          subtract($card-border-radius, $card-border-width) !default;\n$card-cap-padding-y:                $card-spacer-y * .5 !default;\n$card-cap-padding-x:                $card-spacer-x !default;\n$card-cap-bg:                       rgba($black, .03) !default;\n$card-cap-color:                    null !default;\n$card-height:                       null !default;\n$card-color:                        null !default;\n$card-bg:                           $white !default;\n$card-img-overlay-padding:          $spacer !default;\n$card-group-margin:                 $grid-gutter-width * .5 !default;\n// scss-docs-end card-variables\n\n// Accordion\n\n// scss-docs-start accordion-variables\n$accordion-padding-y:                     1rem !default;\n$accordion-padding-x:                     1.25rem !default;\n$accordion-color:                         $body-color !default;\n$accordion-bg:                            $body-bg !default;\n$accordion-border-width:                  $border-width !default;\n$accordion-border-color:                  rgba($black, .125) !default;\n$accordion-border-radius:                 $border-radius !default;\n$accordion-inner-border-radius:           subtract($accordion-border-radius, $accordion-border-width) !default;\n\n$accordion-body-padding-y:                $accordion-padding-y !default;\n$accordion-body-padding-x:                $accordion-padding-x !default;\n\n$accordion-button-padding-y:              $accordion-padding-y !default;\n$accordion-button-padding-x:              $accordion-padding-x !default;\n$accordion-button-color:                  $accordion-color !default;\n$accordion-button-bg:                     $accordion-bg !default;\n$accordion-transition:                    $btn-transition, border-radius .15s ease !default;\n$accordion-button-active-bg:              tint-color($component-active-bg, 90%) !default;\n$accordion-button-active-color:           shade-color($primary, 10%) !default;\n\n$accordion-button-focus-border-color:     $input-focus-border-color !default;\n$accordion-button-focus-box-shadow:       $btn-focus-box-shadow !default;\n\n$accordion-icon-width:                    1.25rem !default;\n$accordion-icon-color:                    $accordion-button-color !default;\n$accordion-icon-active-color:             $accordion-button-active-color !default;\n$accordion-icon-transition:               transform .2s ease-in-out !default;\n$accordion-icon-transform:                rotate(-180deg) !default;\n\n$accordion-button-icon:         url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>\") !default;\n$accordion-button-active-icon:  url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>\") !default;\n// scss-docs-end accordion-variables\n\n// Tooltips\n\n// scss-docs-start tooltip-variables\n$tooltip-font-size:                 $font-size-sm !default;\n$tooltip-max-width:                 200px !default;\n$tooltip-color:                     $white !default;\n$tooltip-bg:                        $black !default;\n$tooltip-border-radius:             $border-radius !default;\n$tooltip-opacity:                   .9 !default;\n$tooltip-padding-y:                 $spacer * .25 !default;\n$tooltip-padding-x:                 $spacer * .5 !default;\n$tooltip-margin:                    0 !default;\n\n$tooltip-arrow-width:               .8rem !default;\n$tooltip-arrow-height:              .4rem !default;\n$tooltip-arrow-color:               $tooltip-bg !default;\n// scss-docs-end tooltip-variables\n\n// Form tooltips must come after regular tooltips\n// scss-docs-start tooltip-feedback-variables\n$form-feedback-tooltip-padding-y:     $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x:     $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size:     $tooltip-font-size !default;\n$form-feedback-tooltip-line-height:   null !default;\n$form-feedback-tooltip-opacity:       $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n// scss-docs-end tooltip-feedback-variables\n\n\n// Popovers\n\n// scss-docs-start popover-variables\n$popover-font-size:                 $font-size-sm !default;\n$popover-bg:                        $white !default;\n$popover-max-width:                 276px !default;\n$popover-border-width:              $border-width !default;\n$popover-border-color:              rgba($black, .2) !default;\n$popover-border-radius:             $border-radius-lg !default;\n$popover-inner-border-radius:       subtract($popover-border-radius, $popover-border-width) !default;\n$popover-box-shadow:                $box-shadow !default;\n\n$popover-header-bg:                 shade-color($popover-bg, 6%) !default;\n$popover-header-color:              $headings-color !default;\n$popover-header-padding-y:          .5rem !default;\n$popover-header-padding-x:          $spacer !default;\n\n$popover-body-color:                $body-color !default;\n$popover-body-padding-y:            $spacer !default;\n$popover-body-padding-x:            $spacer !default;\n\n$popover-arrow-width:               1rem !default;\n$popover-arrow-height:              .5rem !default;\n$popover-arrow-color:               $popover-bg !default;\n\n$popover-arrow-outer-color:         fade-in($popover-border-color, .05) !default;\n// scss-docs-end popover-variables\n\n\n// Toasts\n\n// scss-docs-start toast-variables\n$toast-max-width:                   350px !default;\n$toast-padding-x:                   .75rem !default;\n$toast-padding-y:                   .5rem !default;\n$toast-font-size:                   .875rem !default;\n$toast-color:                       null !default;\n$toast-background-color:            rgba($white, .85) !default;\n$toast-border-width:                1px !default;\n$toast-border-color:                rgba($black, .1) !default;\n$toast-border-radius:               $border-radius !default;\n$toast-box-shadow:                  $box-shadow !default;\n$toast-spacing:                     $container-padding-x !default;\n\n$toast-header-color:                $gray-600 !default;\n$toast-header-background-color:     rgba($white, .85) !default;\n$toast-header-border-color:         rgba($black, .05) !default;\n// scss-docs-end toast-variables\n\n\n// Badges\n\n// scss-docs-start badge-variables\n$badge-font-size:                   .75em !default;\n$badge-font-weight:                 $font-weight-bold !default;\n$badge-color:                       $white !default;\n$badge-padding-y:                   .35em !default;\n$badge-padding-x:                   .65em !default;\n$badge-border-radius:               $border-radius !default;\n// scss-docs-end badge-variables\n\n\n// Modals\n\n// scss-docs-start modal-variables\n$modal-inner-padding:               $spacer !default;\n\n$modal-footer-margin-between:       .5rem !default;\n\n$modal-dialog-margin:               .5rem !default;\n$modal-dialog-margin-y-sm-up:       1.75rem !default;\n\n$modal-title-line-height:           $line-height-base !default;\n\n$modal-content-color:               null !default;\n$modal-content-bg:                  $white !default;\n$modal-content-border-color:        rgba($black, .2) !default;\n$modal-content-border-width:        $border-width !default;\n$modal-content-border-radius:       $border-radius-lg !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs:       $box-shadow-sm !default;\n$modal-content-box-shadow-sm-up:    $box-shadow !default;\n\n$modal-backdrop-bg:                 $black !default;\n$modal-backdrop-opacity:            .5 !default;\n$modal-header-border-color:         $border-color !default;\n$modal-footer-border-color:         $modal-header-border-color !default;\n$modal-header-border-width:         $modal-content-border-width !default;\n$modal-footer-border-width:         $modal-header-border-width !default;\n$modal-header-padding-y:            $modal-inner-padding !default;\n$modal-header-padding-x:            $modal-inner-padding !default;\n$modal-header-padding:              $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-sm:                          300px !default;\n$modal-md:                          500px !default;\n$modal-lg:                          800px !default;\n$modal-xl:                          1140px !default;\n\n$modal-fade-transform:              translate(0, -50px) !default;\n$modal-show-transform:              none !default;\n$modal-transition:                  transform .3s ease-out !default;\n$modal-scale-transform:             scale(1.02) !default;\n// scss-docs-end modal-variables\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n// scss-docs-start alert-variables\n$alert-padding-y:               $spacer !default;\n$alert-padding-x:               $spacer !default;\n$alert-margin-bottom:           1rem !default;\n$alert-border-radius:           $border-radius !default;\n$alert-link-font-weight:        $font-weight-bold !default;\n$alert-border-width:            $border-width !default;\n$alert-bg-scale:                -80% !default;\n$alert-border-scale:            -70% !default;\n$alert-color-scale:             40% !default;\n$alert-dismissible-padding-r:   $alert-padding-x * 3 !default; // 3x covers width of x plus default padding on either side\n// scss-docs-end alert-variables\n\n\n// Progress bars\n\n// scss-docs-start progress-variables\n$progress-height:                   1rem !default;\n$progress-font-size:                $font-size-base * .75 !default;\n$progress-bg:                       $gray-200 !default;\n$progress-border-radius:            $border-radius !default;\n$progress-box-shadow:               $box-shadow-inset !default;\n$progress-bar-color:                $white !default;\n$progress-bar-bg:                   $primary !default;\n$progress-bar-animation-timing:     1s linear infinite !default;\n$progress-bar-transition:           width .6s ease !default;\n// scss-docs-end progress-variables\n\n\n// List group\n\n// scss-docs-start list-group-variables\n$list-group-color:                  $gray-900 !default;\n$list-group-bg:                     $white !default;\n$list-group-border-color:           rgba($black, .125) !default;\n$list-group-border-width:           $border-width !default;\n$list-group-border-radius:          $border-radius !default;\n\n$list-group-item-padding-y:         $spacer * .5 !default;\n$list-group-item-padding-x:         $spacer !default;\n$list-group-item-bg-scale:          -80% !default;\n$list-group-item-color-scale:       40% !default;\n\n$list-group-hover-bg:               $gray-100 !default;\n$list-group-active-color:           $component-active-color !default;\n$list-group-active-bg:              $component-active-bg !default;\n$list-group-active-border-color:    $list-group-active-bg !default;\n\n$list-group-disabled-color:         $gray-600 !default;\n$list-group-disabled-bg:            $list-group-bg !default;\n\n$list-group-action-color:           $gray-700 !default;\n$list-group-action-hover-color:     $list-group-action-color !default;\n\n$list-group-action-active-color:    $body-color !default;\n$list-group-action-active-bg:       $gray-200 !default;\n// scss-docs-end list-group-variables\n\n\n// Image thumbnails\n\n// scss-docs-start thumbnail-variables\n$thumbnail-padding:                 .25rem !default;\n$thumbnail-bg:                      $body-bg !default;\n$thumbnail-border-width:            $border-width !default;\n$thumbnail-border-color:            $gray-300 !default;\n$thumbnail-border-radius:           $border-radius !default;\n$thumbnail-box-shadow:              $box-shadow-sm !default;\n// scss-docs-end thumbnail-variables\n\n\n// Figures\n\n// scss-docs-start figure-variables\n$figure-caption-font-size:          $small-font-size !default;\n$figure-caption-color:              $gray-600 !default;\n// scss-docs-end figure-variables\n\n\n// Breadcrumbs\n\n// scss-docs-start breadcrumb-variables\n$breadcrumb-font-size:              null !default;\n$breadcrumb-padding-y:              0 !default;\n$breadcrumb-padding-x:              0 !default;\n$breadcrumb-item-padding-x:         .5rem !default;\n$breadcrumb-margin-bottom:          1rem !default;\n$breadcrumb-bg:                     null !default;\n$breadcrumb-divider-color:          $gray-600 !default;\n$breadcrumb-active-color:           $gray-600 !default;\n$breadcrumb-divider:                quote(\"/\") !default;\n$breadcrumb-divider-flipped:        $breadcrumb-divider !default;\n$breadcrumb-border-radius:          null !default;\n// scss-docs-end breadcrumb-variables\n\n// Carousel\n\n// scss-docs-start carousel-variables\n$carousel-control-color:             $white !default;\n$carousel-control-width:             15% !default;\n$carousel-control-opacity:           .5 !default;\n$carousel-control-hover-opacity:     .9 !default;\n$carousel-control-transition:        opacity .15s ease !default;\n\n$carousel-indicator-width:           30px !default;\n$carousel-indicator-height:          3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer:          3px !default;\n$carousel-indicator-opacity:         .5 !default;\n$carousel-indicator-active-bg:       $white !default;\n$carousel-indicator-active-opacity:  1 !default;\n$carousel-indicator-transition:      opacity .6s ease !default;\n\n$carousel-caption-width:             70% !default;\n$carousel-caption-color:             $white !default;\n$carousel-caption-padding-y:         1.25rem !default;\n$carousel-caption-spacer:            1.25rem !default;\n\n$carousel-control-icon-width:        2rem !default;\n\n$carousel-control-prev-icon-bg:      url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/></svg>\") !default;\n$carousel-control-next-icon-bg:      url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/></svg>\") !default;\n\n$carousel-transition-duration:       .6s !default;\n$carousel-transition:                transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n$carousel-dark-indicator-active-bg:  $black !default;\n$carousel-dark-caption-color:        $black !default;\n$carousel-dark-control-icon-filter:  invert(1) grayscale(100) !default;\n// scss-docs-end carousel-variables\n\n\n// Spinners\n\n// scss-docs-start spinner-variables\n$spinner-width:           2rem !default;\n$spinner-height:          $spinner-width !default;\n$spinner-vertical-align:  -.125em !default;\n$spinner-border-width:    .25em !default;\n$spinner-animation-speed: .75s !default;\n\n$spinner-width-sm:        1rem !default;\n$spinner-height-sm:       $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n// scss-docs-end spinner-variables\n\n\n// Close\n\n// scss-docs-start close-variables\n$btn-close-width:            1em !default;\n$btn-close-height:           $btn-close-width !default;\n$btn-close-padding-x:        .25em !default;\n$btn-close-padding-y:        $btn-close-padding-x !default;\n$btn-close-color:            $black !default;\n$btn-close-bg:               url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$btn-close-color}'><path d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/></svg>\") !default;\n$btn-close-focus-shadow:     $input-btn-focus-box-shadow !default;\n$btn-close-opacity:          .5 !default;\n$btn-close-hover-opacity:    .75 !default;\n$btn-close-focus-opacity:    1 !default;\n$btn-close-disabled-opacity: .25 !default;\n$btn-close-white-filter:     invert(1) grayscale(100%) brightness(200%) !default;\n// scss-docs-end close-variables\n\n\n// Offcanvas\n\n// scss-docs-start offcanvas-variables\n$offcanvas-padding-y:               $modal-inner-padding !default;\n$offcanvas-padding-x:               $modal-inner-padding !default;\n$offcanvas-horizontal-width:        400px !default;\n$offcanvas-vertical-height:         30vh !default;\n$offcanvas-transition-duration:     .3s !default;\n$offcanvas-border-color:            $modal-content-border-color !default;\n$offcanvas-border-width:            $modal-content-border-width !default;\n$offcanvas-title-line-height:       $modal-title-line-height !default;\n$offcanvas-bg-color:                $modal-content-bg !default;\n$offcanvas-color:                   $modal-content-color !default;\n$offcanvas-box-shadow:              $modal-content-box-shadow-xs !default;\n$offcanvas-backdrop-bg:             $modal-backdrop-bg !default;\n$offcanvas-backdrop-opacity:        $modal-backdrop-opacity !default;\n// scss-docs-end offcanvas-variables\n\n// Code\n\n$code-font-size:                    $small-font-size !default;\n$code-color:                        $pink !default;\n\n$kbd-padding-y:                     .2rem !default;\n$kbd-padding-x:                     .4rem !default;\n$kbd-font-size:                     $code-font-size !default;\n$kbd-color:                         $white !default;\n$kbd-bg:                            $gray-900 !default;\n\n$pre-color:                         null !default;\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/bootstrap.scss",
    "content": "/*!\n * Bootstrap v5.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n// scss-docs-start import-stack\n// Configuration\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"utilities\";\n\n// Layout & components\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"containers\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"accordion\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"alert\";\n@import \"progress\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"offcanvas\";\n@import \"placeholders\";\n\n// Helpers\n@import \"helpers\";\n\n// Utilities\n@import \"utilities/api\";\n// scss-docs-end import-stack\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/forms/_floating-labels.scss",
    "content": ".form-floating {\n  position: relative;\n\n  > .form-control,\n  > .form-select {\n    height: $form-floating-height;\n    line-height: $form-floating-line-height;\n  }\n\n  > label {\n    position: absolute;\n    top: 0;\n    left: 0;\n    height: 100%; // allow textareas\n    padding: $form-floating-padding-y $form-floating-padding-x;\n    pointer-events: none;\n    border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model\n    transform-origin: 0 0;\n    @include transition($form-floating-transition);\n  }\n\n  // stylelint-disable no-duplicate-selectors\n  > .form-control {\n    padding: $form-floating-padding-y $form-floating-padding-x;\n\n    &::placeholder {\n      color: transparent;\n    }\n\n    &:focus,\n    &:not(:placeholder-shown) {\n      padding-top: $form-floating-input-padding-t;\n      padding-bottom: $form-floating-input-padding-b;\n    }\n    // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped\n    &:-webkit-autofill {\n      padding-top: $form-floating-input-padding-t;\n      padding-bottom: $form-floating-input-padding-b;\n    }\n  }\n\n  > .form-select {\n    padding-top: $form-floating-input-padding-t;\n    padding-bottom: $form-floating-input-padding-b;\n  }\n\n  > .form-control:focus,\n  > .form-control:not(:placeholder-shown),\n  > .form-select {\n    ~ label {\n      opacity: $form-floating-label-opacity;\n      transform: $form-floating-label-transform;\n    }\n  }\n  // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped\n  > .form-control:-webkit-autofill {\n    ~ label {\n      opacity: $form-floating-label-opacity;\n      transform: $form-floating-label-transform;\n    }\n  }\n  // stylelint-enable no-duplicate-selectors\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-check.scss",
    "content": "//\n// Check/radio\n//\n\n.form-check {\n  display: block;\n  min-height: $form-check-min-height;\n  padding-left: $form-check-padding-start;\n  margin-bottom: $form-check-margin-bottom;\n\n  .form-check-input {\n    float: left;\n    margin-left: $form-check-padding-start * -1;\n  }\n}\n\n.form-check-input {\n  width: $form-check-input-width;\n  height: $form-check-input-width;\n  margin-top: ($line-height-base - $form-check-input-width) * .5; // line-height minus check height\n  vertical-align: top;\n  background-color: $form-check-input-bg;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n  border: $form-check-input-border;\n  appearance: none;\n  color-adjust: exact; // Keep themed appearance for print\n  @include transition($form-check-transition);\n\n  &[type=\"checkbox\"] {\n    @include border-radius($form-check-input-border-radius);\n  }\n\n  &[type=\"radio\"] {\n    // stylelint-disable-next-line property-disallowed-list\n    border-radius: $form-check-radio-border-radius;\n  }\n\n  &:active {\n    filter: $form-check-input-active-filter;\n  }\n\n  &:focus {\n    border-color: $form-check-input-focus-border;\n    outline: 0;\n    box-shadow: $form-check-input-focus-box-shadow;\n  }\n\n  &:checked {\n    background-color: $form-check-input-checked-bg-color;\n    border-color: $form-check-input-checked-border-color;\n\n    &[type=\"checkbox\"] {\n      @if $enable-gradients {\n        background-image: escape-svg($form-check-input-checked-bg-image), var(--#{$variable-prefix}gradient);\n      } @else {\n        background-image: escape-svg($form-check-input-checked-bg-image);\n      }\n    }\n\n    &[type=\"radio\"] {\n      @if $enable-gradients {\n        background-image: escape-svg($form-check-radio-checked-bg-image), var(--#{$variable-prefix}gradient);\n      } @else {\n        background-image: escape-svg($form-check-radio-checked-bg-image);\n      }\n    }\n  }\n\n  &[type=\"checkbox\"]:indeterminate {\n    background-color: $form-check-input-indeterminate-bg-color;\n    border-color: $form-check-input-indeterminate-border-color;\n\n    @if $enable-gradients {\n      background-image: escape-svg($form-check-input-indeterminate-bg-image), var(--#{$variable-prefix}gradient);\n    } @else {\n      background-image: escape-svg($form-check-input-indeterminate-bg-image);\n    }\n  }\n\n  &:disabled {\n    pointer-events: none;\n    filter: none;\n    opacity: $form-check-input-disabled-opacity;\n  }\n\n  // Use disabled attribute in addition of :disabled pseudo-class\n  // See: https://github.com/twbs/bootstrap/issues/28247\n  &[disabled],\n  &:disabled {\n    ~ .form-check-label {\n      opacity: $form-check-label-disabled-opacity;\n    }\n  }\n}\n\n.form-check-label {\n  color: $form-check-label-color;\n  cursor: $form-check-label-cursor;\n}\n\n//\n// Switch\n//\n\n.form-switch {\n  padding-left: $form-switch-padding-start;\n\n  .form-check-input {\n    width: $form-switch-width;\n    margin-left: $form-switch-padding-start * -1;\n    background-image: escape-svg($form-switch-bg-image);\n    background-position: left center;\n    @include border-radius($form-switch-border-radius);\n    @include transition($form-switch-transition);\n\n    &:focus {\n      background-image: escape-svg($form-switch-focus-bg-image);\n    }\n\n    &:checked {\n      background-position: $form-switch-checked-bg-position;\n\n      @if $enable-gradients {\n        background-image: escape-svg($form-switch-checked-bg-image), var(--#{$variable-prefix}gradient);\n      } @else {\n        background-image: escape-svg($form-switch-checked-bg-image);\n      }\n    }\n  }\n}\n\n.form-check-inline {\n  display: inline-block;\n  margin-right: $form-check-inline-margin-end;\n}\n\n.btn-check {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n\n  &[disabled],\n  &:disabled {\n    + .btn {\n      pointer-events: none;\n      filter: none;\n      opacity: $form-check-btn-check-disabled-opacity;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-control.scss",
    "content": "//\n// General form controls (plus a few specific high-level interventions)\n//\n\n.form-control {\n  display: block;\n  width: 100%;\n  padding: $input-padding-y $input-padding-x;\n  font-family: $input-font-family;\n  @include font-size($input-font-size);\n  font-weight: $input-font-weight;\n  line-height: $input-line-height;\n  color: $input-color;\n  background-color: $input-bg;\n  background-clip: padding-box;\n  border: $input-border-width solid $input-border-color;\n  appearance: none; // Fix appearance for date inputs in Safari\n\n  // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.\n  @include border-radius($input-border-radius, 0);\n\n  @include box-shadow($input-box-shadow);\n  @include transition($input-transition);\n\n  &[type=\"file\"] {\n    overflow: hidden; // prevent pseudo element button overlap\n\n    &:not(:disabled):not([readonly]) {\n      cursor: pointer;\n    }\n  }\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  &:focus {\n    color: $input-focus-color;\n    background-color: $input-focus-bg;\n    border-color: $input-focus-border-color;\n    outline: 0;\n    @if $enable-shadows {\n      @include box-shadow($input-box-shadow, $input-focus-box-shadow);\n    } @else {\n      // Avoid using mixin so we can pass custom focus shadow properly\n      box-shadow: $input-focus-box-shadow;\n    }\n  }\n\n  // Add some height to date inputs on iOS\n  // https://github.com/twbs/bootstrap/issues/23307\n  // TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved\n  &::-webkit-date-and-time-value {\n    // Multiply line-height by 1em if it has no unit\n    height: if(unit($input-line-height) == \"\", $input-line-height * 1em, $input-line-height);\n  }\n\n  // Placeholder\n  &::placeholder {\n    color: $input-placeholder-color;\n    // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n    opacity: 1;\n  }\n\n  // Disabled and read-only inputs\n  //\n  // HTML5 says that controls under a fieldset > legend:first-child won't be\n  // disabled if the fieldset is disabled. Due to implementation difficulty, we\n  // don't honor that edge case; we style them as disabled anyway.\n  &:disabled,\n  &[readonly] {\n    background-color: $input-disabled-bg;\n    border-color: $input-disabled-border-color;\n    // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n    opacity: 1;\n  }\n\n  // File input buttons theming\n  &::file-selector-button {\n    padding: $input-padding-y $input-padding-x;\n    margin: (-$input-padding-y) (-$input-padding-x);\n    margin-inline-end: $input-padding-x;\n    color: $form-file-button-color;\n    @include gradient-bg($form-file-button-bg);\n    pointer-events: none;\n    border-color: inherit;\n    border-style: solid;\n    border-width: 0;\n    border-inline-end-width: $input-border-width;\n    border-radius: 0; // stylelint-disable-line property-disallowed-list\n    @include transition($btn-transition);\n  }\n\n  &:hover:not(:disabled):not([readonly])::file-selector-button {\n    background-color: $form-file-button-hover-bg;\n  }\n\n  &::-webkit-file-upload-button {\n    padding: $input-padding-y $input-padding-x;\n    margin: (-$input-padding-y) (-$input-padding-x);\n    margin-inline-end: $input-padding-x;\n    color: $form-file-button-color;\n    @include gradient-bg($form-file-button-bg);\n    pointer-events: none;\n    border-color: inherit;\n    border-style: solid;\n    border-width: 0;\n    border-inline-end-width: $input-border-width;\n    border-radius: 0; // stylelint-disable-line property-disallowed-list\n    @include transition($btn-transition);\n  }\n\n  &:hover:not(:disabled):not([readonly])::-webkit-file-upload-button {\n    background-color: $form-file-button-hover-bg;\n  }\n}\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n  display: block;\n  width: 100%;\n  padding: $input-padding-y 0;\n  margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n  line-height: $input-line-height;\n  color: $input-plaintext-color;\n  background-color: transparent;\n  border: solid transparent;\n  border-width: $input-border-width 0;\n\n  &.form-control-sm,\n  &.form-control-lg {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// Repeated in `_input_group.scss` to avoid Sass extend issues.\n\n.form-control-sm {\n  min-height: $input-height-sm;\n  padding: $input-padding-y-sm $input-padding-x-sm;\n  @include font-size($input-font-size-sm);\n  @include border-radius($input-border-radius-sm);\n\n  &::file-selector-button {\n    padding: $input-padding-y-sm $input-padding-x-sm;\n    margin: (-$input-padding-y-sm) (-$input-padding-x-sm);\n    margin-inline-end: $input-padding-x-sm;\n  }\n\n  &::-webkit-file-upload-button {\n    padding: $input-padding-y-sm $input-padding-x-sm;\n    margin: (-$input-padding-y-sm) (-$input-padding-x-sm);\n    margin-inline-end: $input-padding-x-sm;\n  }\n}\n\n.form-control-lg {\n  min-height: $input-height-lg;\n  padding: $input-padding-y-lg $input-padding-x-lg;\n  @include font-size($input-font-size-lg);\n  @include border-radius($input-border-radius-lg);\n\n  &::file-selector-button {\n    padding: $input-padding-y-lg $input-padding-x-lg;\n    margin: (-$input-padding-y-lg) (-$input-padding-x-lg);\n    margin-inline-end: $input-padding-x-lg;\n  }\n\n  &::-webkit-file-upload-button {\n    padding: $input-padding-y-lg $input-padding-x-lg;\n    margin: (-$input-padding-y-lg) (-$input-padding-x-lg);\n    margin-inline-end: $input-padding-x-lg;\n  }\n}\n\n// Make sure textareas don't shrink too much when resized\n// https://github.com/twbs/bootstrap/pull/29124\n// stylelint-disable selector-no-qualifying-type\ntextarea {\n  &.form-control {\n    min-height: $input-height;\n  }\n\n  &.form-control-sm {\n    min-height: $input-height-sm;\n  }\n\n  &.form-control-lg {\n    min-height: $input-height-lg;\n  }\n}\n// stylelint-enable selector-no-qualifying-type\n\n.form-control-color {\n  width: $form-color-width;\n  height: auto; // Override fixed browser height\n  padding: $input-padding-y;\n\n  &:not(:disabled):not([readonly]) {\n    cursor: pointer;\n  }\n\n  &::-moz-color-swatch {\n    height: if(unit($input-line-height) == \"\", $input-line-height * 1em, $input-line-height);\n    @include border-radius($input-border-radius);\n  }\n\n  &::-webkit-color-swatch {\n    height: if(unit($input-line-height) == \"\", $input-line-height * 1em, $input-line-height);\n    @include border-radius($input-border-radius);\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-range.scss",
    "content": "// Range\n//\n// Style range inputs the same across browsers. Vendor-specific rules for pseudo\n// elements cannot be mixed. As such, there are no shared styles for focus or\n// active states on prefixed selectors.\n\n.form-range {\n  width: 100%;\n  height: add($form-range-thumb-height, $form-range-thumb-focus-box-shadow-width * 2);\n  padding: 0; // Need to reset padding\n  background-color: transparent;\n  appearance: none;\n\n  &:focus {\n    outline: 0;\n\n    // Pseudo-elements must be split across multiple rulesets to have an effect.\n    // No box-shadow() mixin for focus accessibility.\n    &::-webkit-slider-thumb { box-shadow: $form-range-thumb-focus-box-shadow; }\n    &::-moz-range-thumb     { box-shadow: $form-range-thumb-focus-box-shadow; }\n  }\n\n  &::-moz-focus-outer {\n    border: 0;\n  }\n\n  &::-webkit-slider-thumb {\n    width: $form-range-thumb-width;\n    height: $form-range-thumb-height;\n    margin-top: ($form-range-track-height - $form-range-thumb-height) * .5; // Webkit specific\n    @include gradient-bg($form-range-thumb-bg);\n    border: $form-range-thumb-border;\n    @include border-radius($form-range-thumb-border-radius);\n    @include box-shadow($form-range-thumb-box-shadow);\n    @include transition($form-range-thumb-transition);\n    appearance: none;\n\n    &:active {\n      @include gradient-bg($form-range-thumb-active-bg);\n    }\n  }\n\n  &::-webkit-slider-runnable-track {\n    width: $form-range-track-width;\n    height: $form-range-track-height;\n    color: transparent; // Why?\n    cursor: $form-range-track-cursor;\n    background-color: $form-range-track-bg;\n    border-color: transparent;\n    @include border-radius($form-range-track-border-radius);\n    @include box-shadow($form-range-track-box-shadow);\n  }\n\n  &::-moz-range-thumb {\n    width: $form-range-thumb-width;\n    height: $form-range-thumb-height;\n    @include gradient-bg($form-range-thumb-bg);\n    border: $form-range-thumb-border;\n    @include border-radius($form-range-thumb-border-radius);\n    @include box-shadow($form-range-thumb-box-shadow);\n    @include transition($form-range-thumb-transition);\n    appearance: none;\n\n    &:active {\n      @include gradient-bg($form-range-thumb-active-bg);\n    }\n  }\n\n  &::-moz-range-track {\n    width: $form-range-track-width;\n    height: $form-range-track-height;\n    color: transparent;\n    cursor: $form-range-track-cursor;\n    background-color: $form-range-track-bg;\n    border-color: transparent; // Firefox specific?\n    @include border-radius($form-range-track-border-radius);\n    @include box-shadow($form-range-track-box-shadow);\n  }\n\n  &:disabled {\n    pointer-events: none;\n\n    &::-webkit-slider-thumb {\n      background-color: $form-range-thumb-disabled-bg;\n    }\n\n    &::-moz-range-thumb {\n      background-color: $form-range-thumb-disabled-bg;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-select.scss",
    "content": "// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// https://primer.github.io/.\n\n.form-select {\n  display: block;\n  width: 100%;\n  padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;\n  // stylelint-disable-next-line property-no-vendor-prefix\n  -moz-padding-start: subtract($form-select-padding-x, 3px); // See https://github.com/twbs/bootstrap/issues/32636\n  font-family: $form-select-font-family;\n  @include font-size($form-select-font-size);\n  font-weight: $form-select-font-weight;\n  line-height: $form-select-line-height;\n  color: $form-select-color;\n  background-color: $form-select-bg;\n  background-image: escape-svg($form-select-indicator);\n  background-repeat: no-repeat;\n  background-position: $form-select-bg-position;\n  background-size: $form-select-bg-size;\n  border: $form-select-border-width solid $form-select-border-color;\n  @include border-radius($form-select-border-radius, 0);\n  @include box-shadow($form-select-box-shadow);\n  @include transition($form-select-transition);\n  appearance: none;\n\n  &:focus {\n    border-color: $form-select-focus-border-color;\n    outline: 0;\n    @if $enable-shadows {\n      @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow);\n    } @else {\n      // Avoid using mixin so we can pass custom focus shadow properly\n      box-shadow: $form-select-focus-box-shadow;\n    }\n  }\n\n  &[multiple],\n  &[size]:not([size=\"1\"]) {\n    padding-right: $form-select-padding-x;\n    background-image: none;\n  }\n\n  &:disabled {\n    color: $form-select-disabled-color;\n    background-color: $form-select-disabled-bg;\n    border-color: $form-select-disabled-border-color;\n  }\n\n  // Remove outline from select box in FF\n  &:-moz-focusring {\n    color: transparent;\n    text-shadow: 0 0 0 $form-select-color;\n  }\n}\n\n.form-select-sm {\n  padding-top: $form-select-padding-y-sm;\n  padding-bottom: $form-select-padding-y-sm;\n  padding-left: $form-select-padding-x-sm;\n  @include font-size($form-select-font-size-sm);\n  @include border-radius($form-select-border-radius-sm);\n}\n\n.form-select-lg {\n  padding-top: $form-select-padding-y-lg;\n  padding-bottom: $form-select-padding-y-lg;\n  padding-left: $form-select-padding-x-lg;\n  @include font-size($form-select-font-size-lg);\n  @include border-radius($form-select-border-radius-lg);\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-text.scss",
    "content": "//\n// Form text\n//\n\n.form-text {\n  margin-top: $form-text-margin-top;\n  @include font-size($form-text-font-size);\n  font-style: $form-text-font-style;\n  font-weight: $form-text-font-weight;\n  color: $form-text-color;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/forms/_input-group.scss",
    "content": "//\n// Base styles\n//\n\n.input-group {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap; // For form validation feedback\n  align-items: stretch;\n  width: 100%;\n\n  > .form-control,\n  > .form-select {\n    position: relative; // For focus state's z-index\n    flex: 1 1 auto;\n    width: 1%;\n    min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size\n  }\n\n  // Bring the \"active\" form control to the top of surrounding elements\n  > .form-control:focus,\n  > .form-select:focus {\n    z-index: 3;\n  }\n\n  // Ensure buttons are always above inputs for more visually pleasing borders.\n  // This isn't needed for `.input-group-text` since it shares the same border-color\n  // as our inputs.\n  .btn {\n    position: relative;\n    z-index: 2;\n\n    &:focus {\n      z-index: 3;\n    }\n  }\n}\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n  display: flex;\n  align-items: center;\n  padding: $input-group-addon-padding-y $input-group-addon-padding-x;\n  @include font-size($input-font-size); // Match inputs\n  font-weight: $input-group-addon-font-weight;\n  line-height: $input-line-height;\n  color: $input-group-addon-color;\n  text-align: center;\n  white-space: nowrap;\n  background-color: $input-group-addon-bg;\n  border: $input-border-width solid $input-group-addon-border-color;\n  @include border-radius($input-border-radius);\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .form-select,\n.input-group-lg > .input-group-text,\n.input-group-lg > .btn {\n  padding: $input-padding-y-lg $input-padding-x-lg;\n  @include font-size($input-font-size-lg);\n  @include border-radius($input-border-radius-lg);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .form-select,\n.input-group-sm > .input-group-text,\n.input-group-sm > .btn {\n  padding: $input-padding-y-sm $input-padding-x-sm;\n  @include font-size($input-font-size-sm);\n  @include border-radius($input-border-radius-sm);\n}\n\n.input-group-lg > .form-select,\n.input-group-sm > .form-select {\n  padding-right: $form-select-padding-x + $form-select-indicator-padding;\n}\n\n\n// Rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.input-group {\n  &:not(.has-validation) {\n    > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),\n    > .dropdown-toggle:nth-last-child(n + 3) {\n      @include border-end-radius(0);\n    }\n  }\n\n  &.has-validation {\n    > :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu),\n    > .dropdown-toggle:nth-last-child(n + 4) {\n      @include border-end-radius(0);\n    }\n  }\n\n  $validation-messages: \"\";\n  @each $state in map-keys($form-validation-states) {\n    $validation-messages: $validation-messages + \":not(.\" + unquote($state) + \"-tooltip)\" + \":not(.\" + unquote($state) + \"-feedback)\";\n  }\n\n  > :not(:first-child):not(.dropdown-menu)#{$validation-messages} {\n    margin-left: -$input-border-width;\n    @include border-start-radius(0);\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/forms/_labels.scss",
    "content": "//\n// Labels\n//\n\n.form-label {\n  margin-bottom: $form-label-margin-bottom;\n  @include font-size($form-label-font-size);\n  font-style: $form-label-font-style;\n  font-weight: $form-label-font-weight;\n  color: $form-label-color;\n}\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n  padding-top: add($input-padding-y, $input-border-width);\n  padding-bottom: add($input-padding-y, $input-border-width);\n  margin-bottom: 0; // Override the `<legend>` default\n  @include font-size(inherit); // Override the `<legend>` default\n  font-style: $form-label-font-style;\n  font-weight: $form-label-font-weight;\n  line-height: $input-line-height;\n  color: $form-label-color;\n}\n\n.col-form-label-lg {\n  padding-top: add($input-padding-y-lg, $input-border-width);\n  padding-bottom: add($input-padding-y-lg, $input-border-width);\n  @include font-size($input-font-size-lg);\n}\n\n.col-form-label-sm {\n  padding-top: add($input-padding-y-sm, $input-border-width);\n  padding-bottom: add($input-padding-y-sm, $input-border-width);\n  @include font-size($input-font-size-sm);\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/forms/_validation.scss",
    "content": "// Form validation\n//\n// Provide feedback to users when form field values are valid or invalid. Works\n// primarily for client-side validation via scoped `:invalid` and `:valid`\n// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for\n// server-side validation.\n\n// scss-docs-start form-validation-states-loop\n@each $state, $data in $form-validation-states {\n  @include form-validation-state($state, $data...);\n}\n// scss-docs-end form-validation-states-loop\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_clearfix.scss",
    "content": ".clearfix {\n  @include clearfix();\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_colored-links.scss",
    "content": "@each $color, $value in $theme-colors {\n  .link-#{$color} {\n    color: $value;\n\n    @if $link-shade-percentage != 0 {\n      &:hover,\n      &:focus {\n        color: if(color-contrast($value) == $color-contrast-light, shade-color($value, $link-shade-percentage), tint-color($value, $link-shade-percentage));\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_position.scss",
    "content": "// Shorthand\n\n.fixed-top {\n  position: fixed;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: $zindex-fixed;\n}\n\n.fixed-bottom {\n  position: fixed;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: $zindex-fixed;\n}\n\n// Responsive sticky top\n@each $breakpoint in map-keys($grid-breakpoints) {\n  @include media-breakpoint-up($breakpoint) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    .sticky#{$infix}-top {\n      position: sticky;\n      top: 0;\n      z-index: $zindex-sticky;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_ratio.scss",
    "content": "// Credit: Nicolas Gallagher and SUIT CSS.\n\n.ratio {\n  position: relative;\n  width: 100%;\n\n  &::before {\n    display: block;\n    padding-top: var(--#{$variable-prefix}aspect-ratio);\n    content: \"\";\n  }\n\n  > * {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n  }\n}\n\n@each $key, $ratio in $aspect-ratios {\n  .ratio-#{$key} {\n    --#{$variable-prefix}aspect-ratio: #{$ratio};\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_stacks.scss",
    "content": "// scss-docs-start stacks\n.hstack {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  align-self: stretch;\n}\n\n.vstack {\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n  align-self: stretch;\n}\n// scss-docs-end stacks\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_stretched-link.scss",
    "content": "//\n// Stretched link\n//\n\n.stretched-link {\n  &::#{$stretched-link-pseudo-element} {\n    position: absolute;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n    z-index: $stretched-link-z-index;\n    content: \"\";\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_text-truncation.scss",
    "content": "//\n// Text truncation\n//\n\n.text-truncate {\n  @include text-truncate();\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_visually-hidden.scss",
    "content": "//\n// Visually hidden\n//\n\n.visually-hidden,\n.visually-hidden-focusable:not(:focus):not(:focus-within) {\n  @include visually-hidden();\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_vr.scss",
    "content": ".vr {\n  display: inline-block;\n  align-self: stretch;\n  width: 1px;\n  min-height: 1em;\n  background-color: currentColor;\n  opacity: $hr-opacity;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_alert.scss",
    "content": "// scss-docs-start alert-variant-mixin\n@mixin alert-variant($background, $border, $color) {\n  color: $color;\n  @include gradient-bg($background);\n  border-color: $border;\n\n  .alert-link {\n    color: shade-color($color, 20%);\n  }\n}\n// scss-docs-end alert-variant-mixin\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_backdrop.scss",
    "content": "// Shared between modals and offcanvases\n@mixin overlay-backdrop($zindex, $backdrop-bg, $backdrop-opacity) {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: $zindex;\n  width: 100vw;\n  height: 100vh;\n  background-color: $backdrop-bg;\n\n  // Fade for backdrop\n  &.fade { opacity: 0; }\n  &.show { opacity: $backdrop-opacity; }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_border-radius.scss",
    "content": "// stylelint-disable property-disallowed-list\n// Single side border-radius\n\n// Helper function to replace negative values with 0\n@function valid-radius($radius) {\n  $return: ();\n  @each $value in $radius {\n    @if type-of($value) == number {\n      $return: append($return, max($value, 0));\n    } @else {\n      $return: append($return, $value);\n    }\n  }\n  @return $return;\n}\n\n// scss-docs-start border-radius-mixins\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n  @if $enable-rounded {\n    border-radius: valid-radius($radius);\n  }\n  @else if $fallback-border-radius != false {\n    border-radius: $fallback-border-radius;\n  }\n}\n\n@mixin border-top-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-left-radius: valid-radius($radius);\n    border-top-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-end-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-right-radius: valid-radius($radius);\n    border-bottom-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-bottom-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-bottom-right-radius: valid-radius($radius);\n    border-bottom-left-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-start-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-left-radius: valid-radius($radius);\n    border-bottom-left-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-top-start-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-left-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-top-end-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-top-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-bottom-end-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-bottom-right-radius: valid-radius($radius);\n  }\n}\n\n@mixin border-bottom-start-radius($radius: $border-radius) {\n  @if $enable-rounded {\n    border-bottom-left-radius: valid-radius($radius);\n  }\n}\n// scss-docs-end border-radius-mixins\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_box-shadow.scss",
    "content": "@mixin box-shadow($shadow...) {\n  @if $enable-shadows {\n    $result: ();\n\n    @each $value in $shadow {\n      @if $value != null {\n        $result: append($result, $value, \"comma\");\n      }\n      @if $value == none and length($shadow) > 1 {\n        @warn \"The keyword 'none' must be used as a single argument.\";\n      }\n    }\n\n    @if (length($result) > 0) {\n      box-shadow: $result;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_breakpoints.scss",
    "content": "// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n//    (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n//    >> breakpoint-next(sm)\n//    md\n//    >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    md\n//    >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n//    md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n  $n: index($breakpoint-names, $name);\n  @if not $n {\n    @error \"breakpoint `#{$name}` not found in `#{$breakpoints}`\";\n  }\n  @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n//    >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n  $min: map-get($breakpoints, $name);\n  @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width.\n// The maximum value is reduced by 0.02px to work around the limitations of\n// `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n//    >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n  $max: map-get($breakpoints, $name);\n  @return if($max and $max > 0, $max - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n//    >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    \"\"  (Returns a blank string)\n//    >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n//    \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n  @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n  $min: breakpoint-min($name, $breakpoints);\n  @if $min {\n    @media (min-width: $min) {\n      @content;\n    }\n  } @else {\n    @content;\n  }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n  $max: breakpoint-max($name, $breakpoints);\n  @if $max {\n    @media (max-width: $max) {\n      @content;\n    }\n  } @else {\n    @content;\n  }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n  $min: breakpoint-min($lower, $breakpoints);\n  $max: breakpoint-max($upper, $breakpoints);\n\n  @if $min != null and $max != null {\n    @media (min-width: $min) and (max-width: $max) {\n      @content;\n    }\n  } @else if $max == null {\n    @include media-breakpoint-up($lower, $breakpoints) {\n      @content;\n    }\n  } @else if $min == null {\n    @include media-breakpoint-down($upper, $breakpoints) {\n      @content;\n    }\n  }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n  $min:  breakpoint-min($name, $breakpoints);\n  $next: breakpoint-next($name, $breakpoints);\n  $max:  breakpoint-max($next);\n\n  @if $min != null and $max != null {\n    @media (min-width: $min) and (max-width: $max) {\n      @content;\n    }\n  } @else if $max == null {\n    @include media-breakpoint-up($name, $breakpoints) {\n      @content;\n    }\n  } @else if $min == null {\n    @include media-breakpoint-down($next, $breakpoints) {\n      @content;\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_buttons.scss",
    "content": "// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n// scss-docs-start btn-variant-mixin\n@mixin button-variant(\n  $background,\n  $border,\n  $color: color-contrast($background),\n  $hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)),\n  $hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)),\n  $hover-color: color-contrast($hover-background),\n  $active-background: if($color == $color-contrast-light, shade-color($background, $btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-tint-amount)),\n  $active-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)),\n  $active-color: color-contrast($active-background),\n  $disabled-background: $background,\n  $disabled-border: $border,\n  $disabled-color: color-contrast($disabled-background)\n) {\n  color: $color;\n  @include gradient-bg($background);\n  border-color: $border;\n  @include box-shadow($btn-box-shadow);\n\n  &:hover {\n    color: $hover-color;\n    @include gradient-bg($hover-background);\n    border-color: $hover-border;\n  }\n\n  .btn-check:focus + &,\n  &:focus {\n    color: $hover-color;\n    @include gradient-bg($hover-background);\n    border-color: $hover-border;\n    @if $enable-shadows {\n      @include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5));\n    } @else {\n      // Avoid using mixin so we can pass custom focus shadow properly\n      box-shadow: 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5);\n    }\n  }\n\n  .btn-check:checked + &,\n  .btn-check:active + &,\n  &:active,\n  &.active,\n  .show > &.dropdown-toggle {\n    color: $active-color;\n    background-color: $active-background;\n    // Remove CSS gradients if they're enabled\n    background-image: if($enable-gradients, none, null);\n    border-color: $active-border;\n\n    &:focus {\n      @if $enable-shadows {\n        @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5));\n      } @else {\n        // Avoid using mixin so we can pass custom focus shadow properly\n        box-shadow: 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5);\n      }\n    }\n  }\n\n  &:disabled,\n  &.disabled {\n    color: $disabled-color;\n    background-color: $disabled-background;\n    // Remove CSS gradients if they're enabled\n    background-image: if($enable-gradients, none, null);\n    border-color: $disabled-border;\n  }\n}\n// scss-docs-end btn-variant-mixin\n\n// scss-docs-start btn-outline-variant-mixin\n@mixin button-outline-variant(\n  $color,\n  $color-hover: color-contrast($color),\n  $active-background: $color,\n  $active-border: $color,\n  $active-color: color-contrast($active-background)\n) {\n  color: $color;\n  border-color: $color;\n\n  &:hover {\n    color: $color-hover;\n    background-color: $active-background;\n    border-color: $active-border;\n  }\n\n  .btn-check:focus + &,\n  &:focus {\n    box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n  }\n\n  .btn-check:checked + &,\n  .btn-check:active + &,\n  &:active,\n  &.active,\n  &.dropdown-toggle.show {\n    color: $active-color;\n    background-color: $active-background;\n    border-color: $active-border;\n\n    &:focus {\n      @if $enable-shadows {\n        @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));\n      } @else {\n        // Avoid using mixin so we can pass custom focus shadow properly\n        box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n      }\n    }\n  }\n\n  &:disabled,\n  &.disabled {\n    color: $color;\n    background-color: transparent;\n  }\n}\n// scss-docs-end btn-outline-variant-mixin\n\n// scss-docs-start btn-size-mixin\n@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {\n  padding: $padding-y $padding-x;\n  @include font-size($font-size);\n  // Manually declare to provide an override to the browser default\n  @include border-radius($border-radius, 0);\n}\n// scss-docs-end btn-size-mixin\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_caret.scss",
    "content": "// scss-docs-start caret-mixins\n@mixin caret-down {\n  border-top: $caret-width solid;\n  border-right: $caret-width solid transparent;\n  border-bottom: 0;\n  border-left: $caret-width solid transparent;\n}\n\n@mixin caret-up {\n  border-top: 0;\n  border-right: $caret-width solid transparent;\n  border-bottom: $caret-width solid;\n  border-left: $caret-width solid transparent;\n}\n\n@mixin caret-end {\n  border-top: $caret-width solid transparent;\n  border-right: 0;\n  border-bottom: $caret-width solid transparent;\n  border-left: $caret-width solid;\n}\n\n@mixin caret-start {\n  border-top: $caret-width solid transparent;\n  border-right: $caret-width solid;\n  border-bottom: $caret-width solid transparent;\n}\n\n@mixin caret($direction: down) {\n  @if $enable-caret {\n    &::after {\n      display: inline-block;\n      margin-left: $caret-spacing;\n      vertical-align: $caret-vertical-align;\n      content: \"\";\n      @if $direction == down {\n        @include caret-down();\n      } @else if $direction == up {\n        @include caret-up();\n      } @else if $direction == end {\n        @include caret-end();\n      }\n    }\n\n    @if $direction == start {\n      &::after {\n        display: none;\n      }\n\n      &::before {\n        display: inline-block;\n        margin-right: $caret-spacing;\n        vertical-align: $caret-vertical-align;\n        content: \"\";\n        @include caret-start();\n      }\n    }\n\n    &:empty::after {\n      margin-left: 0;\n    }\n  }\n}\n// scss-docs-end caret-mixins\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_clearfix.scss",
    "content": "// scss-docs-start clearfix\n@mixin clearfix() {\n  &::after {\n    display: block;\n    clear: both;\n    content: \"\";\n  }\n}\n// scss-docs-end clearfix\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_color-scheme.scss",
    "content": "// scss-docs-start mixin-color-scheme\n@mixin color-scheme($name) {\n  @media (prefers-color-scheme: #{$name}) {\n    @content;\n  }\n}\n// scss-docs-end mixin-color-scheme\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_container.scss",
    "content": "// Container mixins\n\n@mixin make-container($gutter: $container-padding-x) {\n  width: 100%;\n  padding-right: var(--#{$variable-prefix}gutter-x, #{$gutter});\n  padding-left: var(--#{$variable-prefix}gutter-x, #{$gutter});\n  margin-right: auto;\n  margin-left: auto;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_deprecate.scss",
    "content": "// Deprecate mixin\n//\n// This mixin can be used to deprecate mixins or functions.\n// `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to\n// some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap)\n@mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) {\n  @if ($enable-deprecation-messages != false and $ignore-warning != true) {\n    @warn \"#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}.\";\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_forms.scss",
    "content": "// This mixin uses an `if()` technique to be compatible with Dart Sass\n// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details\n\n// scss-docs-start form-validation-mixins\n@mixin form-validation-state-selector($state) {\n  @if ($state == \"valid\" or $state == \"invalid\") {\n    .was-validated #{if(&, \"&\", \"\")}:#{$state},\n    #{if(&, \"&\", \"\")}.is-#{$state} {\n      @content;\n    }\n  } @else {\n    #{if(&, \"&\", \"\")}.is-#{$state} {\n      @content;\n    }\n  }\n}\n\n@mixin form-validation-state(\n  $state,\n  $color,\n  $icon,\n  $tooltip-color: color-contrast($color),\n  $tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),\n  $focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity)\n) {\n  .#{$state}-feedback {\n    display: none;\n    width: 100%;\n    margin-top: $form-feedback-margin-top;\n    @include font-size($form-feedback-font-size);\n    font-style: $form-feedback-font-style;\n    color: $color;\n  }\n\n  .#{$state}-tooltip {\n    position: absolute;\n    top: 100%;\n    z-index: 5;\n    display: none;\n    max-width: 100%; // Contain to parent when possible\n    padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;\n    margin-top: .1rem;\n    @include font-size($form-feedback-tooltip-font-size);\n    line-height: $form-feedback-tooltip-line-height;\n    color: $tooltip-color;\n    background-color: $tooltip-bg-color;\n    @include border-radius($form-feedback-tooltip-border-radius);\n  }\n\n  @include form-validation-state-selector($state) {\n    ~ .#{$state}-feedback,\n    ~ .#{$state}-tooltip {\n      display: block;\n    }\n  }\n\n  .form-control {\n    @include form-validation-state-selector($state) {\n      border-color: $color;\n\n      @if $enable-validation-icons {\n        padding-right: $input-height-inner;\n        background-image: escape-svg($icon);\n        background-repeat: no-repeat;\n        background-position: right $input-height-inner-quarter center;\n        background-size: $input-height-inner-half $input-height-inner-half;\n      }\n\n      &:focus {\n        border-color: $color;\n        box-shadow: $focus-box-shadow;\n      }\n    }\n  }\n\n  // stylelint-disable-next-line selector-no-qualifying-type\n  textarea.form-control {\n    @include form-validation-state-selector($state) {\n      @if $enable-validation-icons {\n        padding-right: $input-height-inner;\n        background-position: top $input-height-inner-quarter right $input-height-inner-quarter;\n      }\n    }\n  }\n\n  .form-select {\n    @include form-validation-state-selector($state) {\n      border-color: $color;\n\n      @if $enable-validation-icons {\n        &:not([multiple]):not([size]),\n        &:not([multiple])[size=\"1\"] {\n          padding-right: $form-select-feedback-icon-padding-end;\n          background-image: escape-svg($form-select-indicator), escape-svg($icon);\n          background-position: $form-select-bg-position, $form-select-feedback-icon-position;\n          background-size: $form-select-bg-size, $form-select-feedback-icon-size;\n        }\n      }\n\n      &:focus {\n        border-color: $color;\n        box-shadow: $focus-box-shadow;\n      }\n    }\n  }\n\n  .form-check-input {\n    @include form-validation-state-selector($state) {\n      border-color: $color;\n\n      &:checked {\n        background-color: $color;\n      }\n\n      &:focus {\n        box-shadow: $focus-box-shadow;\n      }\n\n      ~ .form-check-label {\n        color: $color;\n      }\n    }\n  }\n  .form-check-inline .form-check-input {\n    ~ .#{$state}-feedback {\n      margin-left: .5em;\n    }\n  }\n\n  .input-group .form-control,\n  .input-group .form-select {\n    @include form-validation-state-selector($state) {\n      @if $state == \"valid\" {\n        z-index: 1;\n      } @else if $state == \"invalid\" {\n        z-index: 2;\n      }\n      &:focus {\n        z-index: 3;\n      }\n    }\n  }\n}\n// scss-docs-end form-validation-mixins\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_gradients.scss",
    "content": "// Gradients\n\n// scss-docs-start gradient-bg-mixin\n@mixin gradient-bg($color: null) {\n  background-color: $color;\n\n  @if $enable-gradients {\n    background-image: var(--#{$variable-prefix}gradient);\n  }\n}\n// scss-docs-end gradient-bg-mixin\n\n// scss-docs-start gradient-mixins\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n  background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: null, $end-percent: null) {\n  background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n  background-image: linear-gradient($deg, $start-color, $end-color);\n}\n\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n  background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n}\n\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n  background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n}\n\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n  background-image: radial-gradient(circle, $inner-color, $outer-color);\n}\n\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n  background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n// scss-docs-end gradient-mixins\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_grid.scss",
    "content": "// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-row($gutter: $grid-gutter-width) {\n  --#{$variable-prefix}gutter-x: #{$gutter};\n  --#{$variable-prefix}gutter-y: 0;\n  display: flex;\n  flex-wrap: wrap;\n  // TODO: Revisit calc order after https://github.com/react-bootstrap/react-bootstrap/issues/6039 is fixed\n  margin-top: calc(-1 * var(--#{$variable-prefix}gutter-y)); // stylelint-disable-line function-disallowed-list\n  margin-right: calc(-.5 * var(--#{$variable-prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n  margin-left: calc(-.5 * var(--#{$variable-prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n  // Add box sizing if only the grid is loaded\n  box-sizing: if(variable-exists(include-column-box-sizing) and $include-column-box-sizing, border-box, null);\n  // Prevent columns from becoming too narrow when at smaller grid tiers by\n  // always setting `width: 100%;`. This works because we set the width\n  // later on to override this initial width.\n  flex-shrink: 0;\n  width: 100%;\n  max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid\n  padding-right: calc(var(--#{$variable-prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n  padding-left: calc(var(--#{$variable-prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n  margin-top: var(--#{$variable-prefix}gutter-y);\n}\n\n@mixin make-col($size: false, $columns: $grid-columns) {\n  @if $size {\n    flex: 0 0 auto;\n    width: percentage(divide($size, $columns));\n\n  } @else {\n    flex: 1 1 0;\n    max-width: 100%;\n  }\n}\n\n@mixin make-col-auto() {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n  $num: divide($size, $columns);\n  margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// numberof columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n  > * {\n    flex: 0 0 auto;\n    width: divide(100%, $count);\n  }\n}\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n  @each $breakpoint in map-keys($breakpoints) {\n    $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n    @include media-breakpoint-up($breakpoint, $breakpoints) {\n      // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n      .col#{$infix} {\n        flex: 1 0 0%; // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n      }\n\n      .row-cols#{$infix}-auto > * {\n        @include make-col-auto();\n      }\n\n      @if $grid-row-columns > 0 {\n        @for $i from 1 through $grid-row-columns {\n          .row-cols#{$infix}-#{$i} {\n            @include row-cols($i);\n          }\n        }\n      }\n\n      .col#{$infix}-auto {\n        @include make-col-auto();\n      }\n\n      @if $columns > 0 {\n        @for $i from 1 through $columns {\n          .col#{$infix}-#{$i} {\n            @include make-col($i, $columns);\n          }\n        }\n\n        // `$columns - 1` because offsetting by the width of an entire row isn't possible\n        @for $i from 0 through ($columns - 1) {\n          @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n            .offset#{$infix}-#{$i} {\n              @include make-col-offset($i, $columns);\n            }\n          }\n        }\n      }\n\n      // Gutters\n      //\n      // Make use of `.g-*`, `.gx-*` or `.gy-*` utilities to change spacing between the columns.\n      @each $key, $value in $gutters {\n        .g#{$infix}-#{$key},\n        .gx#{$infix}-#{$key} {\n          --#{$variable-prefix}gutter-x: #{$value};\n        }\n\n        .g#{$infix}-#{$key},\n        .gy#{$infix}-#{$key} {\n          --#{$variable-prefix}gutter-y: #{$value};\n        }\n      }\n    }\n  }\n}\n\n@mixin make-cssgrid($columns: $grid-columns, $breakpoints: $grid-breakpoints) {\n  @each $breakpoint in map-keys($breakpoints) {\n    $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n    @include media-breakpoint-up($breakpoint, $breakpoints) {\n      @if $columns > 0 {\n        @for $i from 1 through $columns {\n          .g-col#{$infix}-#{$i} {\n            grid-column: auto / span $i;\n          }\n        }\n\n        // Start with `1` because `0` is and invalid value.\n        // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible.\n        @for $i from 1 through ($columns - 1) {\n          .g-start#{$infix}-#{$i} {\n            grid-column-start: $i;\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_image.scss",
    "content": "// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid {\n  // Part 1: Set a maximum relative to the parent\n  max-width: 100%;\n  // Part 2: Override the height to auto, otherwise images will be stretched\n  // when setting a width and height attribute on the img element.\n  height: auto;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_list-group.scss",
    "content": "// List Groups\n\n// scss-docs-start list-group-mixin\n@mixin list-group-item-variant($state, $background, $color) {\n  .list-group-item-#{$state} {\n    color: $color;\n    background-color: $background;\n\n    &.list-group-item-action {\n      &:hover,\n      &:focus {\n        color: $color;\n        background-color: shade-color($background, 10%);\n      }\n\n      &.active {\n        color: $white;\n        background-color: $color;\n        border-color: $color;\n      }\n    }\n  }\n}\n// scss-docs-end list-group-mixin\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_lists.scss",
    "content": "// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_pagination.scss",
    "content": "// Pagination\n\n// scss-docs-start pagination-mixin\n@mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) {\n  .page-link {\n    padding: $padding-y $padding-x;\n    @include font-size($font-size);\n  }\n\n  .page-item {\n    @if $pagination-margin-start == (-$pagination-border-width) {\n      &:first-child {\n        .page-link {\n          @include border-start-radius($border-radius);\n        }\n      }\n\n      &:last-child {\n        .page-link {\n          @include border-end-radius($border-radius);\n        }\n      }\n    } @else {\n      //Add border-radius to all pageLinks in case they have left margin\n      .page-link {\n        @include border-radius($border-radius);\n      }\n    }\n  }\n}\n// scss-docs-end pagination-mixin\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_reset-text.scss",
    "content": "@mixin reset-text {\n  font-family: $font-family-base;\n  // We deliberately do NOT reset font-size or overflow-wrap / word-wrap.\n  font-style: normal;\n  font-weight: $font-weight-normal;\n  line-height: $line-height-base;\n  text-align: left; // Fallback for where `start` is not supported\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  white-space: normal;\n  line-break: auto;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_resize.scss",
    "content": "// Resize anything\n\n@mixin resizable($direction) {\n  overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`\n  resize: $direction; // Options: horizontal, vertical, both\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_table-variants.scss",
    "content": "// scss-docs-start table-variant\n@mixin table-variant($state, $background) {\n  .table-#{$state} {\n    $color: color-contrast(opaque($body-bg, $background));\n    $hover-bg: mix($color, $background, percentage($table-hover-bg-factor));\n    $striped-bg: mix($color, $background, percentage($table-striped-bg-factor));\n    $active-bg: mix($color, $background, percentage($table-active-bg-factor));\n\n    --#{$variable-prefix}table-bg: #{$background};\n    --#{$variable-prefix}table-striped-bg: #{$striped-bg};\n    --#{$variable-prefix}table-striped-color: #{color-contrast($striped-bg)};\n    --#{$variable-prefix}table-active-bg: #{$active-bg};\n    --#{$variable-prefix}table-active-color: #{color-contrast($active-bg)};\n    --#{$variable-prefix}table-hover-bg: #{$hover-bg};\n    --#{$variable-prefix}table-hover-color: #{color-contrast($hover-bg)};\n\n    color: $color;\n    border-color: mix($color, $background, percentage($table-border-factor));\n  }\n}\n// scss-docs-end table-variant\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_text-truncate.scss",
    "content": "// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_transition.scss",
    "content": "// stylelint-disable property-disallowed-list\n@mixin transition($transition...) {\n  @if length($transition) == 0 {\n    $transition: $transition-base;\n  }\n\n  @if length($transition) > 1 {\n    @each $value in $transition {\n      @if $value == null or $value == none {\n        @warn \"The keyword 'none' or 'null' must be used as a single argument.\";\n      }\n    }\n  }\n\n  @if $enable-transitions {\n    @if nth($transition, 1) != null {\n      transition: $transition;\n    }\n\n    @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none {\n      @media (prefers-reduced-motion: reduce) {\n        transition: none;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_utilities.scss",
    "content": "// Utility generator\n// Used to generate utilities & print utilities\n@mixin generate-utility($utility, $infix, $is-rfs-media-query: false) {\n  $values: map-get($utility, values);\n\n  // If the values are a list or string, convert it into a map\n  @if type-of($values) == \"string\" or type-of(nth($values, 1)) != \"list\" {\n    $values: zip($values, $values);\n  }\n\n  @each $key, $value in $values {\n    $properties: map-get($utility, property);\n\n    // Multiple properties are possible, for example with vertical or horizontal margins or paddings\n    @if type-of($properties) == \"string\" {\n      $properties: append((), $properties);\n    }\n\n    // Use custom class if present\n    $property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));\n    $property-class: if($property-class == null, \"\", $property-class);\n\n    // State params to generate pseudo-classes\n    $state: if(map-has-key($utility, state), map-get($utility, state), ());\n\n    $infix: if($property-class == \"\" and str-slice($infix, 1, 1) == \"-\", str-slice($infix, 2), $infix);\n\n    // Don't prefix if value key is null (eg. with shadow class)\n    $property-class-modifier: if($key, if($property-class == \"\" and $infix == \"\", \"\", \"-\") + $key, \"\");\n\n    @if map-get($utility, rfs) {\n      // Inside the media query\n      @if $is-rfs-media-query {\n        $val: rfs-value($value);\n\n        // Do not render anything if fluid and non fluid values are the same\n        $value: if($val == rfs-fluid-value($value), null, $val);\n      }\n      @else {\n        $value: rfs-fluid-value($value);\n      }\n    }\n\n    $is-css-var: map-get($utility, css-var);\n    $is-local-vars: map-get($utility, local-vars);\n    $is-rtl: map-get($utility, rtl);\n\n    @if $value != null {\n      @if $is-rtl == false {\n        /* rtl:begin:remove */\n      }\n\n      @if $is-css-var {\n        .#{$property-class + $infix + $property-class-modifier} {\n          --#{$variable-prefix}#{$property-class}: #{$value};\n        }\n\n        @each $pseudo in $state {\n          .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n            --#{$variable-prefix}#{$property-class}: #{$value};\n          }\n        }\n      } @else {\n        .#{$property-class + $infix + $property-class-modifier} {\n          @each $property in $properties {\n            @if $is-local-vars {\n              @each $local-var, $value in $is-local-vars {\n                --#{$variable-prefix}#{$local-var}: #{$value};\n              }\n            }\n            #{$property}: $value if($enable-important-utilities, !important, null);\n          }\n        }\n\n        @each $pseudo in $state {\n          .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n            @each $property in $properties {\n              #{$property}: $value if($enable-important-utilities, !important, null);\n            }\n          }\n        }\n      }\n\n      @if $is-rtl == false {\n        /* rtl:end:remove */\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_visually-hidden.scss",
    "content": "// stylelint-disable declaration-no-important\n\n// Hide content visually while keeping it accessible to assistive technologies\n//\n// See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/\n// See: https://kittygiraudel.com/2016/10/13/css-hide-and-seek/\n\n@mixin visually-hidden() {\n  position: absolute !important;\n  width: 1px !important;\n  height: 1px !important;\n  padding: 0 !important;\n  margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686\n  overflow: hidden !important;\n  clip: rect(0, 0, 0, 0) !important;\n  white-space: nowrap !important;\n  border: 0 !important;\n}\n\n// Use to only display content when it's focused, or one of its child elements is focused\n// (i.e. when focus is within the element/container that the class was applied to)\n//\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n\n@mixin visually-hidden-focusable() {\n  &:not(:focus):not(:focus-within) {\n    @include visually-hidden();\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/utilities/_api.scss",
    "content": "// Loop over each breakpoint\n@each $breakpoint in map-keys($grid-breakpoints) {\n\n  // Generate media query if needed\n  @include media-breakpoint-up($breakpoint) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    // Loop over each utility property\n    @each $key, $utility in $utilities {\n      // The utility can be disabled with `false`, thus check if the utility is a map first\n      // Only proceed if responsive media queries are enabled or if it's the base media query\n      @if type-of($utility) == \"map\" and (map-get($utility, responsive) or $infix == \"\") {\n        @include generate-utility($utility, $infix);\n      }\n    }\n  }\n}\n\n// RFS rescaling\n@media (min-width: $rfs-mq-value) {\n  @each $breakpoint in map-keys($grid-breakpoints) {\n    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n    @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) {\n      // Loop over each utility property\n      @each $key, $utility in $utilities {\n        // The utility can be disabled with `false`, thus check if the utility is a map first\n        // Only proceed if responsive media queries are enabled or if it's the base media query\n        @if type-of($utility) == \"map\" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == \"\") {\n          @include generate-utility($utility, $infix, true);\n        }\n      }\n    }\n  }\n}\n\n\n// Print utilities\n@media print {\n  @each $key, $utility in $utilities {\n    // The utility can be disabled with `false`, thus check if the utility is a map first\n    // Then check if the utility needs print styles\n    @if type-of($utility) == \"map\" and map-get($utility, print) == true {\n      @include generate-utility($utility, \"-print\");\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/bootstrap/vendor/_rfs.scss",
    "content": "// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated responsive values for font sizes, paddings, margins and much more\n//\n// Licensed under MIT (https://github.com/twbs/rfs/blob/main/LICENSE)\n\n// Configuration\n\n// Base value\n$rfs-base-value: 1.25rem !default;\n$rfs-unit: rem !default;\n\n@if $rfs-unit != rem and $rfs-unit != px {\n  @error \"`#{$rfs-unit}` is not a valid unit for $rfs-unit. Use `px` or `rem`.\";\n}\n\n// Breakpoint at where values start decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem {\n  @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n}\n\n// Resize values based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != number or $rfs-factor <= 1 {\n  @error \"`#{$rfs-factor}` is not a valid  $rfs-factor, it must be greater than 1.\";\n}\n\n// Mode. Possibilities: \"min-media-query\", \"max-media-query\"\n$rfs-mode: min-media-query !default;\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-rfs to false\n$enable-rfs: true !default;\n\n// Cache $rfs-base-value unit\n$rfs-base-value-unit: unit($rfs-base-value);\n\n@function divide($dividend, $divisor, $precision: 10) {\n  $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);\n  $dividend: abs($dividend);\n  $divisor: abs($divisor);\n  @if $dividend == 0 {\n    @return 0;\n  }\n  @if $divisor == 0 {\n    @error \"Cannot divide by 0\";\n  }\n  $remainder: $dividend;\n  $result: 0;\n  $factor: 10;\n  @while ($remainder > 0 and $precision >= 0) {\n    $quotient: 0;\n    @while ($remainder >= $divisor) {\n      $remainder: $remainder - $divisor;\n      $quotient: $quotient + 1;\n    }\n    $result: $result * 10 + $quotient;\n    $factor: $factor * .1;\n    $remainder: $remainder * 10;\n    $precision: $precision - 1;\n    @if ($precision < 0 and $remainder >= $divisor * 5) {\n      $result: $result + 1;\n    }\n  }\n  $result: $result * $factor * $sign;\n  $dividend-unit: unit($dividend);\n  $divisor-unit: unit($divisor);\n  $unit-map: (\n    \"px\": 1px,\n    \"rem\": 1rem,\n    \"em\": 1em,\n    \"%\": 1%\n  );\n  @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {\n    $result: $result * map-get($unit-map, $dividend-unit);\n  }\n  @return $result;\n}\n\n// Remove px-unit from $rfs-base-value for calculations\n@if $rfs-base-value-unit == px {\n  $rfs-base-value: divide($rfs-base-value, $rfs-base-value * 0 + 1);\n}\n@else if $rfs-base-value-unit == rem {\n  $rfs-base-value: divide($rfs-base-value, divide($rfs-base-value * 0 + 1, $rfs-rem-value));\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == px {\n  $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == \"em\" {\n  $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value));\n}\n\n// Calculate the media query value\n$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit});\n$rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width);\n$rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height);\n\n// Internal mixin used to determine which media query needs to be used\n@mixin _rfs-media-query {\n  @if $rfs-two-dimensional {\n    @if $rfs-mode == max-media-query {\n      @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}), (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n        @content;\n      }\n    }\n    @else {\n      @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) and (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n        @content;\n      }\n    }\n  }\n  @else {\n    @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) {\n      @content;\n    }\n  }\n}\n\n// Internal mixin that adds disable classes to the selector if needed.\n@mixin _rfs-rule {\n  @if $rfs-class == disable and $rfs-mode == max-media-query {\n    // Adding an extra class increases specificity, which prevents the media query to override the property\n    &,\n    .disable-rfs &,\n    &.disable-rfs {\n      @content;\n    }\n  }\n  @else if $rfs-class == enable and $rfs-mode == min-media-query {\n    .enable-rfs &,\n    &.enable-rfs {\n      @content;\n    }\n  }\n  @else {\n    @content;\n  }\n}\n\n// Internal mixin that adds enable classes to the selector if needed.\n@mixin _rfs-media-query-rule {\n\n  @if $rfs-class == enable {\n    @if $rfs-mode == min-media-query {\n      @content;\n    }\n\n    @include _rfs-media-query {\n      .enable-rfs &,\n      &.enable-rfs {\n        @content;\n      }\n    }\n  }\n  @else {\n    @if $rfs-class == disable and $rfs-mode == min-media-query {\n      .disable-rfs &,\n      &.disable-rfs {\n        @content;\n      }\n    }\n    @include _rfs-media-query {\n      @content;\n    }\n  }\n}\n\n// Helper function to get the formatted non-responsive value\n@function rfs-value($values) {\n  // Convert to list\n  $values: if(type-of($values) != list, ($values,), $values);\n\n  $val: '';\n\n  // Loop over each value and calculate value\n  @each $value in $values {\n    @if $value == 0 {\n      $val: $val + ' 0';\n    }\n    @else {\n      // Cache $value unit\n      $unit: if(type-of($value) == \"number\", unit($value), false);\n\n      @if $unit == px {\n        // Convert to rem if needed\n        $val: $val + ' ' + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value);\n      }\n      @else if $unit == rem {\n        // Convert to px if needed\n        $val: $val + ' ' + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value);\n      }\n      @else {\n        // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n        $val: $val + ' ' + $value;\n      }\n    }\n  }\n\n  // Remove first space\n  @return unquote(str-slice($val, 2));\n}\n\n// Helper function to get the responsive value calculated by RFS\n@function rfs-fluid-value($values) {\n  // Convert to list\n  $values: if(type-of($values) != list, ($values,), $values);\n\n  $val: '';\n\n  // Loop over each value and calculate value\n  @each $value in $values {\n    @if $value == 0 {\n      $val: $val + ' 0';\n    }\n\n    @else {\n      // Cache $value unit\n      $unit: if(type-of($value) == \"number\", unit($value), false);\n\n      // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n      @if not $unit or $unit != px and $unit != rem {\n        $val: $val + ' ' + $value;\n      }\n\n      @else {\n        // Remove unit from $value for calculations\n        $value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value)));\n\n        // Only add the media query if the value is greater than the minimum value\n        @if abs($value) <= $rfs-base-value or not $enable-rfs {\n          $val: $val + ' ' +  if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px);\n        }\n        @else {\n          // Calculate the minimum value\n          $value-min: $rfs-base-value + divide(abs($value) - $rfs-base-value, $rfs-factor);\n\n          // Calculate difference between $value and the minimum value\n          $value-diff: abs($value) - $value-min;\n\n          // Base value formatting\n          $min-width: if($rfs-unit == rem, #{divide($value-min, $rfs-rem-value)}rem, #{$value-min}px);\n\n          // Use negative value if needed\n          $min-width: if($value < 0, -$min-width, $min-width);\n\n          // Use `vmin` if two-dimensional is enabled\n          $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n          // Calculate the variable width between 0 and $rfs-breakpoint\n          $variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit};\n\n          // Return the calculated value\n          $val: $val + ' calc(' + $min-width + if($value < 0, ' - ', ' + ') + $variable-width + ')';\n        }\n      }\n    }\n  }\n\n  // Remove first space\n  @return unquote(str-slice($val, 2));\n}\n\n// RFS mixin\n@mixin rfs($values, $property: font-size) {\n  @if $values != null {\n    $val: rfs-value($values);\n    $fluidVal: rfs-fluid-value($values);\n\n    // Do not print the media query if responsive & non-responsive values are the same\n    @if $val == $fluidVal {\n      #{$property}: $val;\n    }\n    @else {\n      @include _rfs-rule {\n        #{$property}: if($rfs-mode == max-media-query, $val, $fluidVal);\n\n        // Include safari iframe resize fix if needed\n        min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);\n      }\n\n      @include _rfs-media-query-rule {\n        #{$property}: if($rfs-mode == max-media-query, $fluidVal, $val);\n      }\n    }\n  }\n}\n\n// Shorthand helper mixins\n@mixin font-size($value) {\n  @include rfs($value);\n}\n\n@mixin padding($value) {\n  @include rfs($value, padding);\n}\n\n@mixin padding-top($value) {\n  @include rfs($value, padding-top);\n}\n\n@mixin padding-right($value) {\n  @include rfs($value, padding-right);\n}\n\n@mixin padding-bottom($value) {\n  @include rfs($value, padding-bottom);\n}\n\n@mixin padding-left($value) {\n  @include rfs($value, padding-left);\n}\n\n@mixin margin($value) {\n  @include rfs($value, margin);\n}\n\n@mixin margin-top($value) {\n  @include rfs($value, margin-top);\n}\n\n@mixin margin-right($value) {\n  @include rfs($value, margin-right);\n}\n\n@mixin margin-bottom($value) {\n  @include rfs($value, margin-bottom);\n}\n\n@mixin margin-left($value) {\n  @include rfs($value, margin-left);\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/flatpickr.css",
    "content": ".flatpickr-calendar {\n  background: transparent;\n  opacity: 0;\n  display: none;\n  text-align: center;\n  visibility: hidden;\n  padding: 0;\n  -webkit-animation: none;\n          animation: none;\n  direction: ltr;\n  border: 0;\n  font-size: 14px;\n  line-height: 24px;\n  border-radius: 5px;\n  position: absolute;\n  width: 307.875px;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  -ms-touch-action: manipulation;\n      touch-action: manipulation;\n  background: #fff;\n  -webkit-box-shadow: 1px 0 0 #e6e6e6, -1px 0 0 #e6e6e6, 0 1px 0 #e6e6e6, 0 -1px 0 #e6e6e6, 0 3px 13px rgba(0,0,0,0.08);\n          box-shadow: 1px 0 0 #e6e6e6, -1px 0 0 #e6e6e6, 0 1px 0 #e6e6e6, 0 -1px 0 #e6e6e6, 0 3px 13px rgba(0,0,0,0.08);\n}\n.flatpickr-calendar.open,\n.flatpickr-calendar.inline {\n  opacity: 1;\n  max-height: 640px;\n  visibility: visible;\n}\n.flatpickr-calendar.open {\n  display: inline-block;\n  z-index: 99999;\n}\n.flatpickr-calendar.animate.open {\n  -webkit-animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1);\n          animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1);\n}\n.flatpickr-calendar.inline {\n  display: block;\n  position: relative;\n  top: 2px;\n}\n.flatpickr-calendar.static {\n  position: absolute;\n  top: calc(100% + 2px);\n}\n.flatpickr-calendar.static.open {\n  z-index: 999;\n  display: block;\n}\n.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+1) .flatpickr-day.inRange:nth-child(7n+7) {\n  -webkit-box-shadow: none !important;\n          box-shadow: none !important;\n}\n.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1) {\n  -webkit-box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;\n          box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;\n}\n.flatpickr-calendar .hasWeeks .dayContainer,\n.flatpickr-calendar .hasTime .dayContainer {\n  border-bottom: 0;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.flatpickr-calendar .hasWeeks .dayContainer {\n  border-left: 0;\n}\n.flatpickr-calendar.hasTime .flatpickr-time {\n  height: 40px;\n  border-top: 1px solid #e6e6e6;\n}\n.flatpickr-calendar.noCalendar.hasTime .flatpickr-time {\n  height: auto;\n}\n.flatpickr-calendar:before,\n.flatpickr-calendar:after {\n  position: absolute;\n  display: block;\n  pointer-events: none;\n  border: solid transparent;\n  content: '';\n  height: 0;\n  width: 0;\n  left: 22px;\n}\n.flatpickr-calendar.rightMost:before,\n.flatpickr-calendar.arrowRight:before,\n.flatpickr-calendar.rightMost:after,\n.flatpickr-calendar.arrowRight:after {\n  left: auto;\n  right: 22px;\n}\n.flatpickr-calendar.arrowCenter:before,\n.flatpickr-calendar.arrowCenter:after {\n  left: 50%;\n  right: 50%;\n}\n.flatpickr-calendar:before {\n  border-width: 5px;\n  margin: 0 -5px;\n}\n.flatpickr-calendar:after {\n  border-width: 4px;\n  margin: 0 -4px;\n}\n.flatpickr-calendar.arrowTop:before,\n.flatpickr-calendar.arrowTop:after {\n  bottom: 100%;\n}\n.flatpickr-calendar.arrowTop:before {\n  border-bottom-color: #e6e6e6;\n}\n.flatpickr-calendar.arrowTop:after {\n  border-bottom-color: #fff;\n}\n.flatpickr-calendar.arrowBottom:before,\n.flatpickr-calendar.arrowBottom:after {\n  top: 100%;\n}\n.flatpickr-calendar.arrowBottom:before {\n  border-top-color: #e6e6e6;\n}\n.flatpickr-calendar.arrowBottom:after {\n  border-top-color: #fff;\n}\n.flatpickr-calendar:focus {\n  outline: 0;\n}\n.flatpickr-wrapper {\n  position: relative;\n  display: inline-block;\n}\n.flatpickr-months {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n}\n.flatpickr-months .flatpickr-month {\n  background: transparent;\n  color: rgba(0,0,0,0.9);\n  fill: rgba(0,0,0,0.9);\n  height: 34px;\n  line-height: 1;\n  text-align: center;\n  position: relative;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  overflow: hidden;\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n      -ms-flex: 1;\n          flex: 1;\n}\n.flatpickr-months .flatpickr-prev-month,\n.flatpickr-months .flatpickr-next-month {\n  text-decoration: none;\n  cursor: pointer;\n  position: absolute;\n  top: 0;\n  height: 34px;\n  padding: 10px;\n  z-index: 3;\n  color: rgba(0,0,0,0.9);\n  fill: rgba(0,0,0,0.9);\n}\n.flatpickr-months .flatpickr-prev-month.flatpickr-disabled,\n.flatpickr-months .flatpickr-next-month.flatpickr-disabled {\n  display: none;\n}\n.flatpickr-months .flatpickr-prev-month i,\n.flatpickr-months .flatpickr-next-month i {\n  position: relative;\n}\n.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month,\n.flatpickr-months .flatpickr-next-month.flatpickr-prev-month {\n/*\n      /*rtl:begin:ignore*/\n/*\n      */\n  left: 0;\n/*\n      /*rtl:end:ignore*/\n/*\n      */\n}\n/*\n      /*rtl:begin:ignore*/\n/*\n      /*rtl:end:ignore*/\n.flatpickr-months .flatpickr-prev-month.flatpickr-next-month,\n.flatpickr-months .flatpickr-next-month.flatpickr-next-month {\n/*\n      /*rtl:begin:ignore*/\n/*\n      */\n  right: 0;\n/*\n      /*rtl:end:ignore*/\n/*\n      */\n}\n/*\n      /*rtl:begin:ignore*/\n/*\n      /*rtl:end:ignore*/\n.flatpickr-months .flatpickr-prev-month:hover,\n.flatpickr-months .flatpickr-next-month:hover {\n  color: #959ea9;\n}\n.flatpickr-months .flatpickr-prev-month:hover svg,\n.flatpickr-months .flatpickr-next-month:hover svg {\n  fill: #f64747;\n}\n.flatpickr-months .flatpickr-prev-month svg,\n.flatpickr-months .flatpickr-next-month svg {\n  width: 14px;\n  height: 14px;\n}\n.flatpickr-months .flatpickr-prev-month svg path,\n.flatpickr-months .flatpickr-next-month svg path {\n  -webkit-transition: fill 0.1s;\n  transition: fill 0.1s;\n  fill: inherit;\n}\n.numInputWrapper {\n  position: relative;\n  height: auto;\n}\n.numInputWrapper input,\n.numInputWrapper span {\n  display: inline-block;\n}\n.numInputWrapper input {\n  width: 100%;\n}\n.numInputWrapper input::-ms-clear {\n  display: none;\n}\n.numInputWrapper input::-webkit-outer-spin-button,\n.numInputWrapper input::-webkit-inner-spin-button {\n  margin: 0;\n  -webkit-appearance: none;\n}\n.numInputWrapper span {\n  position: absolute;\n  right: 0;\n  width: 14px;\n  padding: 0 4px 0 2px;\n  height: 50%;\n  line-height: 50%;\n  opacity: 0;\n  cursor: pointer;\n  border: 1px solid rgba(57,57,57,0.15);\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.numInputWrapper span:hover {\n  background: rgba(0,0,0,0.1);\n}\n.numInputWrapper span:active {\n  background: rgba(0,0,0,0.2);\n}\n.numInputWrapper span:after {\n  display: block;\n  content: \"\";\n  position: absolute;\n}\n.numInputWrapper span.arrowUp {\n  top: 0;\n  border-bottom: 0;\n}\n.numInputWrapper span.arrowUp:after {\n  border-left: 4px solid transparent;\n  border-right: 4px solid transparent;\n  border-bottom: 4px solid rgba(57,57,57,0.6);\n  top: 26%;\n}\n.numInputWrapper span.arrowDown {\n  top: 50%;\n}\n.numInputWrapper span.arrowDown:after {\n  border-left: 4px solid transparent;\n  border-right: 4px solid transparent;\n  border-top: 4px solid rgba(57,57,57,0.6);\n  top: 40%;\n}\n.numInputWrapper span svg {\n  width: inherit;\n  height: auto;\n}\n.numInputWrapper span svg path {\n  fill: rgba(0,0,0,0.5);\n}\n.numInputWrapper:hover {\n  background: rgba(0,0,0,0.05);\n}\n.numInputWrapper:hover span {\n  opacity: 1;\n}\n.flatpickr-current-month {\n  font-size: 135%;\n  line-height: inherit;\n  font-weight: 300;\n  color: inherit;\n  position: absolute;\n  width: 75%;\n  left: 12.5%;\n  padding: 7.48px 0 0 0;\n  line-height: 1;\n  height: 34px;\n  display: inline-block;\n  text-align: center;\n  -webkit-transform: translate3d(0px, 0px, 0px);\n          transform: translate3d(0px, 0px, 0px);\n}\n.flatpickr-current-month span.cur-month {\n  font-family: inherit;\n  font-weight: 700;\n  color: inherit;\n  display: inline-block;\n  margin-left: 0.5ch;\n  padding: 0;\n}\n.flatpickr-current-month span.cur-month:hover {\n  background: rgba(0,0,0,0.05);\n}\n.flatpickr-current-month .numInputWrapper {\n  width: 6ch;\n  width: 7ch\\0;\n  display: inline-block;\n}\n.flatpickr-current-month .numInputWrapper span.arrowUp:after {\n  border-bottom-color: rgba(0,0,0,0.9);\n}\n.flatpickr-current-month .numInputWrapper span.arrowDown:after {\n  border-top-color: rgba(0,0,0,0.9);\n}\n.flatpickr-current-month input.cur-year {\n  background: transparent;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  color: inherit;\n  cursor: text;\n  padding: 0 0 0 0.5ch;\n  margin: 0;\n  display: inline-block;\n  font-size: inherit;\n  font-family: inherit;\n  font-weight: 300;\n  line-height: inherit;\n  height: auto;\n  border: 0;\n  border-radius: 0;\n  vertical-align: initial;\n  -webkit-appearance: textfield;\n  -moz-appearance: textfield;\n  appearance: textfield;\n}\n.flatpickr-current-month input.cur-year:focus {\n  outline: 0;\n}\n.flatpickr-current-month input.cur-year[disabled],\n.flatpickr-current-month input.cur-year[disabled]:hover {\n  font-size: 100%;\n  color: rgba(0,0,0,0.5);\n  background: transparent;\n  pointer-events: none;\n}\n.flatpickr-current-month .flatpickr-monthDropdown-months {\n  appearance: menulist;\n  background: transparent;\n  border: none;\n  border-radius: 0;\n  box-sizing: border-box;\n  color: inherit;\n  cursor: pointer;\n  font-size: inherit;\n  font-family: inherit;\n  font-weight: 300;\n  height: auto;\n  line-height: inherit;\n  margin: -1px 0 0 0;\n  outline: none;\n  padding: 0 0 0 0.5ch;\n  position: relative;\n  vertical-align: initial;\n  -webkit-box-sizing: border-box;\n  -webkit-appearance: menulist;\n  -moz-appearance: menulist;\n  width: auto;\n}\n.flatpickr-current-month .flatpickr-monthDropdown-months:focus,\n.flatpickr-current-month .flatpickr-monthDropdown-months:active {\n  outline: none;\n}\n.flatpickr-current-month .flatpickr-monthDropdown-months:hover {\n  background: rgba(0,0,0,0.05);\n}\n.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month {\n  background-color: transparent;\n  outline: none;\n  padding: 0;\n}\n.flatpickr-weekdays {\n  background: transparent;\n  text-align: center;\n  overflow: hidden;\n  width: 100%;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: center;\n  -webkit-align-items: center;\n      -ms-flex-align: center;\n          align-items: center;\n  height: 28px;\n}\n.flatpickr-weekdays .flatpickr-weekdaycontainer {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n      -ms-flex: 1;\n          flex: 1;\n}\nspan.flatpickr-weekday {\n  cursor: default;\n  font-size: 90%;\n  background: transparent;\n  color: rgba(0,0,0,0.54);\n  line-height: 1;\n  margin: 0;\n  text-align: center;\n  display: block;\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n      -ms-flex: 1;\n          flex: 1;\n  font-weight: bolder;\n}\n.dayContainer,\n.flatpickr-weeks {\n  padding: 1px 0 0 0;\n}\n.flatpickr-days {\n  position: relative;\n  overflow: hidden;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: start;\n  -webkit-align-items: flex-start;\n      -ms-flex-align: start;\n          align-items: flex-start;\n  width: 307.875px;\n}\n.flatpickr-days:focus {\n  outline: 0;\n}\n.dayContainer {\n  padding: 0;\n  outline: 0;\n  text-align: left;\n  width: 307.875px;\n  min-width: 307.875px;\n  max-width: 307.875px;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  display: inline-block;\n  display: -ms-flexbox;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-flex-wrap: wrap;\n          flex-wrap: wrap;\n  -ms-flex-wrap: wrap;\n  -ms-flex-pack: justify;\n  -webkit-justify-content: space-around;\n          justify-content: space-around;\n  -webkit-transform: translate3d(0px, 0px, 0px);\n          transform: translate3d(0px, 0px, 0px);\n  opacity: 1;\n}\n.dayContainer + .dayContainer {\n  -webkit-box-shadow: -1px 0 0 #e6e6e6;\n          box-shadow: -1px 0 0 #e6e6e6;\n}\n.flatpickr-day {\n  background: none;\n  border: 1px solid transparent;\n  border-radius: 150px;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  color: #393939;\n  cursor: pointer;\n  font-weight: 400;\n  width: 14.2857143%;\n  -webkit-flex-basis: 14.2857143%;\n      -ms-flex-preferred-size: 14.2857143%;\n          flex-basis: 14.2857143%;\n  max-width: 39px;\n  height: 39px;\n  line-height: 39px;\n  margin: 0;\n  display: inline-block;\n  position: relative;\n  -webkit-box-pack: center;\n  -webkit-justify-content: center;\n      -ms-flex-pack: center;\n          justify-content: center;\n  text-align: center;\n}\n.flatpickr-day.inRange,\n.flatpickr-day.prevMonthDay.inRange,\n.flatpickr-day.nextMonthDay.inRange,\n.flatpickr-day.today.inRange,\n.flatpickr-day.prevMonthDay.today.inRange,\n.flatpickr-day.nextMonthDay.today.inRange,\n.flatpickr-day:hover,\n.flatpickr-day.prevMonthDay:hover,\n.flatpickr-day.nextMonthDay:hover,\n.flatpickr-day:focus,\n.flatpickr-day.prevMonthDay:focus,\n.flatpickr-day.nextMonthDay:focus {\n  cursor: pointer;\n  outline: 0;\n  background: #e6e6e6;\n  border-color: #e6e6e6;\n}\n.flatpickr-day.today {\n  border-color: #959ea9;\n}\n.flatpickr-day.today:hover,\n.flatpickr-day.today:focus {\n  border-color: #959ea9;\n  background: #959ea9;\n  color: #fff;\n}\n.flatpickr-day.selected,\n.flatpickr-day.startRange,\n.flatpickr-day.endRange,\n.flatpickr-day.selected.inRange,\n.flatpickr-day.startRange.inRange,\n.flatpickr-day.endRange.inRange,\n.flatpickr-day.selected:focus,\n.flatpickr-day.startRange:focus,\n.flatpickr-day.endRange:focus,\n.flatpickr-day.selected:hover,\n.flatpickr-day.startRange:hover,\n.flatpickr-day.endRange:hover,\n.flatpickr-day.selected.prevMonthDay,\n.flatpickr-day.startRange.prevMonthDay,\n.flatpickr-day.endRange.prevMonthDay,\n.flatpickr-day.selected.nextMonthDay,\n.flatpickr-day.startRange.nextMonthDay,\n.flatpickr-day.endRange.nextMonthDay {\n  background: #569ff7;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n  color: #fff;\n  border-color: #569ff7;\n}\n.flatpickr-day.selected.startRange,\n.flatpickr-day.startRange.startRange,\n.flatpickr-day.endRange.startRange {\n  border-radius: 50px 0 0 50px;\n}\n.flatpickr-day.selected.endRange,\n.flatpickr-day.startRange.endRange,\n.flatpickr-day.endRange.endRange {\n  border-radius: 0 50px 50px 0;\n}\n.flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n+1)),\n.flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n+1)),\n.flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n+1)) {\n  -webkit-box-shadow: -10px 0 0 #569ff7;\n          box-shadow: -10px 0 0 #569ff7;\n}\n.flatpickr-day.selected.startRange.endRange,\n.flatpickr-day.startRange.startRange.endRange,\n.flatpickr-day.endRange.startRange.endRange {\n  border-radius: 50px;\n}\n.flatpickr-day.inRange {\n  border-radius: 0;\n  -webkit-box-shadow: -5px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;\n          box-shadow: -5px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;\n}\n.flatpickr-day.flatpickr-disabled,\n.flatpickr-day.flatpickr-disabled:hover,\n.flatpickr-day.prevMonthDay,\n.flatpickr-day.nextMonthDay,\n.flatpickr-day.notAllowed,\n.flatpickr-day.notAllowed.prevMonthDay,\n.flatpickr-day.notAllowed.nextMonthDay {\n  color: rgba(57,57,57,0.3);\n  background: transparent;\n  border-color: transparent;\n  cursor: default;\n}\n.flatpickr-day.flatpickr-disabled,\n.flatpickr-day.flatpickr-disabled:hover {\n  cursor: not-allowed;\n  color: rgba(57,57,57,0.1);\n}\n.flatpickr-day.week.selected {\n  border-radius: 0;\n  -webkit-box-shadow: -5px 0 0 #569ff7, 5px 0 0 #569ff7;\n          box-shadow: -5px 0 0 #569ff7, 5px 0 0 #569ff7;\n}\n.flatpickr-day.hidden {\n  visibility: hidden;\n}\n.rangeMode .flatpickr-day {\n  margin-top: 1px;\n}\n.flatpickr-weekwrapper {\n  float: left;\n}\n.flatpickr-weekwrapper .flatpickr-weeks {\n  padding: 0 12px;\n  -webkit-box-shadow: 1px 0 0 #e6e6e6;\n          box-shadow: 1px 0 0 #e6e6e6;\n}\n.flatpickr-weekwrapper .flatpickr-weekday {\n  float: none;\n  width: 100%;\n  line-height: 28px;\n}\n.flatpickr-weekwrapper span.flatpickr-day,\n.flatpickr-weekwrapper span.flatpickr-day:hover {\n  display: block;\n  width: 100%;\n  max-width: none;\n  color: rgba(57,57,57,0.3);\n  background: transparent;\n  cursor: default;\n  border: none;\n}\n.flatpickr-innerContainer {\n  display: block;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  overflow: hidden;\n}\n.flatpickr-rContainer {\n  display: inline-block;\n  padding: 0;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n}\n.flatpickr-time {\n  text-align: center;\n  outline: 0;\n  display: block;\n  height: 0;\n  line-height: 40px;\n  max-height: 40px;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  overflow: hidden;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n}\n.flatpickr-time:after {\n  content: \"\";\n  display: table;\n  clear: both;\n}\n.flatpickr-time .numInputWrapper {\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n      -ms-flex: 1;\n          flex: 1;\n  width: 40%;\n  height: 40px;\n  float: left;\n}\n.flatpickr-time .numInputWrapper span.arrowUp:after {\n  border-bottom-color: #393939;\n}\n.flatpickr-time .numInputWrapper span.arrowDown:after {\n  border-top-color: #393939;\n}\n.flatpickr-time.hasSeconds .numInputWrapper {\n  width: 26%;\n}\n.flatpickr-time.time24hr .numInputWrapper {\n  width: 49%;\n}\n.flatpickr-time input {\n  background: transparent;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n  border: 0;\n  border-radius: 0;\n  text-align: center;\n  margin: 0;\n  padding: 0;\n  height: inherit;\n  line-height: inherit;\n  color: #393939;\n  font-size: 14px;\n  position: relative;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  -webkit-appearance: textfield;\n  -moz-appearance: textfield;\n  appearance: textfield;\n}\n.flatpickr-time input.flatpickr-hour {\n  font-weight: bold;\n}\n.flatpickr-time input.flatpickr-minute,\n.flatpickr-time input.flatpickr-second {\n  font-weight: 400;\n}\n.flatpickr-time input:focus {\n  outline: 0;\n  border: 0;\n}\n.flatpickr-time .flatpickr-time-separator,\n.flatpickr-time .flatpickr-am-pm {\n  height: inherit;\n  float: left;\n  line-height: inherit;\n  color: #393939;\n  font-weight: bold;\n  width: 2%;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  -webkit-align-self: center;\n      -ms-flex-item-align: center;\n          align-self: center;\n}\n.flatpickr-time .flatpickr-am-pm {\n  outline: 0;\n  width: 18%;\n  cursor: pointer;\n  text-align: center;\n  font-weight: 400;\n}\n.flatpickr-time input:hover,\n.flatpickr-time .flatpickr-am-pm:hover,\n.flatpickr-time input:focus,\n.flatpickr-time .flatpickr-am-pm:focus {\n  background: #eee;\n}\n.flatpickr-input[readonly] {\n  cursor: pointer;\n}\n@-webkit-keyframes fpFadeInDown {\n  from {\n    opacity: 0;\n    -webkit-transform: translate3d(0, -20px, 0);\n            transform: translate3d(0, -20px, 0);\n  }\n  to {\n    opacity: 1;\n    -webkit-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 0);\n  }\n}\n@keyframes fpFadeInDown {\n  from {\n    opacity: 0;\n    -webkit-transform: translate3d(0, -20px, 0);\n            transform: translate3d(0, -20px, 0);\n  }\n  to {\n    opacity: 1;\n    -webkit-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 0);\n  }\n}\n"
  },
  {
    "path": "vendor/assets/stylesheets/rails_admin/font-awesome.scss",
    "content": "/*!\n * Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)\n * Copyright 2022 Fonticons, Inc.\n */\n\n//= depend_on_asset \"rails_admin/fa-solid-900.woff2\"\n//= depend_on_asset \"rails_admin/fa-solid-900.ttf\"\n\n@font-face {\n  font-family: 'Font Awesome 6 Free';\n  font-style: normal;\n  font-weight: 900;\n  font-display: block;\n  src: asset-url(\"rails_admin/fa-solid-900.woff2\") format(\"woff2\"), asset-url(\"rails_admin/fa-solid-900.ttf\") format(\"truetype\"); }\n\n.fa,\n.fas,\n.fa-solid {\n  font-family: var(--fa-style-family, \"Font Awesome 6 Free\");\n  font-weight: var(--fa-style, 900); }\n\n.fa,\n.fas,\n.fa-solid,\n.far,\n.fa-regular,\n.fal,\n.fa-light,\n.fat,\n.fa-thin,\n.fad,\n.fa-duotone,\n.fab,\n.fa-brands {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: var(--fa-display, inline-block);\n  font-style: normal;\n  font-variant: normal;\n  line-height: 1;\n  text-rendering: auto; }\n\n.fa-1x {\n  font-size: 1em; }\n\n.fa-2x {\n  font-size: 2em; }\n\n.fa-3x {\n  font-size: 3em; }\n\n.fa-4x {\n  font-size: 4em; }\n\n.fa-5x {\n  font-size: 5em; }\n\n.fa-6x {\n  font-size: 6em; }\n\n.fa-7x {\n  font-size: 7em; }\n\n.fa-8x {\n  font-size: 8em; }\n\n.fa-9x {\n  font-size: 9em; }\n\n.fa-10x {\n  font-size: 10em; }\n\n.fa-2xs {\n  font-size: 0.625em;\n  line-height: 0.1em;\n  vertical-align: 0.225em; }\n\n.fa-xs {\n  font-size: 0.75em;\n  line-height: 0.08333em;\n  vertical-align: 0.125em; }\n\n.fa-sm {\n  font-size: 0.875em;\n  line-height: 0.07143em;\n  vertical-align: 0.05357em; }\n\n.fa-lg {\n  font-size: 1.25em;\n  line-height: 0.05em;\n  vertical-align: -0.075em; }\n\n.fa-xl {\n  font-size: 1.5em;\n  line-height: 0.04167em;\n  vertical-align: -0.125em; }\n\n.fa-2xl {\n  font-size: 2em;\n  line-height: 0.03125em;\n  vertical-align: -0.1875em; }\n\n.fa-fw {\n  text-align: center;\n  width: 1.25em; }\n\n.fa-ul {\n  list-style-type: none;\n  margin-left: var(--fa-li-margin, 2.5em);\n  padding-left: 0; }\n  .fa-ul > li {\n    position: relative; }\n\n.fa-li {\n  left: calc(var(--fa-li-width, 2em) * -1);\n  position: absolute;\n  text-align: center;\n  width: var(--fa-li-width, 2em);\n  line-height: inherit; }\n\n.fa-border {\n  border-color: var(--fa-border-color, #eee);\n  border-radius: var(--fa-border-radius, 0.1em);\n  border-style: var(--fa-border-style, solid);\n  border-width: var(--fa-border-width, 0.08em);\n  padding: var(--fa-border-padding, 0.2em 0.25em 0.15em); }\n\n.fa-pull-left {\n  float: left;\n  margin-right: var(--fa-pull-margin, 0.3em); }\n\n.fa-pull-right {\n  float: right;\n  margin-left: var(--fa-pull-margin, 0.3em); }\n\n.fa-beat {\n  -webkit-animation-name: fa-beat;\n          animation-name: fa-beat;\n  -webkit-animation-delay: var(--fa-animation-delay, 0);\n          animation-delay: var(--fa-animation-delay, 0);\n  -webkit-animation-direction: var(--fa-animation-direction, normal);\n          animation-direction: var(--fa-animation-direction, normal);\n  -webkit-animation-duration: var(--fa-animation-duration, 1s);\n          animation-duration: var(--fa-animation-duration, 1s);\n  -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n          animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n  -webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);\n          animation-timing-function: var(--fa-animation-timing, ease-in-out); }\n\n.fa-bounce {\n  -webkit-animation-name: fa-bounce;\n          animation-name: fa-bounce;\n  -webkit-animation-delay: var(--fa-animation-delay, 0);\n          animation-delay: var(--fa-animation-delay, 0);\n  -webkit-animation-direction: var(--fa-animation-direction, normal);\n          animation-direction: var(--fa-animation-direction, normal);\n  -webkit-animation-duration: var(--fa-animation-duration, 1s);\n          animation-duration: var(--fa-animation-duration, 1s);\n  -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n          animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n  -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));\n          animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1)); }\n\n.fa-fade {\n  -webkit-animation-name: fa-fade;\n          animation-name: fa-fade;\n  -webkit-animation-delay: var(--fa-animation-delay, 0);\n          animation-delay: var(--fa-animation-delay, 0);\n  -webkit-animation-direction: var(--fa-animation-direction, normal);\n          animation-direction: var(--fa-animation-direction, normal);\n  -webkit-animation-duration: var(--fa-animation-duration, 1s);\n          animation-duration: var(--fa-animation-duration, 1s);\n  -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n          animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n  -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\n          animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }\n\n.fa-beat-fade {\n  -webkit-animation-name: fa-beat-fade;\n          animation-name: fa-beat-fade;\n  -webkit-animation-delay: var(--fa-animation-delay, 0);\n          animation-delay: var(--fa-animation-delay, 0);\n  -webkit-animation-direction: var(--fa-animation-direction, normal);\n          animation-direction: var(--fa-animation-direction, normal);\n  -webkit-animation-duration: var(--fa-animation-duration, 1s);\n          animation-duration: var(--fa-animation-duration, 1s);\n  -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n          animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n  -webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));\n          animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1)); }\n\n.fa-flip {\n  -webkit-animation-name: fa-flip;\n          animation-name: fa-flip;\n  -webkit-animation-delay: var(--fa-animation-delay, 0);\n          animation-delay: var(--fa-animation-delay, 0);\n  -webkit-animation-direction: var(--fa-animation-direction, normal);\n          animation-direction: var(--fa-animation-direction, normal);\n  -webkit-animation-duration: var(--fa-animation-duration, 1s);\n          animation-duration: var(--fa-animation-duration, 1s);\n  -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n          animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n  -webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);\n          animation-timing-function: var(--fa-animation-timing, ease-in-out); }\n\n.fa-shake {\n  -webkit-animation-name: fa-shake;\n          animation-name: fa-shake;\n  -webkit-animation-delay: var(--fa-animation-delay, 0);\n          animation-delay: var(--fa-animation-delay, 0);\n  -webkit-animation-direction: var(--fa-animation-direction, normal);\n          animation-direction: var(--fa-animation-direction, normal);\n  -webkit-animation-duration: var(--fa-animation-duration, 1s);\n          animation-duration: var(--fa-animation-duration, 1s);\n  -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n          animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n  -webkit-animation-timing-function: var(--fa-animation-timing, linear);\n          animation-timing-function: var(--fa-animation-timing, linear); }\n\n.fa-spin {\n  -webkit-animation-name: fa-spin;\n          animation-name: fa-spin;\n  -webkit-animation-delay: var(--fa-animation-delay, 0);\n          animation-delay: var(--fa-animation-delay, 0);\n  -webkit-animation-direction: var(--fa-animation-direction, normal);\n          animation-direction: var(--fa-animation-direction, normal);\n  -webkit-animation-duration: var(--fa-animation-duration, 2s);\n          animation-duration: var(--fa-animation-duration, 2s);\n  -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n          animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n  -webkit-animation-timing-function: var(--fa-animation-timing, linear);\n          animation-timing-function: var(--fa-animation-timing, linear); }\n\n.fa-spin-reverse {\n  --fa-animation-direction: reverse; }\n\n.fa-pulse,\n.fa-spin-pulse {\n  -webkit-animation-name: fa-spin;\n          animation-name: fa-spin;\n  -webkit-animation-direction: var(--fa-animation-direction, normal);\n          animation-direction: var(--fa-animation-direction, normal);\n  -webkit-animation-duration: var(--fa-animation-duration, 1s);\n          animation-duration: var(--fa-animation-duration, 1s);\n  -webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n          animation-iteration-count: var(--fa-animation-iteration-count, infinite);\n  -webkit-animation-timing-function: var(--fa-animation-timing, steps(8));\n          animation-timing-function: var(--fa-animation-timing, steps(8)); }\n\n@media (prefers-reduced-motion: reduce) {\n  .fa-beat,\n  .fa-bounce,\n  .fa-fade,\n  .fa-beat-fade,\n  .fa-flip,\n  .fa-pulse,\n  .fa-shake,\n  .fa-spin,\n  .fa-spin-pulse {\n    -webkit-animation-delay: -1ms;\n            animation-delay: -1ms;\n    -webkit-animation-duration: 1ms;\n            animation-duration: 1ms;\n    -webkit-animation-iteration-count: 1;\n            animation-iteration-count: 1;\n    transition-delay: 0s;\n    transition-duration: 0s; } }\n\n@-webkit-keyframes fa-beat {\n  0%, 90% {\n    -webkit-transform: scale(1);\n            transform: scale(1); }\n  45% {\n    -webkit-transform: scale(var(--fa-beat-scale, 1.25));\n            transform: scale(var(--fa-beat-scale, 1.25)); } }\n\n@keyframes fa-beat {\n  0%, 90% {\n    -webkit-transform: scale(1);\n            transform: scale(1); }\n  45% {\n    -webkit-transform: scale(var(--fa-beat-scale, 1.25));\n            transform: scale(var(--fa-beat-scale, 1.25)); } }\n\n@-webkit-keyframes fa-bounce {\n  0% {\n    -webkit-transform: scale(1, 1) translateY(0);\n            transform: scale(1, 1) translateY(0); }\n  10% {\n    -webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\n            transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); }\n  30% {\n    -webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\n            transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); }\n  50% {\n    -webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\n            transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); }\n  57% {\n    -webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\n            transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); }\n  64% {\n    -webkit-transform: scale(1, 1) translateY(0);\n            transform: scale(1, 1) translateY(0); }\n  100% {\n    -webkit-transform: scale(1, 1) translateY(0);\n            transform: scale(1, 1) translateY(0); } }\n\n@keyframes fa-bounce {\n  0% {\n    -webkit-transform: scale(1, 1) translateY(0);\n            transform: scale(1, 1) translateY(0); }\n  10% {\n    -webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);\n            transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0); }\n  30% {\n    -webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));\n            transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em)); }\n  50% {\n    -webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);\n            transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0); }\n  57% {\n    -webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));\n            transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em)); }\n  64% {\n    -webkit-transform: scale(1, 1) translateY(0);\n            transform: scale(1, 1) translateY(0); }\n  100% {\n    -webkit-transform: scale(1, 1) translateY(0);\n            transform: scale(1, 1) translateY(0); } }\n\n@-webkit-keyframes fa-fade {\n  50% {\n    opacity: var(--fa-fade-opacity, 0.4); } }\n\n@keyframes fa-fade {\n  50% {\n    opacity: var(--fa-fade-opacity, 0.4); } }\n\n@-webkit-keyframes fa-beat-fade {\n  0%, 100% {\n    opacity: var(--fa-beat-fade-opacity, 0.4);\n    -webkit-transform: scale(1);\n            transform: scale(1); }\n  50% {\n    opacity: 1;\n    -webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));\n            transform: scale(var(--fa-beat-fade-scale, 1.125)); } }\n\n@keyframes fa-beat-fade {\n  0%, 100% {\n    opacity: var(--fa-beat-fade-opacity, 0.4);\n    -webkit-transform: scale(1);\n            transform: scale(1); }\n  50% {\n    opacity: 1;\n    -webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));\n            transform: scale(var(--fa-beat-fade-scale, 1.125)); } }\n\n@-webkit-keyframes fa-flip {\n  50% {\n    -webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\n            transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } }\n\n@keyframes fa-flip {\n  50% {\n    -webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));\n            transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg)); } }\n\n@-webkit-keyframes fa-shake {\n  0% {\n    -webkit-transform: rotate(-15deg);\n            transform: rotate(-15deg); }\n  4% {\n    -webkit-transform: rotate(15deg);\n            transform: rotate(15deg); }\n  8%, 24% {\n    -webkit-transform: rotate(-18deg);\n            transform: rotate(-18deg); }\n  12%, 28% {\n    -webkit-transform: rotate(18deg);\n            transform: rotate(18deg); }\n  16% {\n    -webkit-transform: rotate(-22deg);\n            transform: rotate(-22deg); }\n  20% {\n    -webkit-transform: rotate(22deg);\n            transform: rotate(22deg); }\n  32% {\n    -webkit-transform: rotate(-12deg);\n            transform: rotate(-12deg); }\n  36% {\n    -webkit-transform: rotate(12deg);\n            transform: rotate(12deg); }\n  40%, 100% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); } }\n\n@keyframes fa-shake {\n  0% {\n    -webkit-transform: rotate(-15deg);\n            transform: rotate(-15deg); }\n  4% {\n    -webkit-transform: rotate(15deg);\n            transform: rotate(15deg); }\n  8%, 24% {\n    -webkit-transform: rotate(-18deg);\n            transform: rotate(-18deg); }\n  12%, 28% {\n    -webkit-transform: rotate(18deg);\n            transform: rotate(18deg); }\n  16% {\n    -webkit-transform: rotate(-22deg);\n            transform: rotate(-22deg); }\n  20% {\n    -webkit-transform: rotate(22deg);\n            transform: rotate(22deg); }\n  32% {\n    -webkit-transform: rotate(-12deg);\n            transform: rotate(-12deg); }\n  36% {\n    -webkit-transform: rotate(12deg);\n            transform: rotate(12deg); }\n  40%, 100% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); } }\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n  -webkit-transform: rotate(90deg);\n          transform: rotate(90deg); }\n\n.fa-rotate-180 {\n  -webkit-transform: rotate(180deg);\n          transform: rotate(180deg); }\n\n.fa-rotate-270 {\n  -webkit-transform: rotate(270deg);\n          transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n  -webkit-transform: scale(-1, 1);\n          transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n  -webkit-transform: scale(1, -1);\n          transform: scale(1, -1); }\n\n.fa-flip-both,\n.fa-flip-horizontal.fa-flip-vertical {\n  -webkit-transform: scale(-1, -1);\n          transform: scale(-1, -1); }\n\n.fa-rotate-by {\n  -webkit-transform: rotate(var(--fa-rotate-angle, none));\n          transform: rotate(var(--fa-rotate-angle, none)); }\n\n.fa-stack {\n  display: inline-block;\n  height: 2em;\n  line-height: 2em;\n  position: relative;\n  vertical-align: middle;\n  width: 2.5em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n  left: 0;\n  position: absolute;\n  text-align: center;\n  width: 100%;\n  z-index: var(--fa-stack-z-index, auto); }\n\n.fa-stack-1x {\n  line-height: inherit; }\n\n.fa-stack-2x {\n  font-size: 2em; }\n\n.fa-inverse {\n  color: var(--fa-inverse, #fff); }\n\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\nreaders do not read off random characters that represent icons */\n.fa-0::before {\n  content: \"\\30\"; }\n\n.fa-1::before {\n  content: \"\\31\"; }\n\n.fa-2::before {\n  content: \"\\32\"; }\n\n.fa-3::before {\n  content: \"\\33\"; }\n\n.fa-4::before {\n  content: \"\\34\"; }\n\n.fa-5::before {\n  content: \"\\35\"; }\n\n.fa-6::before {\n  content: \"\\36\"; }\n\n.fa-7::before {\n  content: \"\\37\"; }\n\n.fa-8::before {\n  content: \"\\38\"; }\n\n.fa-9::before {\n  content: \"\\39\"; }\n\n.fa-a::before {\n  content: \"\\41\"; }\n\n.fa-address-book::before {\n  content: \"\\f2b9\"; }\n\n.fa-contact-book::before {\n  content: \"\\f2b9\"; }\n\n.fa-address-card::before {\n  content: \"\\f2bb\"; }\n\n.fa-contact-card::before {\n  content: \"\\f2bb\"; }\n\n.fa-vcard::before {\n  content: \"\\f2bb\"; }\n\n.fa-align-center::before {\n  content: \"\\f037\"; }\n\n.fa-align-justify::before {\n  content: \"\\f039\"; }\n\n.fa-align-left::before {\n  content: \"\\f036\"; }\n\n.fa-align-right::before {\n  content: \"\\f038\"; }\n\n.fa-anchor::before {\n  content: \"\\f13d\"; }\n\n.fa-anchor-circle-check::before {\n  content: \"\\e4aa\"; }\n\n.fa-anchor-circle-exclamation::before {\n  content: \"\\e4ab\"; }\n\n.fa-anchor-circle-xmark::before {\n  content: \"\\e4ac\"; }\n\n.fa-anchor-lock::before {\n  content: \"\\e4ad\"; }\n\n.fa-angle-down::before {\n  content: \"\\f107\"; }\n\n.fa-angle-left::before {\n  content: \"\\f104\"; }\n\n.fa-angle-right::before {\n  content: \"\\f105\"; }\n\n.fa-angle-up::before {\n  content: \"\\f106\"; }\n\n.fa-angles-down::before {\n  content: \"\\f103\"; }\n\n.fa-angle-double-down::before {\n  content: \"\\f103\"; }\n\n.fa-angles-left::before {\n  content: \"\\f100\"; }\n\n.fa-angle-double-left::before {\n  content: \"\\f100\"; }\n\n.fa-angles-right::before {\n  content: \"\\f101\"; }\n\n.fa-angle-double-right::before {\n  content: \"\\f101\"; }\n\n.fa-angles-up::before {\n  content: \"\\f102\"; }\n\n.fa-angle-double-up::before {\n  content: \"\\f102\"; }\n\n.fa-ankh::before {\n  content: \"\\f644\"; }\n\n.fa-apple-whole::before {\n  content: \"\\f5d1\"; }\n\n.fa-apple-alt::before {\n  content: \"\\f5d1\"; }\n\n.fa-archway::before {\n  content: \"\\f557\"; }\n\n.fa-arrow-down::before {\n  content: \"\\f063\"; }\n\n.fa-arrow-down-1-9::before {\n  content: \"\\f162\"; }\n\n.fa-sort-numeric-asc::before {\n  content: \"\\f162\"; }\n\n.fa-sort-numeric-down::before {\n  content: \"\\f162\"; }\n\n.fa-arrow-down-9-1::before {\n  content: \"\\f886\"; }\n\n.fa-sort-numeric-desc::before {\n  content: \"\\f886\"; }\n\n.fa-sort-numeric-down-alt::before {\n  content: \"\\f886\"; }\n\n.fa-arrow-down-a-z::before {\n  content: \"\\f15d\"; }\n\n.fa-sort-alpha-asc::before {\n  content: \"\\f15d\"; }\n\n.fa-sort-alpha-down::before {\n  content: \"\\f15d\"; }\n\n.fa-arrow-down-long::before {\n  content: \"\\f175\"; }\n\n.fa-long-arrow-down::before {\n  content: \"\\f175\"; }\n\n.fa-arrow-down-short-wide::before {\n  content: \"\\f884\"; }\n\n.fa-sort-amount-desc::before {\n  content: \"\\f884\"; }\n\n.fa-sort-amount-down-alt::before {\n  content: \"\\f884\"; }\n\n.fa-arrow-down-up-across-line::before {\n  content: \"\\e4af\"; }\n\n.fa-arrow-down-up-lock::before {\n  content: \"\\e4b0\"; }\n\n.fa-arrow-down-wide-short::before {\n  content: \"\\f160\"; }\n\n.fa-sort-amount-asc::before {\n  content: \"\\f160\"; }\n\n.fa-sort-amount-down::before {\n  content: \"\\f160\"; }\n\n.fa-arrow-down-z-a::before {\n  content: \"\\f881\"; }\n\n.fa-sort-alpha-desc::before {\n  content: \"\\f881\"; }\n\n.fa-sort-alpha-down-alt::before {\n  content: \"\\f881\"; }\n\n.fa-arrow-left::before {\n  content: \"\\f060\"; }\n\n.fa-arrow-left-long::before {\n  content: \"\\f177\"; }\n\n.fa-long-arrow-left::before {\n  content: \"\\f177\"; }\n\n.fa-arrow-pointer::before {\n  content: \"\\f245\"; }\n\n.fa-mouse-pointer::before {\n  content: \"\\f245\"; }\n\n.fa-arrow-right::before {\n  content: \"\\f061\"; }\n\n.fa-arrow-right-arrow-left::before {\n  content: \"\\f0ec\"; }\n\n.fa-exchange::before {\n  content: \"\\f0ec\"; }\n\n.fa-arrow-right-from-bracket::before {\n  content: \"\\f08b\"; }\n\n.fa-sign-out::before {\n  content: \"\\f08b\"; }\n\n.fa-arrow-right-long::before {\n  content: \"\\f178\"; }\n\n.fa-long-arrow-right::before {\n  content: \"\\f178\"; }\n\n.fa-arrow-right-to-bracket::before {\n  content: \"\\f090\"; }\n\n.fa-sign-in::before {\n  content: \"\\f090\"; }\n\n.fa-arrow-right-to-city::before {\n  content: \"\\e4b3\"; }\n\n.fa-arrow-rotate-left::before {\n  content: \"\\f0e2\"; }\n\n.fa-arrow-left-rotate::before {\n  content: \"\\f0e2\"; }\n\n.fa-arrow-rotate-back::before {\n  content: \"\\f0e2\"; }\n\n.fa-arrow-rotate-backward::before {\n  content: \"\\f0e2\"; }\n\n.fa-undo::before {\n  content: \"\\f0e2\"; }\n\n.fa-arrow-rotate-right::before {\n  content: \"\\f01e\"; }\n\n.fa-arrow-right-rotate::before {\n  content: \"\\f01e\"; }\n\n.fa-arrow-rotate-forward::before {\n  content: \"\\f01e\"; }\n\n.fa-redo::before {\n  content: \"\\f01e\"; }\n\n.fa-arrow-trend-down::before {\n  content: \"\\e097\"; }\n\n.fa-arrow-trend-up::before {\n  content: \"\\e098\"; }\n\n.fa-arrow-turn-down::before {\n  content: \"\\f149\"; }\n\n.fa-level-down::before {\n  content: \"\\f149\"; }\n\n.fa-arrow-turn-up::before {\n  content: \"\\f148\"; }\n\n.fa-level-up::before {\n  content: \"\\f148\"; }\n\n.fa-arrow-up::before {\n  content: \"\\f062\"; }\n\n.fa-arrow-up-1-9::before {\n  content: \"\\f163\"; }\n\n.fa-sort-numeric-up::before {\n  content: \"\\f163\"; }\n\n.fa-arrow-up-9-1::before {\n  content: \"\\f887\"; }\n\n.fa-sort-numeric-up-alt::before {\n  content: \"\\f887\"; }\n\n.fa-arrow-up-a-z::before {\n  content: \"\\f15e\"; }\n\n.fa-sort-alpha-up::before {\n  content: \"\\f15e\"; }\n\n.fa-arrow-up-from-bracket::before {\n  content: \"\\e09a\"; }\n\n.fa-arrow-up-from-ground-water::before {\n  content: \"\\e4b5\"; }\n\n.fa-arrow-up-from-water-pump::before {\n  content: \"\\e4b6\"; }\n\n.fa-arrow-up-long::before {\n  content: \"\\f176\"; }\n\n.fa-long-arrow-up::before {\n  content: \"\\f176\"; }\n\n.fa-arrow-up-right-dots::before {\n  content: \"\\e4b7\"; }\n\n.fa-arrow-up-right-from-square::before {\n  content: \"\\f08e\"; }\n\n.fa-external-link::before {\n  content: \"\\f08e\"; }\n\n.fa-arrow-up-short-wide::before {\n  content: \"\\f885\"; }\n\n.fa-sort-amount-up-alt::before {\n  content: \"\\f885\"; }\n\n.fa-arrow-up-wide-short::before {\n  content: \"\\f161\"; }\n\n.fa-sort-amount-up::before {\n  content: \"\\f161\"; }\n\n.fa-arrow-up-z-a::before {\n  content: \"\\f882\"; }\n\n.fa-sort-alpha-up-alt::before {\n  content: \"\\f882\"; }\n\n.fa-arrows-down-to-line::before {\n  content: \"\\e4b8\"; }\n\n.fa-arrows-down-to-people::before {\n  content: \"\\e4b9\"; }\n\n.fa-arrows-left-right::before {\n  content: \"\\f07e\"; }\n\n.fa-arrows-h::before {\n  content: \"\\f07e\"; }\n\n.fa-arrows-left-right-to-line::before {\n  content: \"\\e4ba\"; }\n\n.fa-arrows-rotate::before {\n  content: \"\\f021\"; }\n\n.fa-refresh::before {\n  content: \"\\f021\"; }\n\n.fa-sync::before {\n  content: \"\\f021\"; }\n\n.fa-arrows-spin::before {\n  content: \"\\e4bb\"; }\n\n.fa-arrows-split-up-and-left::before {\n  content: \"\\e4bc\"; }\n\n.fa-arrows-to-circle::before {\n  content: \"\\e4bd\"; }\n\n.fa-arrows-to-dot::before {\n  content: \"\\e4be\"; }\n\n.fa-arrows-to-eye::before {\n  content: \"\\e4bf\"; }\n\n.fa-arrows-turn-right::before {\n  content: \"\\e4c0\"; }\n\n.fa-arrows-turn-to-dots::before {\n  content: \"\\e4c1\"; }\n\n.fa-arrows-up-down::before {\n  content: \"\\f07d\"; }\n\n.fa-arrows-v::before {\n  content: \"\\f07d\"; }\n\n.fa-arrows-up-down-left-right::before {\n  content: \"\\f047\"; }\n\n.fa-arrows::before {\n  content: \"\\f047\"; }\n\n.fa-arrows-up-to-line::before {\n  content: \"\\e4c2\"; }\n\n.fa-asterisk::before {\n  content: \"\\2a\"; }\n\n.fa-at::before {\n  content: \"\\40\"; }\n\n.fa-atom::before {\n  content: \"\\f5d2\"; }\n\n.fa-audio-description::before {\n  content: \"\\f29e\"; }\n\n.fa-austral-sign::before {\n  content: \"\\e0a9\"; }\n\n.fa-award::before {\n  content: \"\\f559\"; }\n\n.fa-b::before {\n  content: \"\\42\"; }\n\n.fa-baby::before {\n  content: \"\\f77c\"; }\n\n.fa-baby-carriage::before {\n  content: \"\\f77d\"; }\n\n.fa-carriage-baby::before {\n  content: \"\\f77d\"; }\n\n.fa-backward::before {\n  content: \"\\f04a\"; }\n\n.fa-backward-fast::before {\n  content: \"\\f049\"; }\n\n.fa-fast-backward::before {\n  content: \"\\f049\"; }\n\n.fa-backward-step::before {\n  content: \"\\f048\"; }\n\n.fa-step-backward::before {\n  content: \"\\f048\"; }\n\n.fa-bacon::before {\n  content: \"\\f7e5\"; }\n\n.fa-bacteria::before {\n  content: \"\\e059\"; }\n\n.fa-bacterium::before {\n  content: \"\\e05a\"; }\n\n.fa-bag-shopping::before {\n  content: \"\\f290\"; }\n\n.fa-shopping-bag::before {\n  content: \"\\f290\"; }\n\n.fa-bahai::before {\n  content: \"\\f666\"; }\n\n.fa-baht-sign::before {\n  content: \"\\e0ac\"; }\n\n.fa-ban::before {\n  content: \"\\f05e\"; }\n\n.fa-cancel::before {\n  content: \"\\f05e\"; }\n\n.fa-ban-smoking::before {\n  content: \"\\f54d\"; }\n\n.fa-smoking-ban::before {\n  content: \"\\f54d\"; }\n\n.fa-bandage::before {\n  content: \"\\f462\"; }\n\n.fa-band-aid::before {\n  content: \"\\f462\"; }\n\n.fa-barcode::before {\n  content: \"\\f02a\"; }\n\n.fa-bars::before {\n  content: \"\\f0c9\"; }\n\n.fa-navicon::before {\n  content: \"\\f0c9\"; }\n\n.fa-bars-progress::before {\n  content: \"\\f828\"; }\n\n.fa-tasks-alt::before {\n  content: \"\\f828\"; }\n\n.fa-bars-staggered::before {\n  content: \"\\f550\"; }\n\n.fa-reorder::before {\n  content: \"\\f550\"; }\n\n.fa-stream::before {\n  content: \"\\f550\"; }\n\n.fa-baseball::before {\n  content: \"\\f433\"; }\n\n.fa-baseball-ball::before {\n  content: \"\\f433\"; }\n\n.fa-baseball-bat-ball::before {\n  content: \"\\f432\"; }\n\n.fa-basket-shopping::before {\n  content: \"\\f291\"; }\n\n.fa-shopping-basket::before {\n  content: \"\\f291\"; }\n\n.fa-basketball::before {\n  content: \"\\f434\"; }\n\n.fa-basketball-ball::before {\n  content: \"\\f434\"; }\n\n.fa-bath::before {\n  content: \"\\f2cd\"; }\n\n.fa-bathtub::before {\n  content: \"\\f2cd\"; }\n\n.fa-battery-empty::before {\n  content: \"\\f244\"; }\n\n.fa-battery-0::before {\n  content: \"\\f244\"; }\n\n.fa-battery-full::before {\n  content: \"\\f240\"; }\n\n.fa-battery::before {\n  content: \"\\f240\"; }\n\n.fa-battery-5::before {\n  content: \"\\f240\"; }\n\n.fa-battery-half::before {\n  content: \"\\f242\"; }\n\n.fa-battery-3::before {\n  content: \"\\f242\"; }\n\n.fa-battery-quarter::before {\n  content: \"\\f243\"; }\n\n.fa-battery-2::before {\n  content: \"\\f243\"; }\n\n.fa-battery-three-quarters::before {\n  content: \"\\f241\"; }\n\n.fa-battery-4::before {\n  content: \"\\f241\"; }\n\n.fa-bed::before {\n  content: \"\\f236\"; }\n\n.fa-bed-pulse::before {\n  content: \"\\f487\"; }\n\n.fa-procedures::before {\n  content: \"\\f487\"; }\n\n.fa-beer-mug-empty::before {\n  content: \"\\f0fc\"; }\n\n.fa-beer::before {\n  content: \"\\f0fc\"; }\n\n.fa-bell::before {\n  content: \"\\f0f3\"; }\n\n.fa-bell-concierge::before {\n  content: \"\\f562\"; }\n\n.fa-concierge-bell::before {\n  content: \"\\f562\"; }\n\n.fa-bell-slash::before {\n  content: \"\\f1f6\"; }\n\n.fa-bezier-curve::before {\n  content: \"\\f55b\"; }\n\n.fa-bicycle::before {\n  content: \"\\f206\"; }\n\n.fa-binoculars::before {\n  content: \"\\f1e5\"; }\n\n.fa-biohazard::before {\n  content: \"\\f780\"; }\n\n.fa-bitcoin-sign::before {\n  content: \"\\e0b4\"; }\n\n.fa-blender::before {\n  content: \"\\f517\"; }\n\n.fa-blender-phone::before {\n  content: \"\\f6b6\"; }\n\n.fa-blog::before {\n  content: \"\\f781\"; }\n\n.fa-bold::before {\n  content: \"\\f032\"; }\n\n.fa-bolt::before {\n  content: \"\\f0e7\"; }\n\n.fa-zap::before {\n  content: \"\\f0e7\"; }\n\n.fa-bolt-lightning::before {\n  content: \"\\e0b7\"; }\n\n.fa-bomb::before {\n  content: \"\\f1e2\"; }\n\n.fa-bone::before {\n  content: \"\\f5d7\"; }\n\n.fa-bong::before {\n  content: \"\\f55c\"; }\n\n.fa-book::before {\n  content: \"\\f02d\"; }\n\n.fa-book-atlas::before {\n  content: \"\\f558\"; }\n\n.fa-atlas::before {\n  content: \"\\f558\"; }\n\n.fa-book-bible::before {\n  content: \"\\f647\"; }\n\n.fa-bible::before {\n  content: \"\\f647\"; }\n\n.fa-book-bookmark::before {\n  content: \"\\e0bb\"; }\n\n.fa-book-journal-whills::before {\n  content: \"\\f66a\"; }\n\n.fa-journal-whills::before {\n  content: \"\\f66a\"; }\n\n.fa-book-medical::before {\n  content: \"\\f7e6\"; }\n\n.fa-book-open::before {\n  content: \"\\f518\"; }\n\n.fa-book-open-reader::before {\n  content: \"\\f5da\"; }\n\n.fa-book-reader::before {\n  content: \"\\f5da\"; }\n\n.fa-book-quran::before {\n  content: \"\\f687\"; }\n\n.fa-quran::before {\n  content: \"\\f687\"; }\n\n.fa-book-skull::before {\n  content: \"\\f6b7\"; }\n\n.fa-book-dead::before {\n  content: \"\\f6b7\"; }\n\n.fa-bookmark::before {\n  content: \"\\f02e\"; }\n\n.fa-border-all::before {\n  content: \"\\f84c\"; }\n\n.fa-border-none::before {\n  content: \"\\f850\"; }\n\n.fa-border-top-left::before {\n  content: \"\\f853\"; }\n\n.fa-border-style::before {\n  content: \"\\f853\"; }\n\n.fa-bore-hole::before {\n  content: \"\\e4c3\"; }\n\n.fa-bottle-droplet::before {\n  content: \"\\e4c4\"; }\n\n.fa-bottle-water::before {\n  content: \"\\e4c5\"; }\n\n.fa-bowl-food::before {\n  content: \"\\e4c6\"; }\n\n.fa-bowl-rice::before {\n  content: \"\\e2eb\"; }\n\n.fa-bowling-ball::before {\n  content: \"\\f436\"; }\n\n.fa-box::before {\n  content: \"\\f466\"; }\n\n.fa-box-archive::before {\n  content: \"\\f187\"; }\n\n.fa-archive::before {\n  content: \"\\f187\"; }\n\n.fa-box-open::before {\n  content: \"\\f49e\"; }\n\n.fa-box-tissue::before {\n  content: \"\\e05b\"; }\n\n.fa-boxes-packing::before {\n  content: \"\\e4c7\"; }\n\n.fa-boxes-stacked::before {\n  content: \"\\f468\"; }\n\n.fa-boxes::before {\n  content: \"\\f468\"; }\n\n.fa-boxes-alt::before {\n  content: \"\\f468\"; }\n\n.fa-braille::before {\n  content: \"\\f2a1\"; }\n\n.fa-brain::before {\n  content: \"\\f5dc\"; }\n\n.fa-brazilian-real-sign::before {\n  content: \"\\e46c\"; }\n\n.fa-bread-slice::before {\n  content: \"\\f7ec\"; }\n\n.fa-bridge::before {\n  content: \"\\e4c8\"; }\n\n.fa-bridge-circle-check::before {\n  content: \"\\e4c9\"; }\n\n.fa-bridge-circle-exclamation::before {\n  content: \"\\e4ca\"; }\n\n.fa-bridge-circle-xmark::before {\n  content: \"\\e4cb\"; }\n\n.fa-bridge-lock::before {\n  content: \"\\e4cc\"; }\n\n.fa-bridge-water::before {\n  content: \"\\e4ce\"; }\n\n.fa-briefcase::before {\n  content: \"\\f0b1\"; }\n\n.fa-briefcase-medical::before {\n  content: \"\\f469\"; }\n\n.fa-broom::before {\n  content: \"\\f51a\"; }\n\n.fa-broom-ball::before {\n  content: \"\\f458\"; }\n\n.fa-quidditch::before {\n  content: \"\\f458\"; }\n\n.fa-quidditch-broom-ball::before {\n  content: \"\\f458\"; }\n\n.fa-brush::before {\n  content: \"\\f55d\"; }\n\n.fa-bucket::before {\n  content: \"\\e4cf\"; }\n\n.fa-bug::before {\n  content: \"\\f188\"; }\n\n.fa-bug-slash::before {\n  content: \"\\e490\"; }\n\n.fa-bugs::before {\n  content: \"\\e4d0\"; }\n\n.fa-building::before {\n  content: \"\\f1ad\"; }\n\n.fa-building-circle-arrow-right::before {\n  content: \"\\e4d1\"; }\n\n.fa-building-circle-check::before {\n  content: \"\\e4d2\"; }\n\n.fa-building-circle-exclamation::before {\n  content: \"\\e4d3\"; }\n\n.fa-building-circle-xmark::before {\n  content: \"\\e4d4\"; }\n\n.fa-building-columns::before {\n  content: \"\\f19c\"; }\n\n.fa-bank::before {\n  content: \"\\f19c\"; }\n\n.fa-institution::before {\n  content: \"\\f19c\"; }\n\n.fa-museum::before {\n  content: \"\\f19c\"; }\n\n.fa-university::before {\n  content: \"\\f19c\"; }\n\n.fa-building-flag::before {\n  content: \"\\e4d5\"; }\n\n.fa-building-lock::before {\n  content: \"\\e4d6\"; }\n\n.fa-building-ngo::before {\n  content: \"\\e4d7\"; }\n\n.fa-building-shield::before {\n  content: \"\\e4d8\"; }\n\n.fa-building-un::before {\n  content: \"\\e4d9\"; }\n\n.fa-building-user::before {\n  content: \"\\e4da\"; }\n\n.fa-building-wheat::before {\n  content: \"\\e4db\"; }\n\n.fa-bullhorn::before {\n  content: \"\\f0a1\"; }\n\n.fa-bullseye::before {\n  content: \"\\f140\"; }\n\n.fa-burger::before {\n  content: \"\\f805\"; }\n\n.fa-hamburger::before {\n  content: \"\\f805\"; }\n\n.fa-burst::before {\n  content: \"\\e4dc\"; }\n\n.fa-bus::before {\n  content: \"\\f207\"; }\n\n.fa-bus-simple::before {\n  content: \"\\f55e\"; }\n\n.fa-bus-alt::before {\n  content: \"\\f55e\"; }\n\n.fa-business-time::before {\n  content: \"\\f64a\"; }\n\n.fa-briefcase-clock::before {\n  content: \"\\f64a\"; }\n\n.fa-c::before {\n  content: \"\\43\"; }\n\n.fa-cake-candles::before {\n  content: \"\\f1fd\"; }\n\n.fa-birthday-cake::before {\n  content: \"\\f1fd\"; }\n\n.fa-cake::before {\n  content: \"\\f1fd\"; }\n\n.fa-calculator::before {\n  content: \"\\f1ec\"; }\n\n.fa-calendar::before {\n  content: \"\\f133\"; }\n\n.fa-calendar-check::before {\n  content: \"\\f274\"; }\n\n.fa-calendar-day::before {\n  content: \"\\f783\"; }\n\n.fa-calendar-days::before {\n  content: \"\\f073\"; }\n\n.fa-calendar-alt::before {\n  content: \"\\f073\"; }\n\n.fa-calendar-minus::before {\n  content: \"\\f272\"; }\n\n.fa-calendar-plus::before {\n  content: \"\\f271\"; }\n\n.fa-calendar-week::before {\n  content: \"\\f784\"; }\n\n.fa-calendar-xmark::before {\n  content: \"\\f273\"; }\n\n.fa-calendar-times::before {\n  content: \"\\f273\"; }\n\n.fa-camera::before {\n  content: \"\\f030\"; }\n\n.fa-camera-alt::before {\n  content: \"\\f030\"; }\n\n.fa-camera-retro::before {\n  content: \"\\f083\"; }\n\n.fa-camera-rotate::before {\n  content: \"\\e0d8\"; }\n\n.fa-campground::before {\n  content: \"\\f6bb\"; }\n\n.fa-candy-cane::before {\n  content: \"\\f786\"; }\n\n.fa-cannabis::before {\n  content: \"\\f55f\"; }\n\n.fa-capsules::before {\n  content: \"\\f46b\"; }\n\n.fa-car::before {\n  content: \"\\f1b9\"; }\n\n.fa-automobile::before {\n  content: \"\\f1b9\"; }\n\n.fa-car-battery::before {\n  content: \"\\f5df\"; }\n\n.fa-battery-car::before {\n  content: \"\\f5df\"; }\n\n.fa-car-burst::before {\n  content: \"\\f5e1\"; }\n\n.fa-car-crash::before {\n  content: \"\\f5e1\"; }\n\n.fa-car-on::before {\n  content: \"\\e4dd\"; }\n\n.fa-car-rear::before {\n  content: \"\\f5de\"; }\n\n.fa-car-alt::before {\n  content: \"\\f5de\"; }\n\n.fa-car-side::before {\n  content: \"\\f5e4\"; }\n\n.fa-car-tunnel::before {\n  content: \"\\e4de\"; }\n\n.fa-caravan::before {\n  content: \"\\f8ff\"; }\n\n.fa-caret-down::before {\n  content: \"\\f0d7\"; }\n\n.fa-caret-left::before {\n  content: \"\\f0d9\"; }\n\n.fa-caret-right::before {\n  content: \"\\f0da\"; }\n\n.fa-caret-up::before {\n  content: \"\\f0d8\"; }\n\n.fa-carrot::before {\n  content: \"\\f787\"; }\n\n.fa-cart-arrow-down::before {\n  content: \"\\f218\"; }\n\n.fa-cart-flatbed::before {\n  content: \"\\f474\"; }\n\n.fa-dolly-flatbed::before {\n  content: \"\\f474\"; }\n\n.fa-cart-flatbed-suitcase::before {\n  content: \"\\f59d\"; }\n\n.fa-luggage-cart::before {\n  content: \"\\f59d\"; }\n\n.fa-cart-plus::before {\n  content: \"\\f217\"; }\n\n.fa-cart-shopping::before {\n  content: \"\\f07a\"; }\n\n.fa-shopping-cart::before {\n  content: \"\\f07a\"; }\n\n.fa-cash-register::before {\n  content: \"\\f788\"; }\n\n.fa-cat::before {\n  content: \"\\f6be\"; }\n\n.fa-cedi-sign::before {\n  content: \"\\e0df\"; }\n\n.fa-cent-sign::before {\n  content: \"\\e3f5\"; }\n\n.fa-certificate::before {\n  content: \"\\f0a3\"; }\n\n.fa-chair::before {\n  content: \"\\f6c0\"; }\n\n.fa-chalkboard::before {\n  content: \"\\f51b\"; }\n\n.fa-blackboard::before {\n  content: \"\\f51b\"; }\n\n.fa-chalkboard-user::before {\n  content: \"\\f51c\"; }\n\n.fa-chalkboard-teacher::before {\n  content: \"\\f51c\"; }\n\n.fa-champagne-glasses::before {\n  content: \"\\f79f\"; }\n\n.fa-glass-cheers::before {\n  content: \"\\f79f\"; }\n\n.fa-charging-station::before {\n  content: \"\\f5e7\"; }\n\n.fa-chart-area::before {\n  content: \"\\f1fe\"; }\n\n.fa-area-chart::before {\n  content: \"\\f1fe\"; }\n\n.fa-chart-bar::before {\n  content: \"\\f080\"; }\n\n.fa-bar-chart::before {\n  content: \"\\f080\"; }\n\n.fa-chart-column::before {\n  content: \"\\e0e3\"; }\n\n.fa-chart-gantt::before {\n  content: \"\\e0e4\"; }\n\n.fa-chart-line::before {\n  content: \"\\f201\"; }\n\n.fa-line-chart::before {\n  content: \"\\f201\"; }\n\n.fa-chart-pie::before {\n  content: \"\\f200\"; }\n\n.fa-pie-chart::before {\n  content: \"\\f200\"; }\n\n.fa-chart-simple::before {\n  content: \"\\e473\"; }\n\n.fa-check::before {\n  content: \"\\f00c\"; }\n\n.fa-check-double::before {\n  content: \"\\f560\"; }\n\n.fa-check-to-slot::before {\n  content: \"\\f772\"; }\n\n.fa-vote-yea::before {\n  content: \"\\f772\"; }\n\n.fa-cheese::before {\n  content: \"\\f7ef\"; }\n\n.fa-chess::before {\n  content: \"\\f439\"; }\n\n.fa-chess-bishop::before {\n  content: \"\\f43a\"; }\n\n.fa-chess-board::before {\n  content: \"\\f43c\"; }\n\n.fa-chess-king::before {\n  content: \"\\f43f\"; }\n\n.fa-chess-knight::before {\n  content: \"\\f441\"; }\n\n.fa-chess-pawn::before {\n  content: \"\\f443\"; }\n\n.fa-chess-queen::before {\n  content: \"\\f445\"; }\n\n.fa-chess-rook::before {\n  content: \"\\f447\"; }\n\n.fa-chevron-down::before {\n  content: \"\\f078\"; }\n\n.fa-chevron-left::before {\n  content: \"\\f053\"; }\n\n.fa-chevron-right::before {\n  content: \"\\f054\"; }\n\n.fa-chevron-up::before {\n  content: \"\\f077\"; }\n\n.fa-child::before {\n  content: \"\\f1ae\"; }\n\n.fa-child-dress::before {\n  content: \"\\e59c\"; }\n\n.fa-child-reaching::before {\n  content: \"\\e59d\"; }\n\n.fa-child-rifle::before {\n  content: \"\\e4e0\"; }\n\n.fa-children::before {\n  content: \"\\e4e1\"; }\n\n.fa-church::before {\n  content: \"\\f51d\"; }\n\n.fa-circle::before {\n  content: \"\\f111\"; }\n\n.fa-circle-arrow-down::before {\n  content: \"\\f0ab\"; }\n\n.fa-arrow-circle-down::before {\n  content: \"\\f0ab\"; }\n\n.fa-circle-arrow-left::before {\n  content: \"\\f0a8\"; }\n\n.fa-arrow-circle-left::before {\n  content: \"\\f0a8\"; }\n\n.fa-circle-arrow-right::before {\n  content: \"\\f0a9\"; }\n\n.fa-arrow-circle-right::before {\n  content: \"\\f0a9\"; }\n\n.fa-circle-arrow-up::before {\n  content: \"\\f0aa\"; }\n\n.fa-arrow-circle-up::before {\n  content: \"\\f0aa\"; }\n\n.fa-circle-check::before {\n  content: \"\\f058\"; }\n\n.fa-check-circle::before {\n  content: \"\\f058\"; }\n\n.fa-circle-chevron-down::before {\n  content: \"\\f13a\"; }\n\n.fa-chevron-circle-down::before {\n  content: \"\\f13a\"; }\n\n.fa-circle-chevron-left::before {\n  content: \"\\f137\"; }\n\n.fa-chevron-circle-left::before {\n  content: \"\\f137\"; }\n\n.fa-circle-chevron-right::before {\n  content: \"\\f138\"; }\n\n.fa-chevron-circle-right::before {\n  content: \"\\f138\"; }\n\n.fa-circle-chevron-up::before {\n  content: \"\\f139\"; }\n\n.fa-chevron-circle-up::before {\n  content: \"\\f139\"; }\n\n.fa-circle-dollar-to-slot::before {\n  content: \"\\f4b9\"; }\n\n.fa-donate::before {\n  content: \"\\f4b9\"; }\n\n.fa-circle-dot::before {\n  content: \"\\f192\"; }\n\n.fa-dot-circle::before {\n  content: \"\\f192\"; }\n\n.fa-circle-down::before {\n  content: \"\\f358\"; }\n\n.fa-arrow-alt-circle-down::before {\n  content: \"\\f358\"; }\n\n.fa-circle-exclamation::before {\n  content: \"\\f06a\"; }\n\n.fa-exclamation-circle::before {\n  content: \"\\f06a\"; }\n\n.fa-circle-h::before {\n  content: \"\\f47e\"; }\n\n.fa-hospital-symbol::before {\n  content: \"\\f47e\"; }\n\n.fa-circle-half-stroke::before {\n  content: \"\\f042\"; }\n\n.fa-adjust::before {\n  content: \"\\f042\"; }\n\n.fa-circle-info::before {\n  content: \"\\f05a\"; }\n\n.fa-info-circle::before {\n  content: \"\\f05a\"; }\n\n.fa-circle-left::before {\n  content: \"\\f359\"; }\n\n.fa-arrow-alt-circle-left::before {\n  content: \"\\f359\"; }\n\n.fa-circle-minus::before {\n  content: \"\\f056\"; }\n\n.fa-minus-circle::before {\n  content: \"\\f056\"; }\n\n.fa-circle-nodes::before {\n  content: \"\\e4e2\"; }\n\n.fa-circle-notch::before {\n  content: \"\\f1ce\"; }\n\n.fa-circle-pause::before {\n  content: \"\\f28b\"; }\n\n.fa-pause-circle::before {\n  content: \"\\f28b\"; }\n\n.fa-circle-play::before {\n  content: \"\\f144\"; }\n\n.fa-play-circle::before {\n  content: \"\\f144\"; }\n\n.fa-circle-plus::before {\n  content: \"\\f055\"; }\n\n.fa-plus-circle::before {\n  content: \"\\f055\"; }\n\n.fa-circle-question::before {\n  content: \"\\f059\"; }\n\n.fa-question-circle::before {\n  content: \"\\f059\"; }\n\n.fa-circle-radiation::before {\n  content: \"\\f7ba\"; }\n\n.fa-radiation-alt::before {\n  content: \"\\f7ba\"; }\n\n.fa-circle-right::before {\n  content: \"\\f35a\"; }\n\n.fa-arrow-alt-circle-right::before {\n  content: \"\\f35a\"; }\n\n.fa-circle-stop::before {\n  content: \"\\f28d\"; }\n\n.fa-stop-circle::before {\n  content: \"\\f28d\"; }\n\n.fa-circle-up::before {\n  content: \"\\f35b\"; }\n\n.fa-arrow-alt-circle-up::before {\n  content: \"\\f35b\"; }\n\n.fa-circle-user::before {\n  content: \"\\f2bd\"; }\n\n.fa-user-circle::before {\n  content: \"\\f2bd\"; }\n\n.fa-circle-xmark::before {\n  content: \"\\f057\"; }\n\n.fa-times-circle::before {\n  content: \"\\f057\"; }\n\n.fa-xmark-circle::before {\n  content: \"\\f057\"; }\n\n.fa-city::before {\n  content: \"\\f64f\"; }\n\n.fa-clapperboard::before {\n  content: \"\\e131\"; }\n\n.fa-clipboard::before {\n  content: \"\\f328\"; }\n\n.fa-clipboard-check::before {\n  content: \"\\f46c\"; }\n\n.fa-clipboard-list::before {\n  content: \"\\f46d\"; }\n\n.fa-clipboard-question::before {\n  content: \"\\e4e3\"; }\n\n.fa-clipboard-user::before {\n  content: \"\\f7f3\"; }\n\n.fa-clock::before {\n  content: \"\\f017\"; }\n\n.fa-clock-four::before {\n  content: \"\\f017\"; }\n\n.fa-clock-rotate-left::before {\n  content: \"\\f1da\"; }\n\n.fa-history::before {\n  content: \"\\f1da\"; }\n\n.fa-clone::before {\n  content: \"\\f24d\"; }\n\n.fa-closed-captioning::before {\n  content: \"\\f20a\"; }\n\n.fa-cloud::before {\n  content: \"\\f0c2\"; }\n\n.fa-cloud-arrow-down::before {\n  content: \"\\f0ed\"; }\n\n.fa-cloud-download::before {\n  content: \"\\f0ed\"; }\n\n.fa-cloud-download-alt::before {\n  content: \"\\f0ed\"; }\n\n.fa-cloud-arrow-up::before {\n  content: \"\\f0ee\"; }\n\n.fa-cloud-upload::before {\n  content: \"\\f0ee\"; }\n\n.fa-cloud-upload-alt::before {\n  content: \"\\f0ee\"; }\n\n.fa-cloud-bolt::before {\n  content: \"\\f76c\"; }\n\n.fa-thunderstorm::before {\n  content: \"\\f76c\"; }\n\n.fa-cloud-meatball::before {\n  content: \"\\f73b\"; }\n\n.fa-cloud-moon::before {\n  content: \"\\f6c3\"; }\n\n.fa-cloud-moon-rain::before {\n  content: \"\\f73c\"; }\n\n.fa-cloud-rain::before {\n  content: \"\\f73d\"; }\n\n.fa-cloud-showers-heavy::before {\n  content: \"\\f740\"; }\n\n.fa-cloud-showers-water::before {\n  content: \"\\e4e4\"; }\n\n.fa-cloud-sun::before {\n  content: \"\\f6c4\"; }\n\n.fa-cloud-sun-rain::before {\n  content: \"\\f743\"; }\n\n.fa-clover::before {\n  content: \"\\e139\"; }\n\n.fa-code::before {\n  content: \"\\f121\"; }\n\n.fa-code-branch::before {\n  content: \"\\f126\"; }\n\n.fa-code-commit::before {\n  content: \"\\f386\"; }\n\n.fa-code-compare::before {\n  content: \"\\e13a\"; }\n\n.fa-code-fork::before {\n  content: \"\\e13b\"; }\n\n.fa-code-merge::before {\n  content: \"\\f387\"; }\n\n.fa-code-pull-request::before {\n  content: \"\\e13c\"; }\n\n.fa-coins::before {\n  content: \"\\f51e\"; }\n\n.fa-colon-sign::before {\n  content: \"\\e140\"; }\n\n.fa-comment::before {\n  content: \"\\f075\"; }\n\n.fa-comment-dollar::before {\n  content: \"\\f651\"; }\n\n.fa-comment-dots::before {\n  content: \"\\f4ad\"; }\n\n.fa-commenting::before {\n  content: \"\\f4ad\"; }\n\n.fa-comment-medical::before {\n  content: \"\\f7f5\"; }\n\n.fa-comment-slash::before {\n  content: \"\\f4b3\"; }\n\n.fa-comment-sms::before {\n  content: \"\\f7cd\"; }\n\n.fa-sms::before {\n  content: \"\\f7cd\"; }\n\n.fa-comments::before {\n  content: \"\\f086\"; }\n\n.fa-comments-dollar::before {\n  content: \"\\f653\"; }\n\n.fa-compact-disc::before {\n  content: \"\\f51f\"; }\n\n.fa-compass::before {\n  content: \"\\f14e\"; }\n\n.fa-compass-drafting::before {\n  content: \"\\f568\"; }\n\n.fa-drafting-compass::before {\n  content: \"\\f568\"; }\n\n.fa-compress::before {\n  content: \"\\f066\"; }\n\n.fa-computer::before {\n  content: \"\\e4e5\"; }\n\n.fa-computer-mouse::before {\n  content: \"\\f8cc\"; }\n\n.fa-mouse::before {\n  content: \"\\f8cc\"; }\n\n.fa-cookie::before {\n  content: \"\\f563\"; }\n\n.fa-cookie-bite::before {\n  content: \"\\f564\"; }\n\n.fa-copy::before {\n  content: \"\\f0c5\"; }\n\n.fa-copyright::before {\n  content: \"\\f1f9\"; }\n\n.fa-couch::before {\n  content: \"\\f4b8\"; }\n\n.fa-cow::before {\n  content: \"\\f6c8\"; }\n\n.fa-credit-card::before {\n  content: \"\\f09d\"; }\n\n.fa-credit-card-alt::before {\n  content: \"\\f09d\"; }\n\n.fa-crop::before {\n  content: \"\\f125\"; }\n\n.fa-crop-simple::before {\n  content: \"\\f565\"; }\n\n.fa-crop-alt::before {\n  content: \"\\f565\"; }\n\n.fa-cross::before {\n  content: \"\\f654\"; }\n\n.fa-crosshairs::before {\n  content: \"\\f05b\"; }\n\n.fa-crow::before {\n  content: \"\\f520\"; }\n\n.fa-crown::before {\n  content: \"\\f521\"; }\n\n.fa-crutch::before {\n  content: \"\\f7f7\"; }\n\n.fa-cruzeiro-sign::before {\n  content: \"\\e152\"; }\n\n.fa-cube::before {\n  content: \"\\f1b2\"; }\n\n.fa-cubes::before {\n  content: \"\\f1b3\"; }\n\n.fa-cubes-stacked::before {\n  content: \"\\e4e6\"; }\n\n.fa-d::before {\n  content: \"\\44\"; }\n\n.fa-database::before {\n  content: \"\\f1c0\"; }\n\n.fa-delete-left::before {\n  content: \"\\f55a\"; }\n\n.fa-backspace::before {\n  content: \"\\f55a\"; }\n\n.fa-democrat::before {\n  content: \"\\f747\"; }\n\n.fa-desktop::before {\n  content: \"\\f390\"; }\n\n.fa-desktop-alt::before {\n  content: \"\\f390\"; }\n\n.fa-dharmachakra::before {\n  content: \"\\f655\"; }\n\n.fa-diagram-next::before {\n  content: \"\\e476\"; }\n\n.fa-diagram-predecessor::before {\n  content: \"\\e477\"; }\n\n.fa-diagram-project::before {\n  content: \"\\f542\"; }\n\n.fa-project-diagram::before {\n  content: \"\\f542\"; }\n\n.fa-diagram-successor::before {\n  content: \"\\e47a\"; }\n\n.fa-diamond::before {\n  content: \"\\f219\"; }\n\n.fa-diamond-turn-right::before {\n  content: \"\\f5eb\"; }\n\n.fa-directions::before {\n  content: \"\\f5eb\"; }\n\n.fa-dice::before {\n  content: \"\\f522\"; }\n\n.fa-dice-d20::before {\n  content: \"\\f6cf\"; }\n\n.fa-dice-d6::before {\n  content: \"\\f6d1\"; }\n\n.fa-dice-five::before {\n  content: \"\\f523\"; }\n\n.fa-dice-four::before {\n  content: \"\\f524\"; }\n\n.fa-dice-one::before {\n  content: \"\\f525\"; }\n\n.fa-dice-six::before {\n  content: \"\\f526\"; }\n\n.fa-dice-three::before {\n  content: \"\\f527\"; }\n\n.fa-dice-two::before {\n  content: \"\\f528\"; }\n\n.fa-disease::before {\n  content: \"\\f7fa\"; }\n\n.fa-display::before {\n  content: \"\\e163\"; }\n\n.fa-divide::before {\n  content: \"\\f529\"; }\n\n.fa-dna::before {\n  content: \"\\f471\"; }\n\n.fa-dog::before {\n  content: \"\\f6d3\"; }\n\n.fa-dollar-sign::before {\n  content: \"\\24\"; }\n\n.fa-dollar::before {\n  content: \"\\24\"; }\n\n.fa-usd::before {\n  content: \"\\24\"; }\n\n.fa-dolly::before {\n  content: \"\\f472\"; }\n\n.fa-dolly-box::before {\n  content: \"\\f472\"; }\n\n.fa-dong-sign::before {\n  content: \"\\e169\"; }\n\n.fa-door-closed::before {\n  content: \"\\f52a\"; }\n\n.fa-door-open::before {\n  content: \"\\f52b\"; }\n\n.fa-dove::before {\n  content: \"\\f4ba\"; }\n\n.fa-down-left-and-up-right-to-center::before {\n  content: \"\\f422\"; }\n\n.fa-compress-alt::before {\n  content: \"\\f422\"; }\n\n.fa-down-long::before {\n  content: \"\\f309\"; }\n\n.fa-long-arrow-alt-down::before {\n  content: \"\\f309\"; }\n\n.fa-download::before {\n  content: \"\\f019\"; }\n\n.fa-dragon::before {\n  content: \"\\f6d5\"; }\n\n.fa-draw-polygon::before {\n  content: \"\\f5ee\"; }\n\n.fa-droplet::before {\n  content: \"\\f043\"; }\n\n.fa-tint::before {\n  content: \"\\f043\"; }\n\n.fa-droplet-slash::before {\n  content: \"\\f5c7\"; }\n\n.fa-tint-slash::before {\n  content: \"\\f5c7\"; }\n\n.fa-drum::before {\n  content: \"\\f569\"; }\n\n.fa-drum-steelpan::before {\n  content: \"\\f56a\"; }\n\n.fa-drumstick-bite::before {\n  content: \"\\f6d7\"; }\n\n.fa-dumbbell::before {\n  content: \"\\f44b\"; }\n\n.fa-dumpster::before {\n  content: \"\\f793\"; }\n\n.fa-dumpster-fire::before {\n  content: \"\\f794\"; }\n\n.fa-dungeon::before {\n  content: \"\\f6d9\"; }\n\n.fa-e::before {\n  content: \"\\45\"; }\n\n.fa-ear-deaf::before {\n  content: \"\\f2a4\"; }\n\n.fa-deaf::before {\n  content: \"\\f2a4\"; }\n\n.fa-deafness::before {\n  content: \"\\f2a4\"; }\n\n.fa-hard-of-hearing::before {\n  content: \"\\f2a4\"; }\n\n.fa-ear-listen::before {\n  content: \"\\f2a2\"; }\n\n.fa-assistive-listening-systems::before {\n  content: \"\\f2a2\"; }\n\n.fa-earth-africa::before {\n  content: \"\\f57c\"; }\n\n.fa-globe-africa::before {\n  content: \"\\f57c\"; }\n\n.fa-earth-americas::before {\n  content: \"\\f57d\"; }\n\n.fa-earth::before {\n  content: \"\\f57d\"; }\n\n.fa-earth-america::before {\n  content: \"\\f57d\"; }\n\n.fa-globe-americas::before {\n  content: \"\\f57d\"; }\n\n.fa-earth-asia::before {\n  content: \"\\f57e\"; }\n\n.fa-globe-asia::before {\n  content: \"\\f57e\"; }\n\n.fa-earth-europe::before {\n  content: \"\\f7a2\"; }\n\n.fa-globe-europe::before {\n  content: \"\\f7a2\"; }\n\n.fa-earth-oceania::before {\n  content: \"\\e47b\"; }\n\n.fa-globe-oceania::before {\n  content: \"\\e47b\"; }\n\n.fa-egg::before {\n  content: \"\\f7fb\"; }\n\n.fa-eject::before {\n  content: \"\\f052\"; }\n\n.fa-elevator::before {\n  content: \"\\e16d\"; }\n\n.fa-ellipsis::before {\n  content: \"\\f141\"; }\n\n.fa-ellipsis-h::before {\n  content: \"\\f141\"; }\n\n.fa-ellipsis-vertical::before {\n  content: \"\\f142\"; }\n\n.fa-ellipsis-v::before {\n  content: \"\\f142\"; }\n\n.fa-envelope::before {\n  content: \"\\f0e0\"; }\n\n.fa-envelope-circle-check::before {\n  content: \"\\e4e8\"; }\n\n.fa-envelope-open::before {\n  content: \"\\f2b6\"; }\n\n.fa-envelope-open-text::before {\n  content: \"\\f658\"; }\n\n.fa-envelopes-bulk::before {\n  content: \"\\f674\"; }\n\n.fa-mail-bulk::before {\n  content: \"\\f674\"; }\n\n.fa-equals::before {\n  content: \"\\3d\"; }\n\n.fa-eraser::before {\n  content: \"\\f12d\"; }\n\n.fa-ethernet::before {\n  content: \"\\f796\"; }\n\n.fa-euro-sign::before {\n  content: \"\\f153\"; }\n\n.fa-eur::before {\n  content: \"\\f153\"; }\n\n.fa-euro::before {\n  content: \"\\f153\"; }\n\n.fa-exclamation::before {\n  content: \"\\21\"; }\n\n.fa-expand::before {\n  content: \"\\f065\"; }\n\n.fa-explosion::before {\n  content: \"\\e4e9\"; }\n\n.fa-eye::before {\n  content: \"\\f06e\"; }\n\n.fa-eye-dropper::before {\n  content: \"\\f1fb\"; }\n\n.fa-eye-dropper-empty::before {\n  content: \"\\f1fb\"; }\n\n.fa-eyedropper::before {\n  content: \"\\f1fb\"; }\n\n.fa-eye-low-vision::before {\n  content: \"\\f2a8\"; }\n\n.fa-low-vision::before {\n  content: \"\\f2a8\"; }\n\n.fa-eye-slash::before {\n  content: \"\\f070\"; }\n\n.fa-f::before {\n  content: \"\\46\"; }\n\n.fa-face-angry::before {\n  content: \"\\f556\"; }\n\n.fa-angry::before {\n  content: \"\\f556\"; }\n\n.fa-face-dizzy::before {\n  content: \"\\f567\"; }\n\n.fa-dizzy::before {\n  content: \"\\f567\"; }\n\n.fa-face-flushed::before {\n  content: \"\\f579\"; }\n\n.fa-flushed::before {\n  content: \"\\f579\"; }\n\n.fa-face-frown::before {\n  content: \"\\f119\"; }\n\n.fa-frown::before {\n  content: \"\\f119\"; }\n\n.fa-face-frown-open::before {\n  content: \"\\f57a\"; }\n\n.fa-frown-open::before {\n  content: \"\\f57a\"; }\n\n.fa-face-grimace::before {\n  content: \"\\f57f\"; }\n\n.fa-grimace::before {\n  content: \"\\f57f\"; }\n\n.fa-face-grin::before {\n  content: \"\\f580\"; }\n\n.fa-grin::before {\n  content: \"\\f580\"; }\n\n.fa-face-grin-beam::before {\n  content: \"\\f582\"; }\n\n.fa-grin-beam::before {\n  content: \"\\f582\"; }\n\n.fa-face-grin-beam-sweat::before {\n  content: \"\\f583\"; }\n\n.fa-grin-beam-sweat::before {\n  content: \"\\f583\"; }\n\n.fa-face-grin-hearts::before {\n  content: \"\\f584\"; }\n\n.fa-grin-hearts::before {\n  content: \"\\f584\"; }\n\n.fa-face-grin-squint::before {\n  content: \"\\f585\"; }\n\n.fa-grin-squint::before {\n  content: \"\\f585\"; }\n\n.fa-face-grin-squint-tears::before {\n  content: \"\\f586\"; }\n\n.fa-grin-squint-tears::before {\n  content: \"\\f586\"; }\n\n.fa-face-grin-stars::before {\n  content: \"\\f587\"; }\n\n.fa-grin-stars::before {\n  content: \"\\f587\"; }\n\n.fa-face-grin-tears::before {\n  content: \"\\f588\"; }\n\n.fa-grin-tears::before {\n  content: \"\\f588\"; }\n\n.fa-face-grin-tongue::before {\n  content: \"\\f589\"; }\n\n.fa-grin-tongue::before {\n  content: \"\\f589\"; }\n\n.fa-face-grin-tongue-squint::before {\n  content: \"\\f58a\"; }\n\n.fa-grin-tongue-squint::before {\n  content: \"\\f58a\"; }\n\n.fa-face-grin-tongue-wink::before {\n  content: \"\\f58b\"; }\n\n.fa-grin-tongue-wink::before {\n  content: \"\\f58b\"; }\n\n.fa-face-grin-wide::before {\n  content: \"\\f581\"; }\n\n.fa-grin-alt::before {\n  content: \"\\f581\"; }\n\n.fa-face-grin-wink::before {\n  content: \"\\f58c\"; }\n\n.fa-grin-wink::before {\n  content: \"\\f58c\"; }\n\n.fa-face-kiss::before {\n  content: \"\\f596\"; }\n\n.fa-kiss::before {\n  content: \"\\f596\"; }\n\n.fa-face-kiss-beam::before {\n  content: \"\\f597\"; }\n\n.fa-kiss-beam::before {\n  content: \"\\f597\"; }\n\n.fa-face-kiss-wink-heart::before {\n  content: \"\\f598\"; }\n\n.fa-kiss-wink-heart::before {\n  content: \"\\f598\"; }\n\n.fa-face-laugh::before {\n  content: \"\\f599\"; }\n\n.fa-laugh::before {\n  content: \"\\f599\"; }\n\n.fa-face-laugh-beam::before {\n  content: \"\\f59a\"; }\n\n.fa-laugh-beam::before {\n  content: \"\\f59a\"; }\n\n.fa-face-laugh-squint::before {\n  content: \"\\f59b\"; }\n\n.fa-laugh-squint::before {\n  content: \"\\f59b\"; }\n\n.fa-face-laugh-wink::before {\n  content: \"\\f59c\"; }\n\n.fa-laugh-wink::before {\n  content: \"\\f59c\"; }\n\n.fa-face-meh::before {\n  content: \"\\f11a\"; }\n\n.fa-meh::before {\n  content: \"\\f11a\"; }\n\n.fa-face-meh-blank::before {\n  content: \"\\f5a4\"; }\n\n.fa-meh-blank::before {\n  content: \"\\f5a4\"; }\n\n.fa-face-rolling-eyes::before {\n  content: \"\\f5a5\"; }\n\n.fa-meh-rolling-eyes::before {\n  content: \"\\f5a5\"; }\n\n.fa-face-sad-cry::before {\n  content: \"\\f5b3\"; }\n\n.fa-sad-cry::before {\n  content: \"\\f5b3\"; }\n\n.fa-face-sad-tear::before {\n  content: \"\\f5b4\"; }\n\n.fa-sad-tear::before {\n  content: \"\\f5b4\"; }\n\n.fa-face-smile::before {\n  content: \"\\f118\"; }\n\n.fa-smile::before {\n  content: \"\\f118\"; }\n\n.fa-face-smile-beam::before {\n  content: \"\\f5b8\"; }\n\n.fa-smile-beam::before {\n  content: \"\\f5b8\"; }\n\n.fa-face-smile-wink::before {\n  content: \"\\f4da\"; }\n\n.fa-smile-wink::before {\n  content: \"\\f4da\"; }\n\n.fa-face-surprise::before {\n  content: \"\\f5c2\"; }\n\n.fa-surprise::before {\n  content: \"\\f5c2\"; }\n\n.fa-face-tired::before {\n  content: \"\\f5c8\"; }\n\n.fa-tired::before {\n  content: \"\\f5c8\"; }\n\n.fa-fan::before {\n  content: \"\\f863\"; }\n\n.fa-faucet::before {\n  content: \"\\e005\"; }\n\n.fa-faucet-drip::before {\n  content: \"\\e006\"; }\n\n.fa-fax::before {\n  content: \"\\f1ac\"; }\n\n.fa-feather::before {\n  content: \"\\f52d\"; }\n\n.fa-feather-pointed::before {\n  content: \"\\f56b\"; }\n\n.fa-feather-alt::before {\n  content: \"\\f56b\"; }\n\n.fa-ferry::before {\n  content: \"\\e4ea\"; }\n\n.fa-file::before {\n  content: \"\\f15b\"; }\n\n.fa-file-arrow-down::before {\n  content: \"\\f56d\"; }\n\n.fa-file-download::before {\n  content: \"\\f56d\"; }\n\n.fa-file-arrow-up::before {\n  content: \"\\f574\"; }\n\n.fa-file-upload::before {\n  content: \"\\f574\"; }\n\n.fa-file-audio::before {\n  content: \"\\f1c7\"; }\n\n.fa-file-circle-check::before {\n  content: \"\\e493\"; }\n\n.fa-file-circle-exclamation::before {\n  content: \"\\e4eb\"; }\n\n.fa-file-circle-minus::before {\n  content: \"\\e4ed\"; }\n\n.fa-file-circle-plus::before {\n  content: \"\\e4ee\"; }\n\n.fa-file-circle-question::before {\n  content: \"\\e4ef\"; }\n\n.fa-file-circle-xmark::before {\n  content: \"\\e494\"; }\n\n.fa-file-code::before {\n  content: \"\\f1c9\"; }\n\n.fa-file-contract::before {\n  content: \"\\f56c\"; }\n\n.fa-file-csv::before {\n  content: \"\\f6dd\"; }\n\n.fa-file-excel::before {\n  content: \"\\f1c3\"; }\n\n.fa-file-export::before {\n  content: \"\\f56e\"; }\n\n.fa-arrow-right-from-file::before {\n  content: \"\\f56e\"; }\n\n.fa-file-image::before {\n  content: \"\\f1c5\"; }\n\n.fa-file-import::before {\n  content: \"\\f56f\"; }\n\n.fa-arrow-right-to-file::before {\n  content: \"\\f56f\"; }\n\n.fa-file-invoice::before {\n  content: \"\\f570\"; }\n\n.fa-file-invoice-dollar::before {\n  content: \"\\f571\"; }\n\n.fa-file-lines::before {\n  content: \"\\f15c\"; }\n\n.fa-file-alt::before {\n  content: \"\\f15c\"; }\n\n.fa-file-text::before {\n  content: \"\\f15c\"; }\n\n.fa-file-medical::before {\n  content: \"\\f477\"; }\n\n.fa-file-pdf::before {\n  content: \"\\f1c1\"; }\n\n.fa-file-pen::before {\n  content: \"\\f31c\"; }\n\n.fa-file-edit::before {\n  content: \"\\f31c\"; }\n\n.fa-file-powerpoint::before {\n  content: \"\\f1c4\"; }\n\n.fa-file-prescription::before {\n  content: \"\\f572\"; }\n\n.fa-file-shield::before {\n  content: \"\\e4f0\"; }\n\n.fa-file-signature::before {\n  content: \"\\f573\"; }\n\n.fa-file-video::before {\n  content: \"\\f1c8\"; }\n\n.fa-file-waveform::before {\n  content: \"\\f478\"; }\n\n.fa-file-medical-alt::before {\n  content: \"\\f478\"; }\n\n.fa-file-word::before {\n  content: \"\\f1c2\"; }\n\n.fa-file-zipper::before {\n  content: \"\\f1c6\"; }\n\n.fa-file-archive::before {\n  content: \"\\f1c6\"; }\n\n.fa-fill::before {\n  content: \"\\f575\"; }\n\n.fa-fill-drip::before {\n  content: \"\\f576\"; }\n\n.fa-film::before {\n  content: \"\\f008\"; }\n\n.fa-filter::before {\n  content: \"\\f0b0\"; }\n\n.fa-filter-circle-dollar::before {\n  content: \"\\f662\"; }\n\n.fa-funnel-dollar::before {\n  content: \"\\f662\"; }\n\n.fa-filter-circle-xmark::before {\n  content: \"\\e17b\"; }\n\n.fa-fingerprint::before {\n  content: \"\\f577\"; }\n\n.fa-fire::before {\n  content: \"\\f06d\"; }\n\n.fa-fire-burner::before {\n  content: \"\\e4f1\"; }\n\n.fa-fire-extinguisher::before {\n  content: \"\\f134\"; }\n\n.fa-fire-flame-curved::before {\n  content: \"\\f7e4\"; }\n\n.fa-fire-alt::before {\n  content: \"\\f7e4\"; }\n\n.fa-fire-flame-simple::before {\n  content: \"\\f46a\"; }\n\n.fa-burn::before {\n  content: \"\\f46a\"; }\n\n.fa-fish::before {\n  content: \"\\f578\"; }\n\n.fa-fish-fins::before {\n  content: \"\\e4f2\"; }\n\n.fa-flag::before {\n  content: \"\\f024\"; }\n\n.fa-flag-checkered::before {\n  content: \"\\f11e\"; }\n\n.fa-flag-usa::before {\n  content: \"\\f74d\"; }\n\n.fa-flask::before {\n  content: \"\\f0c3\"; }\n\n.fa-flask-vial::before {\n  content: \"\\e4f3\"; }\n\n.fa-floppy-disk::before {\n  content: \"\\f0c7\"; }\n\n.fa-save::before {\n  content: \"\\f0c7\"; }\n\n.fa-florin-sign::before {\n  content: \"\\e184\"; }\n\n.fa-folder::before {\n  content: \"\\f07b\"; }\n\n.fa-folder-blank::before {\n  content: \"\\f07b\"; }\n\n.fa-folder-closed::before {\n  content: \"\\e185\"; }\n\n.fa-folder-minus::before {\n  content: \"\\f65d\"; }\n\n.fa-folder-open::before {\n  content: \"\\f07c\"; }\n\n.fa-folder-plus::before {\n  content: \"\\f65e\"; }\n\n.fa-folder-tree::before {\n  content: \"\\f802\"; }\n\n.fa-font::before {\n  content: \"\\f031\"; }\n\n.fa-football::before {\n  content: \"\\f44e\"; }\n\n.fa-football-ball::before {\n  content: \"\\f44e\"; }\n\n.fa-forward::before {\n  content: \"\\f04e\"; }\n\n.fa-forward-fast::before {\n  content: \"\\f050\"; }\n\n.fa-fast-forward::before {\n  content: \"\\f050\"; }\n\n.fa-forward-step::before {\n  content: \"\\f051\"; }\n\n.fa-step-forward::before {\n  content: \"\\f051\"; }\n\n.fa-franc-sign::before {\n  content: \"\\e18f\"; }\n\n.fa-frog::before {\n  content: \"\\f52e\"; }\n\n.fa-futbol::before {\n  content: \"\\f1e3\"; }\n\n.fa-futbol-ball::before {\n  content: \"\\f1e3\"; }\n\n.fa-soccer-ball::before {\n  content: \"\\f1e3\"; }\n\n.fa-g::before {\n  content: \"\\47\"; }\n\n.fa-gamepad::before {\n  content: \"\\f11b\"; }\n\n.fa-gas-pump::before {\n  content: \"\\f52f\"; }\n\n.fa-gauge::before {\n  content: \"\\f624\"; }\n\n.fa-dashboard::before {\n  content: \"\\f624\"; }\n\n.fa-gauge-med::before {\n  content: \"\\f624\"; }\n\n.fa-tachometer-alt-average::before {\n  content: \"\\f624\"; }\n\n.fa-gauge-high::before {\n  content: \"\\f625\"; }\n\n.fa-tachometer-alt::before {\n  content: \"\\f625\"; }\n\n.fa-tachometer-alt-fast::before {\n  content: \"\\f625\"; }\n\n.fa-gauge-simple::before {\n  content: \"\\f629\"; }\n\n.fa-gauge-simple-med::before {\n  content: \"\\f629\"; }\n\n.fa-tachometer-average::before {\n  content: \"\\f629\"; }\n\n.fa-gauge-simple-high::before {\n  content: \"\\f62a\"; }\n\n.fa-tachometer::before {\n  content: \"\\f62a\"; }\n\n.fa-tachometer-fast::before {\n  content: \"\\f62a\"; }\n\n.fa-gavel::before {\n  content: \"\\f0e3\"; }\n\n.fa-legal::before {\n  content: \"\\f0e3\"; }\n\n.fa-gear::before {\n  content: \"\\f013\"; }\n\n.fa-cog::before {\n  content: \"\\f013\"; }\n\n.fa-gears::before {\n  content: \"\\f085\"; }\n\n.fa-cogs::before {\n  content: \"\\f085\"; }\n\n.fa-gem::before {\n  content: \"\\f3a5\"; }\n\n.fa-genderless::before {\n  content: \"\\f22d\"; }\n\n.fa-ghost::before {\n  content: \"\\f6e2\"; }\n\n.fa-gift::before {\n  content: \"\\f06b\"; }\n\n.fa-gifts::before {\n  content: \"\\f79c\"; }\n\n.fa-glass-water::before {\n  content: \"\\e4f4\"; }\n\n.fa-glass-water-droplet::before {\n  content: \"\\e4f5\"; }\n\n.fa-glasses::before {\n  content: \"\\f530\"; }\n\n.fa-globe::before {\n  content: \"\\f0ac\"; }\n\n.fa-golf-ball-tee::before {\n  content: \"\\f450\"; }\n\n.fa-golf-ball::before {\n  content: \"\\f450\"; }\n\n.fa-gopuram::before {\n  content: \"\\f664\"; }\n\n.fa-graduation-cap::before {\n  content: \"\\f19d\"; }\n\n.fa-mortar-board::before {\n  content: \"\\f19d\"; }\n\n.fa-greater-than::before {\n  content: \"\\3e\"; }\n\n.fa-greater-than-equal::before {\n  content: \"\\f532\"; }\n\n.fa-grip::before {\n  content: \"\\f58d\"; }\n\n.fa-grip-horizontal::before {\n  content: \"\\f58d\"; }\n\n.fa-grip-lines::before {\n  content: \"\\f7a4\"; }\n\n.fa-grip-lines-vertical::before {\n  content: \"\\f7a5\"; }\n\n.fa-grip-vertical::before {\n  content: \"\\f58e\"; }\n\n.fa-group-arrows-rotate::before {\n  content: \"\\e4f6\"; }\n\n.fa-guarani-sign::before {\n  content: \"\\e19a\"; }\n\n.fa-guitar::before {\n  content: \"\\f7a6\"; }\n\n.fa-gun::before {\n  content: \"\\e19b\"; }\n\n.fa-h::before {\n  content: \"\\48\"; }\n\n.fa-hammer::before {\n  content: \"\\f6e3\"; }\n\n.fa-hamsa::before {\n  content: \"\\f665\"; }\n\n.fa-hand::before {\n  content: \"\\f256\"; }\n\n.fa-hand-paper::before {\n  content: \"\\f256\"; }\n\n.fa-hand-back-fist::before {\n  content: \"\\f255\"; }\n\n.fa-hand-rock::before {\n  content: \"\\f255\"; }\n\n.fa-hand-dots::before {\n  content: \"\\f461\"; }\n\n.fa-allergies::before {\n  content: \"\\f461\"; }\n\n.fa-hand-fist::before {\n  content: \"\\f6de\"; }\n\n.fa-fist-raised::before {\n  content: \"\\f6de\"; }\n\n.fa-hand-holding::before {\n  content: \"\\f4bd\"; }\n\n.fa-hand-holding-dollar::before {\n  content: \"\\f4c0\"; }\n\n.fa-hand-holding-usd::before {\n  content: \"\\f4c0\"; }\n\n.fa-hand-holding-droplet::before {\n  content: \"\\f4c1\"; }\n\n.fa-hand-holding-water::before {\n  content: \"\\f4c1\"; }\n\n.fa-hand-holding-hand::before {\n  content: \"\\e4f7\"; }\n\n.fa-hand-holding-heart::before {\n  content: \"\\f4be\"; }\n\n.fa-hand-holding-medical::before {\n  content: \"\\e05c\"; }\n\n.fa-hand-lizard::before {\n  content: \"\\f258\"; }\n\n.fa-hand-middle-finger::before {\n  content: \"\\f806\"; }\n\n.fa-hand-peace::before {\n  content: \"\\f25b\"; }\n\n.fa-hand-point-down::before {\n  content: \"\\f0a7\"; }\n\n.fa-hand-point-left::before {\n  content: \"\\f0a5\"; }\n\n.fa-hand-point-right::before {\n  content: \"\\f0a4\"; }\n\n.fa-hand-point-up::before {\n  content: \"\\f0a6\"; }\n\n.fa-hand-pointer::before {\n  content: \"\\f25a\"; }\n\n.fa-hand-scissors::before {\n  content: \"\\f257\"; }\n\n.fa-hand-sparkles::before {\n  content: \"\\e05d\"; }\n\n.fa-hand-spock::before {\n  content: \"\\f259\"; }\n\n.fa-handcuffs::before {\n  content: \"\\e4f8\"; }\n\n.fa-hands::before {\n  content: \"\\f2a7\"; }\n\n.fa-sign-language::before {\n  content: \"\\f2a7\"; }\n\n.fa-signing::before {\n  content: \"\\f2a7\"; }\n\n.fa-hands-asl-interpreting::before {\n  content: \"\\f2a3\"; }\n\n.fa-american-sign-language-interpreting::before {\n  content: \"\\f2a3\"; }\n\n.fa-asl-interpreting::before {\n  content: \"\\f2a3\"; }\n\n.fa-hands-american-sign-language-interpreting::before {\n  content: \"\\f2a3\"; }\n\n.fa-hands-bound::before {\n  content: \"\\e4f9\"; }\n\n.fa-hands-bubbles::before {\n  content: \"\\e05e\"; }\n\n.fa-hands-wash::before {\n  content: \"\\e05e\"; }\n\n.fa-hands-clapping::before {\n  content: \"\\e1a8\"; }\n\n.fa-hands-holding::before {\n  content: \"\\f4c2\"; }\n\n.fa-hands-holding-child::before {\n  content: \"\\e4fa\"; }\n\n.fa-hands-holding-circle::before {\n  content: \"\\e4fb\"; }\n\n.fa-hands-praying::before {\n  content: \"\\f684\"; }\n\n.fa-praying-hands::before {\n  content: \"\\f684\"; }\n\n.fa-handshake::before {\n  content: \"\\f2b5\"; }\n\n.fa-handshake-angle::before {\n  content: \"\\f4c4\"; }\n\n.fa-hands-helping::before {\n  content: \"\\f4c4\"; }\n\n.fa-handshake-simple::before {\n  content: \"\\f4c6\"; }\n\n.fa-handshake-alt::before {\n  content: \"\\f4c6\"; }\n\n.fa-handshake-simple-slash::before {\n  content: \"\\e05f\"; }\n\n.fa-handshake-alt-slash::before {\n  content: \"\\e05f\"; }\n\n.fa-handshake-slash::before {\n  content: \"\\e060\"; }\n\n.fa-hanukiah::before {\n  content: \"\\f6e6\"; }\n\n.fa-hard-drive::before {\n  content: \"\\f0a0\"; }\n\n.fa-hdd::before {\n  content: \"\\f0a0\"; }\n\n.fa-hashtag::before {\n  content: \"\\23\"; }\n\n.fa-hat-cowboy::before {\n  content: \"\\f8c0\"; }\n\n.fa-hat-cowboy-side::before {\n  content: \"\\f8c1\"; }\n\n.fa-hat-wizard::before {\n  content: \"\\f6e8\"; }\n\n.fa-head-side-cough::before {\n  content: \"\\e061\"; }\n\n.fa-head-side-cough-slash::before {\n  content: \"\\e062\"; }\n\n.fa-head-side-mask::before {\n  content: \"\\e063\"; }\n\n.fa-head-side-virus::before {\n  content: \"\\e064\"; }\n\n.fa-heading::before {\n  content: \"\\f1dc\"; }\n\n.fa-header::before {\n  content: \"\\f1dc\"; }\n\n.fa-headphones::before {\n  content: \"\\f025\"; }\n\n.fa-headphones-simple::before {\n  content: \"\\f58f\"; }\n\n.fa-headphones-alt::before {\n  content: \"\\f58f\"; }\n\n.fa-headset::before {\n  content: \"\\f590\"; }\n\n.fa-heart::before {\n  content: \"\\f004\"; }\n\n.fa-heart-circle-bolt::before {\n  content: \"\\e4fc\"; }\n\n.fa-heart-circle-check::before {\n  content: \"\\e4fd\"; }\n\n.fa-heart-circle-exclamation::before {\n  content: \"\\e4fe\"; }\n\n.fa-heart-circle-minus::before {\n  content: \"\\e4ff\"; }\n\n.fa-heart-circle-plus::before {\n  content: \"\\e500\"; }\n\n.fa-heart-circle-xmark::before {\n  content: \"\\e501\"; }\n\n.fa-heart-crack::before {\n  content: \"\\f7a9\"; }\n\n.fa-heart-broken::before {\n  content: \"\\f7a9\"; }\n\n.fa-heart-pulse::before {\n  content: \"\\f21e\"; }\n\n.fa-heartbeat::before {\n  content: \"\\f21e\"; }\n\n.fa-helicopter::before {\n  content: \"\\f533\"; }\n\n.fa-helicopter-symbol::before {\n  content: \"\\e502\"; }\n\n.fa-helmet-safety::before {\n  content: \"\\f807\"; }\n\n.fa-hard-hat::before {\n  content: \"\\f807\"; }\n\n.fa-hat-hard::before {\n  content: \"\\f807\"; }\n\n.fa-helmet-un::before {\n  content: \"\\e503\"; }\n\n.fa-highlighter::before {\n  content: \"\\f591\"; }\n\n.fa-hill-avalanche::before {\n  content: \"\\e507\"; }\n\n.fa-hill-rockslide::before {\n  content: \"\\e508\"; }\n\n.fa-hippo::before {\n  content: \"\\f6ed\"; }\n\n.fa-hockey-puck::before {\n  content: \"\\f453\"; }\n\n.fa-holly-berry::before {\n  content: \"\\f7aa\"; }\n\n.fa-horse::before {\n  content: \"\\f6f0\"; }\n\n.fa-horse-head::before {\n  content: \"\\f7ab\"; }\n\n.fa-hospital::before {\n  content: \"\\f0f8\"; }\n\n.fa-hospital-alt::before {\n  content: \"\\f0f8\"; }\n\n.fa-hospital-wide::before {\n  content: \"\\f0f8\"; }\n\n.fa-hospital-user::before {\n  content: \"\\f80d\"; }\n\n.fa-hot-tub-person::before {\n  content: \"\\f593\"; }\n\n.fa-hot-tub::before {\n  content: \"\\f593\"; }\n\n.fa-hotdog::before {\n  content: \"\\f80f\"; }\n\n.fa-hotel::before {\n  content: \"\\f594\"; }\n\n.fa-hourglass::before {\n  content: \"\\f254\"; }\n\n.fa-hourglass-2::before {\n  content: \"\\f254\"; }\n\n.fa-hourglass-half::before {\n  content: \"\\f254\"; }\n\n.fa-hourglass-empty::before {\n  content: \"\\f252\"; }\n\n.fa-hourglass-end::before {\n  content: \"\\f253\"; }\n\n.fa-hourglass-3::before {\n  content: \"\\f253\"; }\n\n.fa-hourglass-start::before {\n  content: \"\\f251\"; }\n\n.fa-hourglass-1::before {\n  content: \"\\f251\"; }\n\n.fa-house::before {\n  content: \"\\f015\"; }\n\n.fa-home::before {\n  content: \"\\f015\"; }\n\n.fa-home-alt::before {\n  content: \"\\f015\"; }\n\n.fa-home-lg-alt::before {\n  content: \"\\f015\"; }\n\n.fa-house-chimney::before {\n  content: \"\\e3af\"; }\n\n.fa-home-lg::before {\n  content: \"\\e3af\"; }\n\n.fa-house-chimney-crack::before {\n  content: \"\\f6f1\"; }\n\n.fa-house-damage::before {\n  content: \"\\f6f1\"; }\n\n.fa-house-chimney-medical::before {\n  content: \"\\f7f2\"; }\n\n.fa-clinic-medical::before {\n  content: \"\\f7f2\"; }\n\n.fa-house-chimney-user::before {\n  content: \"\\e065\"; }\n\n.fa-house-chimney-window::before {\n  content: \"\\e00d\"; }\n\n.fa-house-circle-check::before {\n  content: \"\\e509\"; }\n\n.fa-house-circle-exclamation::before {\n  content: \"\\e50a\"; }\n\n.fa-house-circle-xmark::before {\n  content: \"\\e50b\"; }\n\n.fa-house-crack::before {\n  content: \"\\e3b1\"; }\n\n.fa-house-fire::before {\n  content: \"\\e50c\"; }\n\n.fa-house-flag::before {\n  content: \"\\e50d\"; }\n\n.fa-house-flood-water::before {\n  content: \"\\e50e\"; }\n\n.fa-house-flood-water-circle-arrow-right::before {\n  content: \"\\e50f\"; }\n\n.fa-house-laptop::before {\n  content: \"\\e066\"; }\n\n.fa-laptop-house::before {\n  content: \"\\e066\"; }\n\n.fa-house-lock::before {\n  content: \"\\e510\"; }\n\n.fa-house-medical::before {\n  content: \"\\e3b2\"; }\n\n.fa-house-medical-circle-check::before {\n  content: \"\\e511\"; }\n\n.fa-house-medical-circle-exclamation::before {\n  content: \"\\e512\"; }\n\n.fa-house-medical-circle-xmark::before {\n  content: \"\\e513\"; }\n\n.fa-house-medical-flag::before {\n  content: \"\\e514\"; }\n\n.fa-house-signal::before {\n  content: \"\\e012\"; }\n\n.fa-house-tsunami::before {\n  content: \"\\e515\"; }\n\n.fa-house-user::before {\n  content: \"\\e1b0\"; }\n\n.fa-home-user::before {\n  content: \"\\e1b0\"; }\n\n.fa-hryvnia-sign::before {\n  content: \"\\f6f2\"; }\n\n.fa-hryvnia::before {\n  content: \"\\f6f2\"; }\n\n.fa-hurricane::before {\n  content: \"\\f751\"; }\n\n.fa-i::before {\n  content: \"\\49\"; }\n\n.fa-i-cursor::before {\n  content: \"\\f246\"; }\n\n.fa-ice-cream::before {\n  content: \"\\f810\"; }\n\n.fa-icicles::before {\n  content: \"\\f7ad\"; }\n\n.fa-icons::before {\n  content: \"\\f86d\"; }\n\n.fa-heart-music-camera-bolt::before {\n  content: \"\\f86d\"; }\n\n.fa-id-badge::before {\n  content: \"\\f2c1\"; }\n\n.fa-id-card::before {\n  content: \"\\f2c2\"; }\n\n.fa-drivers-license::before {\n  content: \"\\f2c2\"; }\n\n.fa-id-card-clip::before {\n  content: \"\\f47f\"; }\n\n.fa-id-card-alt::before {\n  content: \"\\f47f\"; }\n\n.fa-igloo::before {\n  content: \"\\f7ae\"; }\n\n.fa-image::before {\n  content: \"\\f03e\"; }\n\n.fa-image-portrait::before {\n  content: \"\\f3e0\"; }\n\n.fa-portrait::before {\n  content: \"\\f3e0\"; }\n\n.fa-images::before {\n  content: \"\\f302\"; }\n\n.fa-inbox::before {\n  content: \"\\f01c\"; }\n\n.fa-indent::before {\n  content: \"\\f03c\"; }\n\n.fa-indian-rupee-sign::before {\n  content: \"\\e1bc\"; }\n\n.fa-indian-rupee::before {\n  content: \"\\e1bc\"; }\n\n.fa-inr::before {\n  content: \"\\e1bc\"; }\n\n.fa-industry::before {\n  content: \"\\f275\"; }\n\n.fa-infinity::before {\n  content: \"\\f534\"; }\n\n.fa-info::before {\n  content: \"\\f129\"; }\n\n.fa-italic::before {\n  content: \"\\f033\"; }\n\n.fa-j::before {\n  content: \"\\4a\"; }\n\n.fa-jar::before {\n  content: \"\\e516\"; }\n\n.fa-jar-wheat::before {\n  content: \"\\e517\"; }\n\n.fa-jedi::before {\n  content: \"\\f669\"; }\n\n.fa-jet-fighter::before {\n  content: \"\\f0fb\"; }\n\n.fa-fighter-jet::before {\n  content: \"\\f0fb\"; }\n\n.fa-jet-fighter-up::before {\n  content: \"\\e518\"; }\n\n.fa-joint::before {\n  content: \"\\f595\"; }\n\n.fa-jug-detergent::before {\n  content: \"\\e519\"; }\n\n.fa-k::before {\n  content: \"\\4b\"; }\n\n.fa-kaaba::before {\n  content: \"\\f66b\"; }\n\n.fa-key::before {\n  content: \"\\f084\"; }\n\n.fa-keyboard::before {\n  content: \"\\f11c\"; }\n\n.fa-khanda::before {\n  content: \"\\f66d\"; }\n\n.fa-kip-sign::before {\n  content: \"\\e1c4\"; }\n\n.fa-kit-medical::before {\n  content: \"\\f479\"; }\n\n.fa-first-aid::before {\n  content: \"\\f479\"; }\n\n.fa-kitchen-set::before {\n  content: \"\\e51a\"; }\n\n.fa-kiwi-bird::before {\n  content: \"\\f535\"; }\n\n.fa-l::before {\n  content: \"\\4c\"; }\n\n.fa-land-mine-on::before {\n  content: \"\\e51b\"; }\n\n.fa-landmark::before {\n  content: \"\\f66f\"; }\n\n.fa-landmark-dome::before {\n  content: \"\\f752\"; }\n\n.fa-landmark-alt::before {\n  content: \"\\f752\"; }\n\n.fa-landmark-flag::before {\n  content: \"\\e51c\"; }\n\n.fa-language::before {\n  content: \"\\f1ab\"; }\n\n.fa-laptop::before {\n  content: \"\\f109\"; }\n\n.fa-laptop-code::before {\n  content: \"\\f5fc\"; }\n\n.fa-laptop-file::before {\n  content: \"\\e51d\"; }\n\n.fa-laptop-medical::before {\n  content: \"\\f812\"; }\n\n.fa-lari-sign::before {\n  content: \"\\e1c8\"; }\n\n.fa-layer-group::before {\n  content: \"\\f5fd\"; }\n\n.fa-leaf::before {\n  content: \"\\f06c\"; }\n\n.fa-left-long::before {\n  content: \"\\f30a\"; }\n\n.fa-long-arrow-alt-left::before {\n  content: \"\\f30a\"; }\n\n.fa-left-right::before {\n  content: \"\\f337\"; }\n\n.fa-arrows-alt-h::before {\n  content: \"\\f337\"; }\n\n.fa-lemon::before {\n  content: \"\\f094\"; }\n\n.fa-less-than::before {\n  content: \"\\3c\"; }\n\n.fa-less-than-equal::before {\n  content: \"\\f537\"; }\n\n.fa-life-ring::before {\n  content: \"\\f1cd\"; }\n\n.fa-lightbulb::before {\n  content: \"\\f0eb\"; }\n\n.fa-lines-leaning::before {\n  content: \"\\e51e\"; }\n\n.fa-link::before {\n  content: \"\\f0c1\"; }\n\n.fa-chain::before {\n  content: \"\\f0c1\"; }\n\n.fa-link-slash::before {\n  content: \"\\f127\"; }\n\n.fa-chain-broken::before {\n  content: \"\\f127\"; }\n\n.fa-chain-slash::before {\n  content: \"\\f127\"; }\n\n.fa-unlink::before {\n  content: \"\\f127\"; }\n\n.fa-lira-sign::before {\n  content: \"\\f195\"; }\n\n.fa-list::before {\n  content: \"\\f03a\"; }\n\n.fa-list-squares::before {\n  content: \"\\f03a\"; }\n\n.fa-list-check::before {\n  content: \"\\f0ae\"; }\n\n.fa-tasks::before {\n  content: \"\\f0ae\"; }\n\n.fa-list-ol::before {\n  content: \"\\f0cb\"; }\n\n.fa-list-1-2::before {\n  content: \"\\f0cb\"; }\n\n.fa-list-numeric::before {\n  content: \"\\f0cb\"; }\n\n.fa-list-ul::before {\n  content: \"\\f0ca\"; }\n\n.fa-list-dots::before {\n  content: \"\\f0ca\"; }\n\n.fa-litecoin-sign::before {\n  content: \"\\e1d3\"; }\n\n.fa-location-arrow::before {\n  content: \"\\f124\"; }\n\n.fa-location-crosshairs::before {\n  content: \"\\f601\"; }\n\n.fa-location::before {\n  content: \"\\f601\"; }\n\n.fa-location-dot::before {\n  content: \"\\f3c5\"; }\n\n.fa-map-marker-alt::before {\n  content: \"\\f3c5\"; }\n\n.fa-location-pin::before {\n  content: \"\\f041\"; }\n\n.fa-map-marker::before {\n  content: \"\\f041\"; }\n\n.fa-location-pin-lock::before {\n  content: \"\\e51f\"; }\n\n.fa-lock::before {\n  content: \"\\f023\"; }\n\n.fa-lock-open::before {\n  content: \"\\f3c1\"; }\n\n.fa-locust::before {\n  content: \"\\e520\"; }\n\n.fa-lungs::before {\n  content: \"\\f604\"; }\n\n.fa-lungs-virus::before {\n  content: \"\\e067\"; }\n\n.fa-m::before {\n  content: \"\\4d\"; }\n\n.fa-magnet::before {\n  content: \"\\f076\"; }\n\n.fa-magnifying-glass::before {\n  content: \"\\f002\"; }\n\n.fa-search::before {\n  content: \"\\f002\"; }\n\n.fa-magnifying-glass-arrow-right::before {\n  content: \"\\e521\"; }\n\n.fa-magnifying-glass-chart::before {\n  content: \"\\e522\"; }\n\n.fa-magnifying-glass-dollar::before {\n  content: \"\\f688\"; }\n\n.fa-search-dollar::before {\n  content: \"\\f688\"; }\n\n.fa-magnifying-glass-location::before {\n  content: \"\\f689\"; }\n\n.fa-search-location::before {\n  content: \"\\f689\"; }\n\n.fa-magnifying-glass-minus::before {\n  content: \"\\f010\"; }\n\n.fa-search-minus::before {\n  content: \"\\f010\"; }\n\n.fa-magnifying-glass-plus::before {\n  content: \"\\f00e\"; }\n\n.fa-search-plus::before {\n  content: \"\\f00e\"; }\n\n.fa-manat-sign::before {\n  content: \"\\e1d5\"; }\n\n.fa-map::before {\n  content: \"\\f279\"; }\n\n.fa-map-location::before {\n  content: \"\\f59f\"; }\n\n.fa-map-marked::before {\n  content: \"\\f59f\"; }\n\n.fa-map-location-dot::before {\n  content: \"\\f5a0\"; }\n\n.fa-map-marked-alt::before {\n  content: \"\\f5a0\"; }\n\n.fa-map-pin::before {\n  content: \"\\f276\"; }\n\n.fa-marker::before {\n  content: \"\\f5a1\"; }\n\n.fa-mars::before {\n  content: \"\\f222\"; }\n\n.fa-mars-and-venus::before {\n  content: \"\\f224\"; }\n\n.fa-mars-and-venus-burst::before {\n  content: \"\\e523\"; }\n\n.fa-mars-double::before {\n  content: \"\\f227\"; }\n\n.fa-mars-stroke::before {\n  content: \"\\f229\"; }\n\n.fa-mars-stroke-right::before {\n  content: \"\\f22b\"; }\n\n.fa-mars-stroke-h::before {\n  content: \"\\f22b\"; }\n\n.fa-mars-stroke-up::before {\n  content: \"\\f22a\"; }\n\n.fa-mars-stroke-v::before {\n  content: \"\\f22a\"; }\n\n.fa-martini-glass::before {\n  content: \"\\f57b\"; }\n\n.fa-glass-martini-alt::before {\n  content: \"\\f57b\"; }\n\n.fa-martini-glass-citrus::before {\n  content: \"\\f561\"; }\n\n.fa-cocktail::before {\n  content: \"\\f561\"; }\n\n.fa-martini-glass-empty::before {\n  content: \"\\f000\"; }\n\n.fa-glass-martini::before {\n  content: \"\\f000\"; }\n\n.fa-mask::before {\n  content: \"\\f6fa\"; }\n\n.fa-mask-face::before {\n  content: \"\\e1d7\"; }\n\n.fa-mask-ventilator::before {\n  content: \"\\e524\"; }\n\n.fa-masks-theater::before {\n  content: \"\\f630\"; }\n\n.fa-theater-masks::before {\n  content: \"\\f630\"; }\n\n.fa-mattress-pillow::before {\n  content: \"\\e525\"; }\n\n.fa-maximize::before {\n  content: \"\\f31e\"; }\n\n.fa-expand-arrows-alt::before {\n  content: \"\\f31e\"; }\n\n.fa-medal::before {\n  content: \"\\f5a2\"; }\n\n.fa-memory::before {\n  content: \"\\f538\"; }\n\n.fa-menorah::before {\n  content: \"\\f676\"; }\n\n.fa-mercury::before {\n  content: \"\\f223\"; }\n\n.fa-message::before {\n  content: \"\\f27a\"; }\n\n.fa-comment-alt::before {\n  content: \"\\f27a\"; }\n\n.fa-meteor::before {\n  content: \"\\f753\"; }\n\n.fa-microchip::before {\n  content: \"\\f2db\"; }\n\n.fa-microphone::before {\n  content: \"\\f130\"; }\n\n.fa-microphone-lines::before {\n  content: \"\\f3c9\"; }\n\n.fa-microphone-alt::before {\n  content: \"\\f3c9\"; }\n\n.fa-microphone-lines-slash::before {\n  content: \"\\f539\"; }\n\n.fa-microphone-alt-slash::before {\n  content: \"\\f539\"; }\n\n.fa-microphone-slash::before {\n  content: \"\\f131\"; }\n\n.fa-microscope::before {\n  content: \"\\f610\"; }\n\n.fa-mill-sign::before {\n  content: \"\\e1ed\"; }\n\n.fa-minimize::before {\n  content: \"\\f78c\"; }\n\n.fa-compress-arrows-alt::before {\n  content: \"\\f78c\"; }\n\n.fa-minus::before {\n  content: \"\\f068\"; }\n\n.fa-subtract::before {\n  content: \"\\f068\"; }\n\n.fa-mitten::before {\n  content: \"\\f7b5\"; }\n\n.fa-mobile::before {\n  content: \"\\f3ce\"; }\n\n.fa-mobile-android::before {\n  content: \"\\f3ce\"; }\n\n.fa-mobile-phone::before {\n  content: \"\\f3ce\"; }\n\n.fa-mobile-button::before {\n  content: \"\\f10b\"; }\n\n.fa-mobile-retro::before {\n  content: \"\\e527\"; }\n\n.fa-mobile-screen::before {\n  content: \"\\f3cf\"; }\n\n.fa-mobile-android-alt::before {\n  content: \"\\f3cf\"; }\n\n.fa-mobile-screen-button::before {\n  content: \"\\f3cd\"; }\n\n.fa-mobile-alt::before {\n  content: \"\\f3cd\"; }\n\n.fa-money-bill::before {\n  content: \"\\f0d6\"; }\n\n.fa-money-bill-1::before {\n  content: \"\\f3d1\"; }\n\n.fa-money-bill-alt::before {\n  content: \"\\f3d1\"; }\n\n.fa-money-bill-1-wave::before {\n  content: \"\\f53b\"; }\n\n.fa-money-bill-wave-alt::before {\n  content: \"\\f53b\"; }\n\n.fa-money-bill-transfer::before {\n  content: \"\\e528\"; }\n\n.fa-money-bill-trend-up::before {\n  content: \"\\e529\"; }\n\n.fa-money-bill-wave::before {\n  content: \"\\f53a\"; }\n\n.fa-money-bill-wheat::before {\n  content: \"\\e52a\"; }\n\n.fa-money-bills::before {\n  content: \"\\e1f3\"; }\n\n.fa-money-check::before {\n  content: \"\\f53c\"; }\n\n.fa-money-check-dollar::before {\n  content: \"\\f53d\"; }\n\n.fa-money-check-alt::before {\n  content: \"\\f53d\"; }\n\n.fa-monument::before {\n  content: \"\\f5a6\"; }\n\n.fa-moon::before {\n  content: \"\\f186\"; }\n\n.fa-mortar-pestle::before {\n  content: \"\\f5a7\"; }\n\n.fa-mosque::before {\n  content: \"\\f678\"; }\n\n.fa-mosquito::before {\n  content: \"\\e52b\"; }\n\n.fa-mosquito-net::before {\n  content: \"\\e52c\"; }\n\n.fa-motorcycle::before {\n  content: \"\\f21c\"; }\n\n.fa-mound::before {\n  content: \"\\e52d\"; }\n\n.fa-mountain::before {\n  content: \"\\f6fc\"; }\n\n.fa-mountain-city::before {\n  content: \"\\e52e\"; }\n\n.fa-mountain-sun::before {\n  content: \"\\e52f\"; }\n\n.fa-mug-hot::before {\n  content: \"\\f7b6\"; }\n\n.fa-mug-saucer::before {\n  content: \"\\f0f4\"; }\n\n.fa-coffee::before {\n  content: \"\\f0f4\"; }\n\n.fa-music::before {\n  content: \"\\f001\"; }\n\n.fa-n::before {\n  content: \"\\4e\"; }\n\n.fa-naira-sign::before {\n  content: \"\\e1f6\"; }\n\n.fa-network-wired::before {\n  content: \"\\f6ff\"; }\n\n.fa-neuter::before {\n  content: \"\\f22c\"; }\n\n.fa-newspaper::before {\n  content: \"\\f1ea\"; }\n\n.fa-not-equal::before {\n  content: \"\\f53e\"; }\n\n.fa-note-sticky::before {\n  content: \"\\f249\"; }\n\n.fa-sticky-note::before {\n  content: \"\\f249\"; }\n\n.fa-notes-medical::before {\n  content: \"\\f481\"; }\n\n.fa-o::before {\n  content: \"\\4f\"; }\n\n.fa-object-group::before {\n  content: \"\\f247\"; }\n\n.fa-object-ungroup::before {\n  content: \"\\f248\"; }\n\n.fa-oil-can::before {\n  content: \"\\f613\"; }\n\n.fa-oil-well::before {\n  content: \"\\e532\"; }\n\n.fa-om::before {\n  content: \"\\f679\"; }\n\n.fa-otter::before {\n  content: \"\\f700\"; }\n\n.fa-outdent::before {\n  content: \"\\f03b\"; }\n\n.fa-dedent::before {\n  content: \"\\f03b\"; }\n\n.fa-p::before {\n  content: \"\\50\"; }\n\n.fa-pager::before {\n  content: \"\\f815\"; }\n\n.fa-paint-roller::before {\n  content: \"\\f5aa\"; }\n\n.fa-paintbrush::before {\n  content: \"\\f1fc\"; }\n\n.fa-paint-brush::before {\n  content: \"\\f1fc\"; }\n\n.fa-palette::before {\n  content: \"\\f53f\"; }\n\n.fa-pallet::before {\n  content: \"\\f482\"; }\n\n.fa-panorama::before {\n  content: \"\\e209\"; }\n\n.fa-paper-plane::before {\n  content: \"\\f1d8\"; }\n\n.fa-paperclip::before {\n  content: \"\\f0c6\"; }\n\n.fa-parachute-box::before {\n  content: \"\\f4cd\"; }\n\n.fa-paragraph::before {\n  content: \"\\f1dd\"; }\n\n.fa-passport::before {\n  content: \"\\f5ab\"; }\n\n.fa-paste::before {\n  content: \"\\f0ea\"; }\n\n.fa-file-clipboard::before {\n  content: \"\\f0ea\"; }\n\n.fa-pause::before {\n  content: \"\\f04c\"; }\n\n.fa-paw::before {\n  content: \"\\f1b0\"; }\n\n.fa-peace::before {\n  content: \"\\f67c\"; }\n\n.fa-pen::before {\n  content: \"\\f304\"; }\n\n.fa-pen-clip::before {\n  content: \"\\f305\"; }\n\n.fa-pen-alt::before {\n  content: \"\\f305\"; }\n\n.fa-pen-fancy::before {\n  content: \"\\f5ac\"; }\n\n.fa-pen-nib::before {\n  content: \"\\f5ad\"; }\n\n.fa-pen-ruler::before {\n  content: \"\\f5ae\"; }\n\n.fa-pencil-ruler::before {\n  content: \"\\f5ae\"; }\n\n.fa-pen-to-square::before {\n  content: \"\\f044\"; }\n\n.fa-edit::before {\n  content: \"\\f044\"; }\n\n.fa-pencil::before {\n  content: \"\\f303\"; }\n\n.fa-pencil-alt::before {\n  content: \"\\f303\"; }\n\n.fa-people-arrows-left-right::before {\n  content: \"\\e068\"; }\n\n.fa-people-arrows::before {\n  content: \"\\e068\"; }\n\n.fa-people-carry-box::before {\n  content: \"\\f4ce\"; }\n\n.fa-people-carry::before {\n  content: \"\\f4ce\"; }\n\n.fa-people-group::before {\n  content: \"\\e533\"; }\n\n.fa-people-line::before {\n  content: \"\\e534\"; }\n\n.fa-people-pulling::before {\n  content: \"\\e535\"; }\n\n.fa-people-robbery::before {\n  content: \"\\e536\"; }\n\n.fa-people-roof::before {\n  content: \"\\e537\"; }\n\n.fa-pepper-hot::before {\n  content: \"\\f816\"; }\n\n.fa-percent::before {\n  content: \"\\25\"; }\n\n.fa-percentage::before {\n  content: \"\\25\"; }\n\n.fa-person::before {\n  content: \"\\f183\"; }\n\n.fa-male::before {\n  content: \"\\f183\"; }\n\n.fa-person-arrow-down-to-line::before {\n  content: \"\\e538\"; }\n\n.fa-person-arrow-up-from-line::before {\n  content: \"\\e539\"; }\n\n.fa-person-biking::before {\n  content: \"\\f84a\"; }\n\n.fa-biking::before {\n  content: \"\\f84a\"; }\n\n.fa-person-booth::before {\n  content: \"\\f756\"; }\n\n.fa-person-breastfeeding::before {\n  content: \"\\e53a\"; }\n\n.fa-person-burst::before {\n  content: \"\\e53b\"; }\n\n.fa-person-cane::before {\n  content: \"\\e53c\"; }\n\n.fa-person-chalkboard::before {\n  content: \"\\e53d\"; }\n\n.fa-person-circle-check::before {\n  content: \"\\e53e\"; }\n\n.fa-person-circle-exclamation::before {\n  content: \"\\e53f\"; }\n\n.fa-person-circle-minus::before {\n  content: \"\\e540\"; }\n\n.fa-person-circle-plus::before {\n  content: \"\\e541\"; }\n\n.fa-person-circle-question::before {\n  content: \"\\e542\"; }\n\n.fa-person-circle-xmark::before {\n  content: \"\\e543\"; }\n\n.fa-person-digging::before {\n  content: \"\\f85e\"; }\n\n.fa-digging::before {\n  content: \"\\f85e\"; }\n\n.fa-person-dots-from-line::before {\n  content: \"\\f470\"; }\n\n.fa-diagnoses::before {\n  content: \"\\f470\"; }\n\n.fa-person-dress::before {\n  content: \"\\f182\"; }\n\n.fa-female::before {\n  content: \"\\f182\"; }\n\n.fa-person-dress-burst::before {\n  content: \"\\e544\"; }\n\n.fa-person-drowning::before {\n  content: \"\\e545\"; }\n\n.fa-person-falling::before {\n  content: \"\\e546\"; }\n\n.fa-person-falling-burst::before {\n  content: \"\\e547\"; }\n\n.fa-person-half-dress::before {\n  content: \"\\e548\"; }\n\n.fa-person-harassing::before {\n  content: \"\\e549\"; }\n\n.fa-person-hiking::before {\n  content: \"\\f6ec\"; }\n\n.fa-hiking::before {\n  content: \"\\f6ec\"; }\n\n.fa-person-military-pointing::before {\n  content: \"\\e54a\"; }\n\n.fa-person-military-rifle::before {\n  content: \"\\e54b\"; }\n\n.fa-person-military-to-person::before {\n  content: \"\\e54c\"; }\n\n.fa-person-praying::before {\n  content: \"\\f683\"; }\n\n.fa-pray::before {\n  content: \"\\f683\"; }\n\n.fa-person-pregnant::before {\n  content: \"\\e31e\"; }\n\n.fa-person-rays::before {\n  content: \"\\e54d\"; }\n\n.fa-person-rifle::before {\n  content: \"\\e54e\"; }\n\n.fa-person-running::before {\n  content: \"\\f70c\"; }\n\n.fa-running::before {\n  content: \"\\f70c\"; }\n\n.fa-person-shelter::before {\n  content: \"\\e54f\"; }\n\n.fa-person-skating::before {\n  content: \"\\f7c5\"; }\n\n.fa-skating::before {\n  content: \"\\f7c5\"; }\n\n.fa-person-skiing::before {\n  content: \"\\f7c9\"; }\n\n.fa-skiing::before {\n  content: \"\\f7c9\"; }\n\n.fa-person-skiing-nordic::before {\n  content: \"\\f7ca\"; }\n\n.fa-skiing-nordic::before {\n  content: \"\\f7ca\"; }\n\n.fa-person-snowboarding::before {\n  content: \"\\f7ce\"; }\n\n.fa-snowboarding::before {\n  content: \"\\f7ce\"; }\n\n.fa-person-swimming::before {\n  content: \"\\f5c4\"; }\n\n.fa-swimmer::before {\n  content: \"\\f5c4\"; }\n\n.fa-person-through-window::before {\n  content: \"\\e433\"; }\n\n.fa-person-walking::before {\n  content: \"\\f554\"; }\n\n.fa-walking::before {\n  content: \"\\f554\"; }\n\n.fa-person-walking-arrow-loop-left::before {\n  content: \"\\e551\"; }\n\n.fa-person-walking-arrow-right::before {\n  content: \"\\e552\"; }\n\n.fa-person-walking-dashed-line-arrow-right::before {\n  content: \"\\e553\"; }\n\n.fa-person-walking-luggage::before {\n  content: \"\\e554\"; }\n\n.fa-person-walking-with-cane::before {\n  content: \"\\f29d\"; }\n\n.fa-blind::before {\n  content: \"\\f29d\"; }\n\n.fa-peseta-sign::before {\n  content: \"\\e221\"; }\n\n.fa-peso-sign::before {\n  content: \"\\e222\"; }\n\n.fa-phone::before {\n  content: \"\\f095\"; }\n\n.fa-phone-flip::before {\n  content: \"\\f879\"; }\n\n.fa-phone-alt::before {\n  content: \"\\f879\"; }\n\n.fa-phone-slash::before {\n  content: \"\\f3dd\"; }\n\n.fa-phone-volume::before {\n  content: \"\\f2a0\"; }\n\n.fa-volume-control-phone::before {\n  content: \"\\f2a0\"; }\n\n.fa-photo-film::before {\n  content: \"\\f87c\"; }\n\n.fa-photo-video::before {\n  content: \"\\f87c\"; }\n\n.fa-piggy-bank::before {\n  content: \"\\f4d3\"; }\n\n.fa-pills::before {\n  content: \"\\f484\"; }\n\n.fa-pizza-slice::before {\n  content: \"\\f818\"; }\n\n.fa-place-of-worship::before {\n  content: \"\\f67f\"; }\n\n.fa-plane::before {\n  content: \"\\f072\"; }\n\n.fa-plane-arrival::before {\n  content: \"\\f5af\"; }\n\n.fa-plane-circle-check::before {\n  content: \"\\e555\"; }\n\n.fa-plane-circle-exclamation::before {\n  content: \"\\e556\"; }\n\n.fa-plane-circle-xmark::before {\n  content: \"\\e557\"; }\n\n.fa-plane-departure::before {\n  content: \"\\f5b0\"; }\n\n.fa-plane-lock::before {\n  content: \"\\e558\"; }\n\n.fa-plane-slash::before {\n  content: \"\\e069\"; }\n\n.fa-plane-up::before {\n  content: \"\\e22d\"; }\n\n.fa-plant-wilt::before {\n  content: \"\\e43b\"; }\n\n.fa-plate-wheat::before {\n  content: \"\\e55a\"; }\n\n.fa-play::before {\n  content: \"\\f04b\"; }\n\n.fa-plug::before {\n  content: \"\\f1e6\"; }\n\n.fa-plug-circle-bolt::before {\n  content: \"\\e55b\"; }\n\n.fa-plug-circle-check::before {\n  content: \"\\e55c\"; }\n\n.fa-plug-circle-exclamation::before {\n  content: \"\\e55d\"; }\n\n.fa-plug-circle-minus::before {\n  content: \"\\e55e\"; }\n\n.fa-plug-circle-plus::before {\n  content: \"\\e55f\"; }\n\n.fa-plug-circle-xmark::before {\n  content: \"\\e560\"; }\n\n.fa-plus::before {\n  content: \"\\2b\"; }\n\n.fa-add::before {\n  content: \"\\2b\"; }\n\n.fa-plus-minus::before {\n  content: \"\\e43c\"; }\n\n.fa-podcast::before {\n  content: \"\\f2ce\"; }\n\n.fa-poo::before {\n  content: \"\\f2fe\"; }\n\n.fa-poo-storm::before {\n  content: \"\\f75a\"; }\n\n.fa-poo-bolt::before {\n  content: \"\\f75a\"; }\n\n.fa-poop::before {\n  content: \"\\f619\"; }\n\n.fa-power-off::before {\n  content: \"\\f011\"; }\n\n.fa-prescription::before {\n  content: \"\\f5b1\"; }\n\n.fa-prescription-bottle::before {\n  content: \"\\f485\"; }\n\n.fa-prescription-bottle-medical::before {\n  content: \"\\f486\"; }\n\n.fa-prescription-bottle-alt::before {\n  content: \"\\f486\"; }\n\n.fa-print::before {\n  content: \"\\f02f\"; }\n\n.fa-pump-medical::before {\n  content: \"\\e06a\"; }\n\n.fa-pump-soap::before {\n  content: \"\\e06b\"; }\n\n.fa-puzzle-piece::before {\n  content: \"\\f12e\"; }\n\n.fa-q::before {\n  content: \"\\51\"; }\n\n.fa-qrcode::before {\n  content: \"\\f029\"; }\n\n.fa-question::before {\n  content: \"\\3f\"; }\n\n.fa-quote-left::before {\n  content: \"\\f10d\"; }\n\n.fa-quote-left-alt::before {\n  content: \"\\f10d\"; }\n\n.fa-quote-right::before {\n  content: \"\\f10e\"; }\n\n.fa-quote-right-alt::before {\n  content: \"\\f10e\"; }\n\n.fa-r::before {\n  content: \"\\52\"; }\n\n.fa-radiation::before {\n  content: \"\\f7b9\"; }\n\n.fa-radio::before {\n  content: \"\\f8d7\"; }\n\n.fa-rainbow::before {\n  content: \"\\f75b\"; }\n\n.fa-ranking-star::before {\n  content: \"\\e561\"; }\n\n.fa-receipt::before {\n  content: \"\\f543\"; }\n\n.fa-record-vinyl::before {\n  content: \"\\f8d9\"; }\n\n.fa-rectangle-ad::before {\n  content: \"\\f641\"; }\n\n.fa-ad::before {\n  content: \"\\f641\"; }\n\n.fa-rectangle-list::before {\n  content: \"\\f022\"; }\n\n.fa-list-alt::before {\n  content: \"\\f022\"; }\n\n.fa-rectangle-xmark::before {\n  content: \"\\f410\"; }\n\n.fa-rectangle-times::before {\n  content: \"\\f410\"; }\n\n.fa-times-rectangle::before {\n  content: \"\\f410\"; }\n\n.fa-window-close::before {\n  content: \"\\f410\"; }\n\n.fa-recycle::before {\n  content: \"\\f1b8\"; }\n\n.fa-registered::before {\n  content: \"\\f25d\"; }\n\n.fa-repeat::before {\n  content: \"\\f363\"; }\n\n.fa-reply::before {\n  content: \"\\f3e5\"; }\n\n.fa-mail-reply::before {\n  content: \"\\f3e5\"; }\n\n.fa-reply-all::before {\n  content: \"\\f122\"; }\n\n.fa-mail-reply-all::before {\n  content: \"\\f122\"; }\n\n.fa-republican::before {\n  content: \"\\f75e\"; }\n\n.fa-restroom::before {\n  content: \"\\f7bd\"; }\n\n.fa-retweet::before {\n  content: \"\\f079\"; }\n\n.fa-ribbon::before {\n  content: \"\\f4d6\"; }\n\n.fa-right-from-bracket::before {\n  content: \"\\f2f5\"; }\n\n.fa-sign-out-alt::before {\n  content: \"\\f2f5\"; }\n\n.fa-right-left::before {\n  content: \"\\f362\"; }\n\n.fa-exchange-alt::before {\n  content: \"\\f362\"; }\n\n.fa-right-long::before {\n  content: \"\\f30b\"; }\n\n.fa-long-arrow-alt-right::before {\n  content: \"\\f30b\"; }\n\n.fa-right-to-bracket::before {\n  content: \"\\f2f6\"; }\n\n.fa-sign-in-alt::before {\n  content: \"\\f2f6\"; }\n\n.fa-ring::before {\n  content: \"\\f70b\"; }\n\n.fa-road::before {\n  content: \"\\f018\"; }\n\n.fa-road-barrier::before {\n  content: \"\\e562\"; }\n\n.fa-road-bridge::before {\n  content: \"\\e563\"; }\n\n.fa-road-circle-check::before {\n  content: \"\\e564\"; }\n\n.fa-road-circle-exclamation::before {\n  content: \"\\e565\"; }\n\n.fa-road-circle-xmark::before {\n  content: \"\\e566\"; }\n\n.fa-road-lock::before {\n  content: \"\\e567\"; }\n\n.fa-road-spikes::before {\n  content: \"\\e568\"; }\n\n.fa-robot::before {\n  content: \"\\f544\"; }\n\n.fa-rocket::before {\n  content: \"\\f135\"; }\n\n.fa-rotate::before {\n  content: \"\\f2f1\"; }\n\n.fa-sync-alt::before {\n  content: \"\\f2f1\"; }\n\n.fa-rotate-left::before {\n  content: \"\\f2ea\"; }\n\n.fa-rotate-back::before {\n  content: \"\\f2ea\"; }\n\n.fa-rotate-backward::before {\n  content: \"\\f2ea\"; }\n\n.fa-undo-alt::before {\n  content: \"\\f2ea\"; }\n\n.fa-rotate-right::before {\n  content: \"\\f2f9\"; }\n\n.fa-redo-alt::before {\n  content: \"\\f2f9\"; }\n\n.fa-rotate-forward::before {\n  content: \"\\f2f9\"; }\n\n.fa-route::before {\n  content: \"\\f4d7\"; }\n\n.fa-rss::before {\n  content: \"\\f09e\"; }\n\n.fa-feed::before {\n  content: \"\\f09e\"; }\n\n.fa-ruble-sign::before {\n  content: \"\\f158\"; }\n\n.fa-rouble::before {\n  content: \"\\f158\"; }\n\n.fa-rub::before {\n  content: \"\\f158\"; }\n\n.fa-ruble::before {\n  content: \"\\f158\"; }\n\n.fa-rug::before {\n  content: \"\\e569\"; }\n\n.fa-ruler::before {\n  content: \"\\f545\"; }\n\n.fa-ruler-combined::before {\n  content: \"\\f546\"; }\n\n.fa-ruler-horizontal::before {\n  content: \"\\f547\"; }\n\n.fa-ruler-vertical::before {\n  content: \"\\f548\"; }\n\n.fa-rupee-sign::before {\n  content: \"\\f156\"; }\n\n.fa-rupee::before {\n  content: \"\\f156\"; }\n\n.fa-rupiah-sign::before {\n  content: \"\\e23d\"; }\n\n.fa-s::before {\n  content: \"\\53\"; }\n\n.fa-sack-dollar::before {\n  content: \"\\f81d\"; }\n\n.fa-sack-xmark::before {\n  content: \"\\e56a\"; }\n\n.fa-sailboat::before {\n  content: \"\\e445\"; }\n\n.fa-satellite::before {\n  content: \"\\f7bf\"; }\n\n.fa-satellite-dish::before {\n  content: \"\\f7c0\"; }\n\n.fa-scale-balanced::before {\n  content: \"\\f24e\"; }\n\n.fa-balance-scale::before {\n  content: \"\\f24e\"; }\n\n.fa-scale-unbalanced::before {\n  content: \"\\f515\"; }\n\n.fa-balance-scale-left::before {\n  content: \"\\f515\"; }\n\n.fa-scale-unbalanced-flip::before {\n  content: \"\\f516\"; }\n\n.fa-balance-scale-right::before {\n  content: \"\\f516\"; }\n\n.fa-school::before {\n  content: \"\\f549\"; }\n\n.fa-school-circle-check::before {\n  content: \"\\e56b\"; }\n\n.fa-school-circle-exclamation::before {\n  content: \"\\e56c\"; }\n\n.fa-school-circle-xmark::before {\n  content: \"\\e56d\"; }\n\n.fa-school-flag::before {\n  content: \"\\e56e\"; }\n\n.fa-school-lock::before {\n  content: \"\\e56f\"; }\n\n.fa-scissors::before {\n  content: \"\\f0c4\"; }\n\n.fa-cut::before {\n  content: \"\\f0c4\"; }\n\n.fa-screwdriver::before {\n  content: \"\\f54a\"; }\n\n.fa-screwdriver-wrench::before {\n  content: \"\\f7d9\"; }\n\n.fa-tools::before {\n  content: \"\\f7d9\"; }\n\n.fa-scroll::before {\n  content: \"\\f70e\"; }\n\n.fa-scroll-torah::before {\n  content: \"\\f6a0\"; }\n\n.fa-torah::before {\n  content: \"\\f6a0\"; }\n\n.fa-sd-card::before {\n  content: \"\\f7c2\"; }\n\n.fa-section::before {\n  content: \"\\e447\"; }\n\n.fa-seedling::before {\n  content: \"\\f4d8\"; }\n\n.fa-sprout::before {\n  content: \"\\f4d8\"; }\n\n.fa-server::before {\n  content: \"\\f233\"; }\n\n.fa-shapes::before {\n  content: \"\\f61f\"; }\n\n.fa-triangle-circle-square::before {\n  content: \"\\f61f\"; }\n\n.fa-share::before {\n  content: \"\\f064\"; }\n\n.fa-arrow-turn-right::before {\n  content: \"\\f064\"; }\n\n.fa-mail-forward::before {\n  content: \"\\f064\"; }\n\n.fa-share-from-square::before {\n  content: \"\\f14d\"; }\n\n.fa-share-square::before {\n  content: \"\\f14d\"; }\n\n.fa-share-nodes::before {\n  content: \"\\f1e0\"; }\n\n.fa-share-alt::before {\n  content: \"\\f1e0\"; }\n\n.fa-sheet-plastic::before {\n  content: \"\\e571\"; }\n\n.fa-shekel-sign::before {\n  content: \"\\f20b\"; }\n\n.fa-ils::before {\n  content: \"\\f20b\"; }\n\n.fa-shekel::before {\n  content: \"\\f20b\"; }\n\n.fa-sheqel::before {\n  content: \"\\f20b\"; }\n\n.fa-sheqel-sign::before {\n  content: \"\\f20b\"; }\n\n.fa-shield::before {\n  content: \"\\f132\"; }\n\n.fa-shield-blank::before {\n  content: \"\\f132\"; }\n\n.fa-shield-cat::before {\n  content: \"\\e572\"; }\n\n.fa-shield-dog::before {\n  content: \"\\e573\"; }\n\n.fa-shield-halved::before {\n  content: \"\\f3ed\"; }\n\n.fa-shield-alt::before {\n  content: \"\\f3ed\"; }\n\n.fa-shield-heart::before {\n  content: \"\\e574\"; }\n\n.fa-shield-virus::before {\n  content: \"\\e06c\"; }\n\n.fa-ship::before {\n  content: \"\\f21a\"; }\n\n.fa-shirt::before {\n  content: \"\\f553\"; }\n\n.fa-t-shirt::before {\n  content: \"\\f553\"; }\n\n.fa-tshirt::before {\n  content: \"\\f553\"; }\n\n.fa-shoe-prints::before {\n  content: \"\\f54b\"; }\n\n.fa-shop::before {\n  content: \"\\f54f\"; }\n\n.fa-store-alt::before {\n  content: \"\\f54f\"; }\n\n.fa-shop-lock::before {\n  content: \"\\e4a5\"; }\n\n.fa-shop-slash::before {\n  content: \"\\e070\"; }\n\n.fa-store-alt-slash::before {\n  content: \"\\e070\"; }\n\n.fa-shower::before {\n  content: \"\\f2cc\"; }\n\n.fa-shrimp::before {\n  content: \"\\e448\"; }\n\n.fa-shuffle::before {\n  content: \"\\f074\"; }\n\n.fa-random::before {\n  content: \"\\f074\"; }\n\n.fa-shuttle-space::before {\n  content: \"\\f197\"; }\n\n.fa-space-shuttle::before {\n  content: \"\\f197\"; }\n\n.fa-sign-hanging::before {\n  content: \"\\f4d9\"; }\n\n.fa-sign::before {\n  content: \"\\f4d9\"; }\n\n.fa-signal::before {\n  content: \"\\f012\"; }\n\n.fa-signal-5::before {\n  content: \"\\f012\"; }\n\n.fa-signal-perfect::before {\n  content: \"\\f012\"; }\n\n.fa-signature::before {\n  content: \"\\f5b7\"; }\n\n.fa-signs-post::before {\n  content: \"\\f277\"; }\n\n.fa-map-signs::before {\n  content: \"\\f277\"; }\n\n.fa-sim-card::before {\n  content: \"\\f7c4\"; }\n\n.fa-sink::before {\n  content: \"\\e06d\"; }\n\n.fa-sitemap::before {\n  content: \"\\f0e8\"; }\n\n.fa-skull::before {\n  content: \"\\f54c\"; }\n\n.fa-skull-crossbones::before {\n  content: \"\\f714\"; }\n\n.fa-slash::before {\n  content: \"\\f715\"; }\n\n.fa-sleigh::before {\n  content: \"\\f7cc\"; }\n\n.fa-sliders::before {\n  content: \"\\f1de\"; }\n\n.fa-sliders-h::before {\n  content: \"\\f1de\"; }\n\n.fa-smog::before {\n  content: \"\\f75f\"; }\n\n.fa-smoking::before {\n  content: \"\\f48d\"; }\n\n.fa-snowflake::before {\n  content: \"\\f2dc\"; }\n\n.fa-snowman::before {\n  content: \"\\f7d0\"; }\n\n.fa-snowplow::before {\n  content: \"\\f7d2\"; }\n\n.fa-soap::before {\n  content: \"\\e06e\"; }\n\n.fa-socks::before {\n  content: \"\\f696\"; }\n\n.fa-solar-panel::before {\n  content: \"\\f5ba\"; }\n\n.fa-sort::before {\n  content: \"\\f0dc\"; }\n\n.fa-unsorted::before {\n  content: \"\\f0dc\"; }\n\n.fa-sort-down::before {\n  content: \"\\f0dd\"; }\n\n.fa-sort-desc::before {\n  content: \"\\f0dd\"; }\n\n.fa-sort-up::before {\n  content: \"\\f0de\"; }\n\n.fa-sort-asc::before {\n  content: \"\\f0de\"; }\n\n.fa-spa::before {\n  content: \"\\f5bb\"; }\n\n.fa-spaghetti-monster-flying::before {\n  content: \"\\f67b\"; }\n\n.fa-pastafarianism::before {\n  content: \"\\f67b\"; }\n\n.fa-spell-check::before {\n  content: \"\\f891\"; }\n\n.fa-spider::before {\n  content: \"\\f717\"; }\n\n.fa-spinner::before {\n  content: \"\\f110\"; }\n\n.fa-splotch::before {\n  content: \"\\f5bc\"; }\n\n.fa-spoon::before {\n  content: \"\\f2e5\"; }\n\n.fa-utensil-spoon::before {\n  content: \"\\f2e5\"; }\n\n.fa-spray-can::before {\n  content: \"\\f5bd\"; }\n\n.fa-spray-can-sparkles::before {\n  content: \"\\f5d0\"; }\n\n.fa-air-freshener::before {\n  content: \"\\f5d0\"; }\n\n.fa-square::before {\n  content: \"\\f0c8\"; }\n\n.fa-square-arrow-up-right::before {\n  content: \"\\f14c\"; }\n\n.fa-external-link-square::before {\n  content: \"\\f14c\"; }\n\n.fa-square-caret-down::before {\n  content: \"\\f150\"; }\n\n.fa-caret-square-down::before {\n  content: \"\\f150\"; }\n\n.fa-square-caret-left::before {\n  content: \"\\f191\"; }\n\n.fa-caret-square-left::before {\n  content: \"\\f191\"; }\n\n.fa-square-caret-right::before {\n  content: \"\\f152\"; }\n\n.fa-caret-square-right::before {\n  content: \"\\f152\"; }\n\n.fa-square-caret-up::before {\n  content: \"\\f151\"; }\n\n.fa-caret-square-up::before {\n  content: \"\\f151\"; }\n\n.fa-square-check::before {\n  content: \"\\f14a\"; }\n\n.fa-check-square::before {\n  content: \"\\f14a\"; }\n\n.fa-square-envelope::before {\n  content: \"\\f199\"; }\n\n.fa-envelope-square::before {\n  content: \"\\f199\"; }\n\n.fa-square-full::before {\n  content: \"\\f45c\"; }\n\n.fa-square-h::before {\n  content: \"\\f0fd\"; }\n\n.fa-h-square::before {\n  content: \"\\f0fd\"; }\n\n.fa-square-minus::before {\n  content: \"\\f146\"; }\n\n.fa-minus-square::before {\n  content: \"\\f146\"; }\n\n.fa-square-nfi::before {\n  content: \"\\e576\"; }\n\n.fa-square-parking::before {\n  content: \"\\f540\"; }\n\n.fa-parking::before {\n  content: \"\\f540\"; }\n\n.fa-square-pen::before {\n  content: \"\\f14b\"; }\n\n.fa-pen-square::before {\n  content: \"\\f14b\"; }\n\n.fa-pencil-square::before {\n  content: \"\\f14b\"; }\n\n.fa-square-person-confined::before {\n  content: \"\\e577\"; }\n\n.fa-square-phone::before {\n  content: \"\\f098\"; }\n\n.fa-phone-square::before {\n  content: \"\\f098\"; }\n\n.fa-square-phone-flip::before {\n  content: \"\\f87b\"; }\n\n.fa-phone-square-alt::before {\n  content: \"\\f87b\"; }\n\n.fa-square-plus::before {\n  content: \"\\f0fe\"; }\n\n.fa-plus-square::before {\n  content: \"\\f0fe\"; }\n\n.fa-square-poll-horizontal::before {\n  content: \"\\f682\"; }\n\n.fa-poll-h::before {\n  content: \"\\f682\"; }\n\n.fa-square-poll-vertical::before {\n  content: \"\\f681\"; }\n\n.fa-poll::before {\n  content: \"\\f681\"; }\n\n.fa-square-root-variable::before {\n  content: \"\\f698\"; }\n\n.fa-square-root-alt::before {\n  content: \"\\f698\"; }\n\n.fa-square-rss::before {\n  content: \"\\f143\"; }\n\n.fa-rss-square::before {\n  content: \"\\f143\"; }\n\n.fa-square-share-nodes::before {\n  content: \"\\f1e1\"; }\n\n.fa-share-alt-square::before {\n  content: \"\\f1e1\"; }\n\n.fa-square-up-right::before {\n  content: \"\\f360\"; }\n\n.fa-external-link-square-alt::before {\n  content: \"\\f360\"; }\n\n.fa-square-virus::before {\n  content: \"\\e578\"; }\n\n.fa-square-xmark::before {\n  content: \"\\f2d3\"; }\n\n.fa-times-square::before {\n  content: \"\\f2d3\"; }\n\n.fa-xmark-square::before {\n  content: \"\\f2d3\"; }\n\n.fa-staff-aesculapius::before {\n  content: \"\\e579\"; }\n\n.fa-rod-asclepius::before {\n  content: \"\\e579\"; }\n\n.fa-rod-snake::before {\n  content: \"\\e579\"; }\n\n.fa-staff-snake::before {\n  content: \"\\e579\"; }\n\n.fa-stairs::before {\n  content: \"\\e289\"; }\n\n.fa-stamp::before {\n  content: \"\\f5bf\"; }\n\n.fa-star::before {\n  content: \"\\f005\"; }\n\n.fa-star-and-crescent::before {\n  content: \"\\f699\"; }\n\n.fa-star-half::before {\n  content: \"\\f089\"; }\n\n.fa-star-half-stroke::before {\n  content: \"\\f5c0\"; }\n\n.fa-star-half-alt::before {\n  content: \"\\f5c0\"; }\n\n.fa-star-of-david::before {\n  content: \"\\f69a\"; }\n\n.fa-star-of-life::before {\n  content: \"\\f621\"; }\n\n.fa-sterling-sign::before {\n  content: \"\\f154\"; }\n\n.fa-gbp::before {\n  content: \"\\f154\"; }\n\n.fa-pound-sign::before {\n  content: \"\\f154\"; }\n\n.fa-stethoscope::before {\n  content: \"\\f0f1\"; }\n\n.fa-stop::before {\n  content: \"\\f04d\"; }\n\n.fa-stopwatch::before {\n  content: \"\\f2f2\"; }\n\n.fa-stopwatch-20::before {\n  content: \"\\e06f\"; }\n\n.fa-store::before {\n  content: \"\\f54e\"; }\n\n.fa-store-slash::before {\n  content: \"\\e071\"; }\n\n.fa-street-view::before {\n  content: \"\\f21d\"; }\n\n.fa-strikethrough::before {\n  content: \"\\f0cc\"; }\n\n.fa-stroopwafel::before {\n  content: \"\\f551\"; }\n\n.fa-subscript::before {\n  content: \"\\f12c\"; }\n\n.fa-suitcase::before {\n  content: \"\\f0f2\"; }\n\n.fa-suitcase-medical::before {\n  content: \"\\f0fa\"; }\n\n.fa-medkit::before {\n  content: \"\\f0fa\"; }\n\n.fa-suitcase-rolling::before {\n  content: \"\\f5c1\"; }\n\n.fa-sun::before {\n  content: \"\\f185\"; }\n\n.fa-sun-plant-wilt::before {\n  content: \"\\e57a\"; }\n\n.fa-superscript::before {\n  content: \"\\f12b\"; }\n\n.fa-swatchbook::before {\n  content: \"\\f5c3\"; }\n\n.fa-synagogue::before {\n  content: \"\\f69b\"; }\n\n.fa-syringe::before {\n  content: \"\\f48e\"; }\n\n.fa-t::before {\n  content: \"\\54\"; }\n\n.fa-table::before {\n  content: \"\\f0ce\"; }\n\n.fa-table-cells::before {\n  content: \"\\f00a\"; }\n\n.fa-th::before {\n  content: \"\\f00a\"; }\n\n.fa-table-cells-large::before {\n  content: \"\\f009\"; }\n\n.fa-th-large::before {\n  content: \"\\f009\"; }\n\n.fa-table-columns::before {\n  content: \"\\f0db\"; }\n\n.fa-columns::before {\n  content: \"\\f0db\"; }\n\n.fa-table-list::before {\n  content: \"\\f00b\"; }\n\n.fa-th-list::before {\n  content: \"\\f00b\"; }\n\n.fa-table-tennis-paddle-ball::before {\n  content: \"\\f45d\"; }\n\n.fa-ping-pong-paddle-ball::before {\n  content: \"\\f45d\"; }\n\n.fa-table-tennis::before {\n  content: \"\\f45d\"; }\n\n.fa-tablet::before {\n  content: \"\\f3fb\"; }\n\n.fa-tablet-android::before {\n  content: \"\\f3fb\"; }\n\n.fa-tablet-button::before {\n  content: \"\\f10a\"; }\n\n.fa-tablet-screen-button::before {\n  content: \"\\f3fa\"; }\n\n.fa-tablet-alt::before {\n  content: \"\\f3fa\"; }\n\n.fa-tablets::before {\n  content: \"\\f490\"; }\n\n.fa-tachograph-digital::before {\n  content: \"\\f566\"; }\n\n.fa-digital-tachograph::before {\n  content: \"\\f566\"; }\n\n.fa-tag::before {\n  content: \"\\f02b\"; }\n\n.fa-tags::before {\n  content: \"\\f02c\"; }\n\n.fa-tape::before {\n  content: \"\\f4db\"; }\n\n.fa-tarp::before {\n  content: \"\\e57b\"; }\n\n.fa-tarp-droplet::before {\n  content: \"\\e57c\"; }\n\n.fa-taxi::before {\n  content: \"\\f1ba\"; }\n\n.fa-cab::before {\n  content: \"\\f1ba\"; }\n\n.fa-teeth::before {\n  content: \"\\f62e\"; }\n\n.fa-teeth-open::before {\n  content: \"\\f62f\"; }\n\n.fa-temperature-arrow-down::before {\n  content: \"\\e03f\"; }\n\n.fa-temperature-down::before {\n  content: \"\\e03f\"; }\n\n.fa-temperature-arrow-up::before {\n  content: \"\\e040\"; }\n\n.fa-temperature-up::before {\n  content: \"\\e040\"; }\n\n.fa-temperature-empty::before {\n  content: \"\\f2cb\"; }\n\n.fa-temperature-0::before {\n  content: \"\\f2cb\"; }\n\n.fa-thermometer-0::before {\n  content: \"\\f2cb\"; }\n\n.fa-thermometer-empty::before {\n  content: \"\\f2cb\"; }\n\n.fa-temperature-full::before {\n  content: \"\\f2c7\"; }\n\n.fa-temperature-4::before {\n  content: \"\\f2c7\"; }\n\n.fa-thermometer-4::before {\n  content: \"\\f2c7\"; }\n\n.fa-thermometer-full::before {\n  content: \"\\f2c7\"; }\n\n.fa-temperature-half::before {\n  content: \"\\f2c9\"; }\n\n.fa-temperature-2::before {\n  content: \"\\f2c9\"; }\n\n.fa-thermometer-2::before {\n  content: \"\\f2c9\"; }\n\n.fa-thermometer-half::before {\n  content: \"\\f2c9\"; }\n\n.fa-temperature-high::before {\n  content: \"\\f769\"; }\n\n.fa-temperature-low::before {\n  content: \"\\f76b\"; }\n\n.fa-temperature-quarter::before {\n  content: \"\\f2ca\"; }\n\n.fa-temperature-1::before {\n  content: \"\\f2ca\"; }\n\n.fa-thermometer-1::before {\n  content: \"\\f2ca\"; }\n\n.fa-thermometer-quarter::before {\n  content: \"\\f2ca\"; }\n\n.fa-temperature-three-quarters::before {\n  content: \"\\f2c8\"; }\n\n.fa-temperature-3::before {\n  content: \"\\f2c8\"; }\n\n.fa-thermometer-3::before {\n  content: \"\\f2c8\"; }\n\n.fa-thermometer-three-quarters::before {\n  content: \"\\f2c8\"; }\n\n.fa-tenge-sign::before {\n  content: \"\\f7d7\"; }\n\n.fa-tenge::before {\n  content: \"\\f7d7\"; }\n\n.fa-tent::before {\n  content: \"\\e57d\"; }\n\n.fa-tent-arrow-down-to-line::before {\n  content: \"\\e57e\"; }\n\n.fa-tent-arrow-left-right::before {\n  content: \"\\e57f\"; }\n\n.fa-tent-arrow-turn-left::before {\n  content: \"\\e580\"; }\n\n.fa-tent-arrows-down::before {\n  content: \"\\e581\"; }\n\n.fa-tents::before {\n  content: \"\\e582\"; }\n\n.fa-terminal::before {\n  content: \"\\f120\"; }\n\n.fa-text-height::before {\n  content: \"\\f034\"; }\n\n.fa-text-slash::before {\n  content: \"\\f87d\"; }\n\n.fa-remove-format::before {\n  content: \"\\f87d\"; }\n\n.fa-text-width::before {\n  content: \"\\f035\"; }\n\n.fa-thermometer::before {\n  content: \"\\f491\"; }\n\n.fa-thumbs-down::before {\n  content: \"\\f165\"; }\n\n.fa-thumbs-up::before {\n  content: \"\\f164\"; }\n\n.fa-thumbtack::before {\n  content: \"\\f08d\"; }\n\n.fa-thumb-tack::before {\n  content: \"\\f08d\"; }\n\n.fa-ticket::before {\n  content: \"\\f145\"; }\n\n.fa-ticket-simple::before {\n  content: \"\\f3ff\"; }\n\n.fa-ticket-alt::before {\n  content: \"\\f3ff\"; }\n\n.fa-timeline::before {\n  content: \"\\e29c\"; }\n\n.fa-toggle-off::before {\n  content: \"\\f204\"; }\n\n.fa-toggle-on::before {\n  content: \"\\f205\"; }\n\n.fa-toilet::before {\n  content: \"\\f7d8\"; }\n\n.fa-toilet-paper::before {\n  content: \"\\f71e\"; }\n\n.fa-toilet-paper-slash::before {\n  content: \"\\e072\"; }\n\n.fa-toilet-portable::before {\n  content: \"\\e583\"; }\n\n.fa-toilets-portable::before {\n  content: \"\\e584\"; }\n\n.fa-toolbox::before {\n  content: \"\\f552\"; }\n\n.fa-tooth::before {\n  content: \"\\f5c9\"; }\n\n.fa-torii-gate::before {\n  content: \"\\f6a1\"; }\n\n.fa-tornado::before {\n  content: \"\\f76f\"; }\n\n.fa-tower-broadcast::before {\n  content: \"\\f519\"; }\n\n.fa-broadcast-tower::before {\n  content: \"\\f519\"; }\n\n.fa-tower-cell::before {\n  content: \"\\e585\"; }\n\n.fa-tower-observation::before {\n  content: \"\\e586\"; }\n\n.fa-tractor::before {\n  content: \"\\f722\"; }\n\n.fa-trademark::before {\n  content: \"\\f25c\"; }\n\n.fa-traffic-light::before {\n  content: \"\\f637\"; }\n\n.fa-trailer::before {\n  content: \"\\e041\"; }\n\n.fa-train::before {\n  content: \"\\f238\"; }\n\n.fa-train-subway::before {\n  content: \"\\f239\"; }\n\n.fa-subway::before {\n  content: \"\\f239\"; }\n\n.fa-train-tram::before {\n  content: \"\\f7da\"; }\n\n.fa-tram::before {\n  content: \"\\f7da\"; }\n\n.fa-transgender::before {\n  content: \"\\f225\"; }\n\n.fa-transgender-alt::before {\n  content: \"\\f225\"; }\n\n.fa-trash::before {\n  content: \"\\f1f8\"; }\n\n.fa-trash-arrow-up::before {\n  content: \"\\f829\"; }\n\n.fa-trash-restore::before {\n  content: \"\\f829\"; }\n\n.fa-trash-can::before {\n  content: \"\\f2ed\"; }\n\n.fa-trash-alt::before {\n  content: \"\\f2ed\"; }\n\n.fa-trash-can-arrow-up::before {\n  content: \"\\f82a\"; }\n\n.fa-trash-restore-alt::before {\n  content: \"\\f82a\"; }\n\n.fa-tree::before {\n  content: \"\\f1bb\"; }\n\n.fa-tree-city::before {\n  content: \"\\e587\"; }\n\n.fa-triangle-exclamation::before {\n  content: \"\\f071\"; }\n\n.fa-exclamation-triangle::before {\n  content: \"\\f071\"; }\n\n.fa-warning::before {\n  content: \"\\f071\"; }\n\n.fa-trophy::before {\n  content: \"\\f091\"; }\n\n.fa-trowel::before {\n  content: \"\\e589\"; }\n\n.fa-trowel-bricks::before {\n  content: \"\\e58a\"; }\n\n.fa-truck::before {\n  content: \"\\f0d1\"; }\n\n.fa-truck-arrow-right::before {\n  content: \"\\e58b\"; }\n\n.fa-truck-droplet::before {\n  content: \"\\e58c\"; }\n\n.fa-truck-fast::before {\n  content: \"\\f48b\"; }\n\n.fa-shipping-fast::before {\n  content: \"\\f48b\"; }\n\n.fa-truck-field::before {\n  content: \"\\e58d\"; }\n\n.fa-truck-field-un::before {\n  content: \"\\e58e\"; }\n\n.fa-truck-front::before {\n  content: \"\\e2b7\"; }\n\n.fa-truck-medical::before {\n  content: \"\\f0f9\"; }\n\n.fa-ambulance::before {\n  content: \"\\f0f9\"; }\n\n.fa-truck-monster::before {\n  content: \"\\f63b\"; }\n\n.fa-truck-moving::before {\n  content: \"\\f4df\"; }\n\n.fa-truck-pickup::before {\n  content: \"\\f63c\"; }\n\n.fa-truck-plane::before {\n  content: \"\\e58f\"; }\n\n.fa-truck-ramp-box::before {\n  content: \"\\f4de\"; }\n\n.fa-truck-loading::before {\n  content: \"\\f4de\"; }\n\n.fa-tty::before {\n  content: \"\\f1e4\"; }\n\n.fa-teletype::before {\n  content: \"\\f1e4\"; }\n\n.fa-turkish-lira-sign::before {\n  content: \"\\e2bb\"; }\n\n.fa-try::before {\n  content: \"\\e2bb\"; }\n\n.fa-turkish-lira::before {\n  content: \"\\e2bb\"; }\n\n.fa-turn-down::before {\n  content: \"\\f3be\"; }\n\n.fa-level-down-alt::before {\n  content: \"\\f3be\"; }\n\n.fa-turn-up::before {\n  content: \"\\f3bf\"; }\n\n.fa-level-up-alt::before {\n  content: \"\\f3bf\"; }\n\n.fa-tv::before {\n  content: \"\\f26c\"; }\n\n.fa-television::before {\n  content: \"\\f26c\"; }\n\n.fa-tv-alt::before {\n  content: \"\\f26c\"; }\n\n.fa-u::before {\n  content: \"\\55\"; }\n\n.fa-umbrella::before {\n  content: \"\\f0e9\"; }\n\n.fa-umbrella-beach::before {\n  content: \"\\f5ca\"; }\n\n.fa-underline::before {\n  content: \"\\f0cd\"; }\n\n.fa-universal-access::before {\n  content: \"\\f29a\"; }\n\n.fa-unlock::before {\n  content: \"\\f09c\"; }\n\n.fa-unlock-keyhole::before {\n  content: \"\\f13e\"; }\n\n.fa-unlock-alt::before {\n  content: \"\\f13e\"; }\n\n.fa-up-down::before {\n  content: \"\\f338\"; }\n\n.fa-arrows-alt-v::before {\n  content: \"\\f338\"; }\n\n.fa-up-down-left-right::before {\n  content: \"\\f0b2\"; }\n\n.fa-arrows-alt::before {\n  content: \"\\f0b2\"; }\n\n.fa-up-long::before {\n  content: \"\\f30c\"; }\n\n.fa-long-arrow-alt-up::before {\n  content: \"\\f30c\"; }\n\n.fa-up-right-and-down-left-from-center::before {\n  content: \"\\f424\"; }\n\n.fa-expand-alt::before {\n  content: \"\\f424\"; }\n\n.fa-up-right-from-square::before {\n  content: \"\\f35d\"; }\n\n.fa-external-link-alt::before {\n  content: \"\\f35d\"; }\n\n.fa-upload::before {\n  content: \"\\f093\"; }\n\n.fa-user::before {\n  content: \"\\f007\"; }\n\n.fa-user-astronaut::before {\n  content: \"\\f4fb\"; }\n\n.fa-user-check::before {\n  content: \"\\f4fc\"; }\n\n.fa-user-clock::before {\n  content: \"\\f4fd\"; }\n\n.fa-user-doctor::before {\n  content: \"\\f0f0\"; }\n\n.fa-user-md::before {\n  content: \"\\f0f0\"; }\n\n.fa-user-gear::before {\n  content: \"\\f4fe\"; }\n\n.fa-user-cog::before {\n  content: \"\\f4fe\"; }\n\n.fa-user-graduate::before {\n  content: \"\\f501\"; }\n\n.fa-user-group::before {\n  content: \"\\f500\"; }\n\n.fa-user-friends::before {\n  content: \"\\f500\"; }\n\n.fa-user-injured::before {\n  content: \"\\f728\"; }\n\n.fa-user-large::before {\n  content: \"\\f406\"; }\n\n.fa-user-alt::before {\n  content: \"\\f406\"; }\n\n.fa-user-large-slash::before {\n  content: \"\\f4fa\"; }\n\n.fa-user-alt-slash::before {\n  content: \"\\f4fa\"; }\n\n.fa-user-lock::before {\n  content: \"\\f502\"; }\n\n.fa-user-minus::before {\n  content: \"\\f503\"; }\n\n.fa-user-ninja::before {\n  content: \"\\f504\"; }\n\n.fa-user-nurse::before {\n  content: \"\\f82f\"; }\n\n.fa-user-pen::before {\n  content: \"\\f4ff\"; }\n\n.fa-user-edit::before {\n  content: \"\\f4ff\"; }\n\n.fa-user-plus::before {\n  content: \"\\f234\"; }\n\n.fa-user-secret::before {\n  content: \"\\f21b\"; }\n\n.fa-user-shield::before {\n  content: \"\\f505\"; }\n\n.fa-user-slash::before {\n  content: \"\\f506\"; }\n\n.fa-user-tag::before {\n  content: \"\\f507\"; }\n\n.fa-user-tie::before {\n  content: \"\\f508\"; }\n\n.fa-user-xmark::before {\n  content: \"\\f235\"; }\n\n.fa-user-times::before {\n  content: \"\\f235\"; }\n\n.fa-users::before {\n  content: \"\\f0c0\"; }\n\n.fa-users-between-lines::before {\n  content: \"\\e591\"; }\n\n.fa-users-gear::before {\n  content: \"\\f509\"; }\n\n.fa-users-cog::before {\n  content: \"\\f509\"; }\n\n.fa-users-line::before {\n  content: \"\\e592\"; }\n\n.fa-users-rays::before {\n  content: \"\\e593\"; }\n\n.fa-users-rectangle::before {\n  content: \"\\e594\"; }\n\n.fa-users-slash::before {\n  content: \"\\e073\"; }\n\n.fa-users-viewfinder::before {\n  content: \"\\e595\"; }\n\n.fa-utensils::before {\n  content: \"\\f2e7\"; }\n\n.fa-cutlery::before {\n  content: \"\\f2e7\"; }\n\n.fa-v::before {\n  content: \"\\56\"; }\n\n.fa-van-shuttle::before {\n  content: \"\\f5b6\"; }\n\n.fa-shuttle-van::before {\n  content: \"\\f5b6\"; }\n\n.fa-vault::before {\n  content: \"\\e2c5\"; }\n\n.fa-vector-square::before {\n  content: \"\\f5cb\"; }\n\n.fa-venus::before {\n  content: \"\\f221\"; }\n\n.fa-venus-double::before {\n  content: \"\\f226\"; }\n\n.fa-venus-mars::before {\n  content: \"\\f228\"; }\n\n.fa-vest::before {\n  content: \"\\e085\"; }\n\n.fa-vest-patches::before {\n  content: \"\\e086\"; }\n\n.fa-vial::before {\n  content: \"\\f492\"; }\n\n.fa-vial-circle-check::before {\n  content: \"\\e596\"; }\n\n.fa-vial-virus::before {\n  content: \"\\e597\"; }\n\n.fa-vials::before {\n  content: \"\\f493\"; }\n\n.fa-video::before {\n  content: \"\\f03d\"; }\n\n.fa-video-camera::before {\n  content: \"\\f03d\"; }\n\n.fa-video-slash::before {\n  content: \"\\f4e2\"; }\n\n.fa-vihara::before {\n  content: \"\\f6a7\"; }\n\n.fa-virus::before {\n  content: \"\\e074\"; }\n\n.fa-virus-covid::before {\n  content: \"\\e4a8\"; }\n\n.fa-virus-covid-slash::before {\n  content: \"\\e4a9\"; }\n\n.fa-virus-slash::before {\n  content: \"\\e075\"; }\n\n.fa-viruses::before {\n  content: \"\\e076\"; }\n\n.fa-voicemail::before {\n  content: \"\\f897\"; }\n\n.fa-volcano::before {\n  content: \"\\f770\"; }\n\n.fa-volleyball::before {\n  content: \"\\f45f\"; }\n\n.fa-volleyball-ball::before {\n  content: \"\\f45f\"; }\n\n.fa-volume-high::before {\n  content: \"\\f028\"; }\n\n.fa-volume-up::before {\n  content: \"\\f028\"; }\n\n.fa-volume-low::before {\n  content: \"\\f027\"; }\n\n.fa-volume-down::before {\n  content: \"\\f027\"; }\n\n.fa-volume-off::before {\n  content: \"\\f026\"; }\n\n.fa-volume-xmark::before {\n  content: \"\\f6a9\"; }\n\n.fa-volume-mute::before {\n  content: \"\\f6a9\"; }\n\n.fa-volume-times::before {\n  content: \"\\f6a9\"; }\n\n.fa-vr-cardboard::before {\n  content: \"\\f729\"; }\n\n.fa-w::before {\n  content: \"\\57\"; }\n\n.fa-walkie-talkie::before {\n  content: \"\\f8ef\"; }\n\n.fa-wallet::before {\n  content: \"\\f555\"; }\n\n.fa-wand-magic::before {\n  content: \"\\f0d0\"; }\n\n.fa-magic::before {\n  content: \"\\f0d0\"; }\n\n.fa-wand-magic-sparkles::before {\n  content: \"\\e2ca\"; }\n\n.fa-magic-wand-sparkles::before {\n  content: \"\\e2ca\"; }\n\n.fa-wand-sparkles::before {\n  content: \"\\f72b\"; }\n\n.fa-warehouse::before {\n  content: \"\\f494\"; }\n\n.fa-water::before {\n  content: \"\\f773\"; }\n\n.fa-water-ladder::before {\n  content: \"\\f5c5\"; }\n\n.fa-ladder-water::before {\n  content: \"\\f5c5\"; }\n\n.fa-swimming-pool::before {\n  content: \"\\f5c5\"; }\n\n.fa-wave-square::before {\n  content: \"\\f83e\"; }\n\n.fa-weight-hanging::before {\n  content: \"\\f5cd\"; }\n\n.fa-weight-scale::before {\n  content: \"\\f496\"; }\n\n.fa-weight::before {\n  content: \"\\f496\"; }\n\n.fa-wheat-awn::before {\n  content: \"\\e2cd\"; }\n\n.fa-wheat-alt::before {\n  content: \"\\e2cd\"; }\n\n.fa-wheat-awn-circle-exclamation::before {\n  content: \"\\e598\"; }\n\n.fa-wheelchair::before {\n  content: \"\\f193\"; }\n\n.fa-wheelchair-move::before {\n  content: \"\\e2ce\"; }\n\n.fa-wheelchair-alt::before {\n  content: \"\\e2ce\"; }\n\n.fa-whiskey-glass::before {\n  content: \"\\f7a0\"; }\n\n.fa-glass-whiskey::before {\n  content: \"\\f7a0\"; }\n\n.fa-wifi::before {\n  content: \"\\f1eb\"; }\n\n.fa-wifi-3::before {\n  content: \"\\f1eb\"; }\n\n.fa-wifi-strong::before {\n  content: \"\\f1eb\"; }\n\n.fa-wind::before {\n  content: \"\\f72e\"; }\n\n.fa-window-maximize::before {\n  content: \"\\f2d0\"; }\n\n.fa-window-minimize::before {\n  content: \"\\f2d1\"; }\n\n.fa-window-restore::before {\n  content: \"\\f2d2\"; }\n\n.fa-wine-bottle::before {\n  content: \"\\f72f\"; }\n\n.fa-wine-glass::before {\n  content: \"\\f4e3\"; }\n\n.fa-wine-glass-empty::before {\n  content: \"\\f5ce\"; }\n\n.fa-wine-glass-alt::before {\n  content: \"\\f5ce\"; }\n\n.fa-won-sign::before {\n  content: \"\\f159\"; }\n\n.fa-krw::before {\n  content: \"\\f159\"; }\n\n.fa-won::before {\n  content: \"\\f159\"; }\n\n.fa-worm::before {\n  content: \"\\e599\"; }\n\n.fa-wrench::before {\n  content: \"\\f0ad\"; }\n\n.fa-x::before {\n  content: \"\\58\"; }\n\n.fa-x-ray::before {\n  content: \"\\f497\"; }\n\n.fa-xmark::before {\n  content: \"\\f00d\"; }\n\n.fa-close::before {\n  content: \"\\f00d\"; }\n\n.fa-multiply::before {\n  content: \"\\f00d\"; }\n\n.fa-remove::before {\n  content: \"\\f00d\"; }\n\n.fa-times::before {\n  content: \"\\f00d\"; }\n\n.fa-xmarks-lines::before {\n  content: \"\\e59a\"; }\n\n.fa-y::before {\n  content: \"\\59\"; }\n\n.fa-yen-sign::before {\n  content: \"\\f157\"; }\n\n.fa-cny::before {\n  content: \"\\f157\"; }\n\n.fa-jpy::before {\n  content: \"\\f157\"; }\n\n.fa-rmb::before {\n  content: \"\\f157\"; }\n\n.fa-yen::before {\n  content: \"\\f157\"; }\n\n.fa-yin-yang::before {\n  content: \"\\f6ad\"; }\n\n.fa-z::before {\n  content: \"\\5a\"; }\n\n.sr-only,\n.fa-sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  white-space: nowrap;\n  border-width: 0; }\n\n.sr-only-focusable:not(:focus),\n.fa-sr-only-focusable:not(:focus) {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  white-space: nowrap;\n  border-width: 0; }\n"
  }
]