├── log └── .keep ├── storage └── .keep ├── tmp └── .keep ├── vendor └── .keep ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── public ├── favicon.ico ├── apple-touch-icon.png ├── apple-touch-icon-precomposed.png ├── robots.txt ├── 500.html ├── 422.html └── 404.html ├── test ├── helpers │ └── .keep ├── mailers │ └── .keep ├── models │ └── .keep ├── system │ └── .keep ├── controllers │ ├── .keep │ └── home_page_controller_test.rb ├── fixtures │ ├── .keep │ └── files │ │ └── .keep ├── integration │ └── .keep ├── application_system_test_case.rb ├── channels │ └── application_cable │ │ └── connection_test.rb └── test_helper.rb ├── .node-version ├── .ruby-version ├── app ├── assets │ ├── builds │ │ ├── .keep │ │ └── application.css │ ├── images │ │ └── .keep │ ├── config │ │ └── manifest.js │ └── stylesheets │ │ ├── application.tailwind.css │ │ └── application.css ├── models │ ├── concerns │ │ └── .keep │ ├── application_record.rb │ └── user.rb ├── controllers │ ├── concerns │ │ └── .keep │ ├── home_page_controller.rb │ └── application_controller.rb ├── views │ ├── layouts │ │ ├── mailer.text.erb │ │ ├── _footer.html.erb │ │ ├── mailer.html.erb │ │ ├── _navigation.html.erb │ │ └── application.html.erb │ ├── rapidfire │ │ ├── attempts │ │ │ ├── show.html.erb │ │ │ ├── edit.html.erb │ │ │ ├── _answer_wrapper.html.erb │ │ │ ├── new.html.erb │ │ │ └── _form.html.erb │ │ ├── surveys │ │ │ ├── edit.html.erb │ │ │ ├── new.html.erb │ │ │ ├── _survey.html.erb │ │ │ ├── index.html.erb │ │ │ ├── _form.html.erb │ │ │ └── results.html.erb │ │ ├── answers │ │ │ ├── _errors.html.erb │ │ │ ├── _date.html.erb │ │ │ ├── _numeric.html.erb │ │ │ ├── _long.html.erb │ │ │ ├── _file.html.erb │ │ │ ├── _multifile.html.erb │ │ │ ├── _select.html.erb │ │ │ ├── _short.html.erb │ │ │ ├── _checkbox.html.erb │ │ │ └── _radio.html.erb │ │ └── questions │ │ │ ├── new.html.erb │ │ │ ├── index.html.erb │ │ │ ├── _question.html.erb │ │ │ ├── edit.html.erb │ │ │ └── _form.html.erb │ ├── home_page │ │ └── index.html.erb │ └── devise │ │ ├── mailer │ │ ├── password_change.html.erb │ │ ├── confirmation_instructions.html.erb │ │ ├── unlock_instructions.html.erb │ │ ├── email_changed.html.erb │ │ └── reset_password_instructions.html.erb │ │ ├── unlocks │ │ └── new.html.erb │ │ ├── passwords │ │ ├── new.html.erb │ │ └── edit.html.erb │ │ ├── shared │ │ ├── _error_messages.html.erb │ │ └── _links.html.erb │ │ ├── confirmations │ │ └── new.html.erb │ │ ├── sessions │ │ └── new.html.erb │ │ └── registrations │ │ ├── edit.html.erb │ │ └── new.html.erb ├── helpers │ ├── home_page_helper.rb │ └── application_helper.rb ├── channels │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb ├── javascript │ ├── application.js │ ├── controllers │ │ ├── hello_controller.js │ │ ├── application.js │ │ └── index.js │ ├── channels │ │ ├── index.js │ │ └── consumer.js │ ├── packs │ │ └── application.js │ └── src │ │ └── layout.scss ├── mailers │ └── application_mailer.rb └── jobs │ └── application_job.rb ├── .browserslistrc ├── bin ├── rake ├── rails ├── dev ├── docker-entrypoint ├── yarn ├── webpack ├── webpack-dev-server ├── spring ├── setup └── bundle ├── Procfile.dev ├── config ├── webpack │ ├── environment.js │ ├── test.js │ ├── production.js │ └── development.js ├── dockerfile.yml ├── spring.rb ├── routes.rb ├── environment.rb ├── initializers │ ├── mime_types.rb │ ├── application_controller_renderer.rb │ ├── cookies_serializer.rb │ ├── backtrace_silencers.rb │ ├── filter_parameter_logging.rb │ ├── permissions_policy.rb │ ├── assets.rb │ ├── wrap_parameters.rb │ ├── inflections.rb │ ├── content_security_policy.rb │ └── devise.rb ├── boot.rb ├── cable.yml ├── credentials.yml.enc ├── application.rb ├── locales │ ├── en.yml │ └── devise.en.yml ├── storage.yml ├── puma.rb ├── webpacker.yml ├── environments │ ├── test.rb │ ├── development.rb │ └── production.rb └── database.yml ├── db ├── migrate │ ├── 20190901102811_add_admin_to_users.rb │ ├── 20190901101611_add_after_survey_content_to_survey.rapidfire.rb │ ├── 20190831191544_devise_create_users.rb │ ├── 20190901101610_create_rapidfire_tables.rapidfire.rb │ └── 20230402174122_create_active_storage_tables.active_storage.rb ├── seeds.rb └── schema.rb ├── config.ru ├── tailwind.config.js ├── Rakefile ├── postcss.config.js ├── README.md ├── package.json ├── Gemfile ├── .dockerignore ├── fly.toml ├── .gitignore ├── babel.config.js ├── Dockerfile ├── Gemfile.lock └── yarn.lock /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /storage/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tmp/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/system/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 18.12.1 -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.2.2 2 | -------------------------------------------------------------------------------- /app/assets/builds/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/files/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /app/helpers/home_page_helper.rb: -------------------------------------------------------------------------------- 1 | module HomePageHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_tree ../builds 3 | -------------------------------------------------------------------------------- /app/views/rapidfire/attempts/show.html.erb: -------------------------------------------------------------------------------- 1 | <%= @survey.after_survey_content.html_safe %> -------------------------------------------------------------------------------- /app/views/rapidfire/surveys/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render partial: 'form', locals: {survey: @survey} %> 2 | -------------------------------------------------------------------------------- /app/views/rapidfire/attempts/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render partial: 'form', locals: { submit_text: 'Update' } %> 2 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | primary_abstract_class 3 | end 4 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /Procfile.dev: -------------------------------------------------------------------------------- 1 | web: unset PORT && bin/rails server 2 | js: npm run build -- --watch 3 | css: npm run build:css -- --watch 4 | -------------------------------------------------------------------------------- /config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | 3 | module.exports = environment 4 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /app/controllers/home_page_controller.rb: -------------------------------------------------------------------------------- 1 | class HomePageController < ApplicationController 2 | def index 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/views/layouts/_footer.html.erb: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /config/dockerfile.yml: -------------------------------------------------------------------------------- 1 | # generated by dockerfile-rails 2 | 3 | --- 4 | options: 5 | label: 6 | fly_launch_runtime: rails 7 | -------------------------------------------------------------------------------- /app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/javascript/application.js: -------------------------------------------------------------------------------- 1 | // Entry point for the build script in your package.json 2 | import "@hotwired/turbo-rails" 3 | import "./controllers" 4 | -------------------------------------------------------------------------------- /app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: "from@example.com" 3 | layout "mailer" 4 | end 5 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | devise_for :users 3 | mount Rapidfire::Engine => "/rapidfire" 4 | root 'home_page#index' 5 | end 6 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /app/views/home_page/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 | Welcome to rapidfire. Try rapidfire surveys <%= link_to "here", rapidfire_path %> 3 |
4 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | def can_administer? 3 | current_user.try(:admin?) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/devise/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

We're contacting you to notify you that your password has been changed.

4 | -------------------------------------------------------------------------------- /db/migrate/20190901102811_add_admin_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddAdminToUsers < ActiveRecord::Migration[6.0] 2 | def change 3 | add_column :users, :admin, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /bin/dev: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | if ! gem list foreman -i --silent; then 4 | echo "Installing foreman..." 5 | gem install foreman 6 | fi 7 | 8 | exec foreman start -f Procfile.dev "$@" 9 | -------------------------------------------------------------------------------- /config/webpack/test.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /app/views/rapidfire/attempts/_answer_wrapper.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= render partial: "rapidfire/answers/#{partial}", locals: { f: f, answer: answer } -%> 3 |
4 | -------------------------------------------------------------------------------- /config/webpack/production.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'production' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/webpack/development.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = process.env.NODE_ENV || 'development' 2 | 3 | const environment = require('./environment') 4 | 5 | module.exports = environment.toWebpackConfig() 6 | -------------------------------------------------------------------------------- /test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 4 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400] 5 | end 6 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: [ 3 | './app/views/**/*.html.erb', 4 | './app/helpers/**/*.rb', 5 | './app/assets/stylesheets/**/*.css', 6 | './app/javascript/**/*.js' 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /bin/docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # If running the rails server then create or migrate existing database 4 | if [ "${*}" == "./bin/rails server" ]; then 5 | ./bin/rails db:prepare 6 | fi 7 | 8 | exec "${@}" 9 | -------------------------------------------------------------------------------- /app/javascript/controllers/hello_controller.js: -------------------------------------------------------------------------------- 1 | import { Controller } from "@hotwired/stimulus" 2 | 3 | export default class extends Controller { 4 | connect() { 5 | this.element.textContent = "Hello World!" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @email %>!

2 | 3 |

You can confirm your account email through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

6 | -------------------------------------------------------------------------------- /test/controllers/home_page_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class HomePageControllerTest < ActionDispatch::IntegrationTest 4 | test "should get index" do 5 | get home_page_index_url 6 | assert_response :success 7 | end 8 | 9 | end 10 | -------------------------------------------------------------------------------- /config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: redis 3 | url: redis://localhost:6379/1 4 | 5 | test: 6 | adapter: test 7 | 8 | production: 9 | adapter: redis 10 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 11 | channel_prefix: rapidfire_app_production 12 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('postcss-flexbugs-fixes'), 5 | require('postcss-preset-env')({ 6 | autoprefixer: { 7 | flexbox: 'no-2009' 8 | }, 9 | stage: 3 10 | }) 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /app/javascript/controllers/application.js: -------------------------------------------------------------------------------- 1 | import { Application } from "@hotwired/stimulus" 2 | 3 | const application = Application.start() 4 | 5 | // Configure Stimulus development experience 6 | application.debug = false 7 | window.Stimulus = application 8 | 9 | export { application } 10 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ApplicationRecord 2 | # Include default devise modules. Others available are: 3 | # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 4 | devise :database_authenticatable, :registerable, 5 | :recoverable, :rememberable, :validatable 6 | end 7 | -------------------------------------------------------------------------------- /app/views/rapidfire/surveys/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Add a survey

3 | 4 | <%= link_to "Back to surveys", surveys_path %> 5 |
6 | 7 |
8 | 9 | <%= render partial: 'form', locals: { survey: @survey } %> 10 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_errors.html.erb: -------------------------------------------------------------------------------- 1 | <%- if answer.errors.any? %> 2 |
3 | 8 |
9 | <% end %> 10 | -------------------------------------------------------------------------------- /app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_date.html.erb: -------------------------------------------------------------------------------- 1 | <%= render partial: "rapidfire/answers/errors", locals: {answer: answer} %> 2 |
3 | <%= f.label :answer_text, answer.question.question_text, class: "title is-6" %> 4 | <%= f.text_field :answer_text, placeholder: answer.question.placeholder, class: "input" %> 5 |
6 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_numeric.html.erb: -------------------------------------------------------------------------------- 1 | <%= render partial: "rapidfire/answers/errors", locals: {answer: answer} %> 2 |
3 | <%= f.label :answer_text, answer.question.question_text, class: "title is-6" %> 4 | <%= f.text_field :answer_text, placeholder: answer.question.placeholder, class: "input" %> 5 |
6 | -------------------------------------------------------------------------------- /app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /test/channels/application_cable/connection_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase 4 | # test "connects with cookies" do 5 | # cookies.signed[:user_id] = 42 6 | # 7 | # connect 8 | # 9 | # assert_equal connection.user_id, "42" 10 | # end 11 | end 12 | -------------------------------------------------------------------------------- /bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/views/devise/mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @email %>!

2 | 3 | <% if @resource.try(:unconfirmed_email?) %> 4 |

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

5 | <% else %> 6 |

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

7 | <% end %> 8 | -------------------------------------------------------------------------------- /app/javascript/controllers/index.js: -------------------------------------------------------------------------------- 1 | // This file is auto-generated by ./bin/rails stimulus:manifest:update 2 | // Run that command whenever you add a new controller or create them with 3 | // ./bin/rails generate stimulus controllerName 4 | 5 | import { application } from "./application" 6 | 7 | import HelloController from "./hello_controller" 8 | application.register("hello", HelloController) 9 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # movies = Movie.create([{ name: "Star Wars" }, { name: "Lord of the Rings" }]) 7 | # Character.create(name: "Luke", movie: movies.first) 8 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_long.html.erb: -------------------------------------------------------------------------------- 1 | <%= render partial: "rapidfire/answers/errors", locals: {answer: answer} %> 2 |
3 | <%= f.label :answer_text, answer.question.question_text, class: "title is-6" %> 4 | <%= f.text_area :answer_text, value: answer.answer_text || answer.question.default_text, :rows => 5, placeholder: answer.question.placeholder, class: "textarea" %> 5 |
6 | -------------------------------------------------------------------------------- /app/views/rapidfire/questions/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Add a question

3 | 4 | <%= link_to "Back to questions", survey_questions_path(@survey) %> 5 |
6 | 7 |
8 | 9 | <%= render partial: 'form', locals: { form: @question_form, url: survey_questions_path(@survey), method: :post, submit_text: 'Create Question' } %> 10 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_file.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= f.label :answer_text, answer.question.question_text, class: "block text-sm font-medium leading-6 text-gray-900" %> 3 | <%= f.file_field :file, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 4 | <%= render partial: "rapidfire/answers/errors", locals: {answer: answer} %> 5 |
6 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_multifile.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= f.label :answer_text, answer.question.question_text, class: "block text-sm font-medium leading-6 text-gray-900" %> 3 | <%= f.file_field :files, multiple: true, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 4 | <%= render partial: "rapidfire/answers/errors", locals: {answer: answer} %> 5 |
6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rapidfire App 2 | 3 | Welcome to Rapidfire! This is a simple implementation of the [rapidfire](https://github.com/code-mancers/rapidfire) gem. You can deploy this app to Fly as well. The demo app is hosted on Fly [https://rapidfire.fly.dev](https://rapidfire.fly.dev). 4 | 5 | This app uses Rails v7 with Tailwind. Mobile first 6 | 7 | #### Development 8 | 9 | Just follow Rails conventions and use `foreman start -f Procfile.dev` 10 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] ||= "test" 2 | require_relative "../config/environment" 3 | require "rails/test_help" 4 | 5 | class ActiveSupport::TestCase 6 | # Run tests in parallel with specified workers 7 | parallelize(workers: :number_of_processors) 8 | 9 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 10 | fixtures :all 11 | 12 | # Add more helper methods to be used by all tests here... 13 | end 14 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure parameters to be filtered from the log file. Use this to limit dissemination of 4 | # sensitive information. See the ActiveSupport::ParameterFilter documentation for supported 5 | # notations and behaviors. 6 | Rails.application.config.filter_parameters += [ 7 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 8 | ] 9 | -------------------------------------------------------------------------------- /config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Define an application-wide HTTP permissions policy. For further 2 | # information see https://developers.google.com/web/updates/2018/06/feature-policy 3 | # 4 | # Rails.application.config.permissions_policy do |f| 5 | # f.camera :none 6 | # f.gyroscope :none 7 | # f.microphone :none 8 | # f.usb :none 9 | # f.fullscreen :self 10 | # f.payment :self, "https://secure.example.com" 11 | # end 12 | -------------------------------------------------------------------------------- /app/views/devise/mailer/reset_password_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Someone has requested a link to change your password. You can do this through the link below.

4 | 5 |

<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>

6 | 7 |

If you didn't request this, please ignore this email.

8 |

Your password won't change until you access the link above and create a new one.

9 | -------------------------------------------------------------------------------- /app/views/rapidfire/questions/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= @questions.count %> Question(s)

3 | <%= link_to "New Question", new_survey_question_path(@survey) %> 4 |
5 | 6 |
7 | 8 | <% if @questions.count == 0 %> 9 |
Please add a few questions.
10 | <% else %> 11 | <%= render partial: "question", collection: @questions %> 12 | <% end %> 13 | -------------------------------------------------------------------------------- /config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | oE9r77X9o2zluQpK39HeND3W988WFqkB9z4T4zfvhFUQoRsZg4eOKomOZdwSw7ru+3FRXUFhKAAL/4M5BgY7AU1cs/8wcjnSBw5s4Pk8FZBHHVq920LC0miUSZZx/uc3U6CobswFYPa9iA/zQYoHKbTbXqnmFec7FMniJak+PYmfvlRS9DzaORM0iITaHDPG2D3mx+Iu1+XONGT3HJt3eU08XZjBH5/Us/UtDR600a+5+ACVMmDQ9Odp1r28IlwhOcO9iYSwaIMR9cVcVTYXCv6BJSVFbkyMtIM/95izvQQsaT2LK0kJHGkM9HNQHTNtHtRj6IWMzwnyD2Ly3aRlB7jaysmjstgOn1k1+LD56qyupxpQzx9a3gcgGGloqQmnGzyfnb1gr1mKZnpB5SRl07alEYayst3tXb7q--RItwDIR793v/BaCc--i4dDzTQum6F1oSnIQ4RcOw== -------------------------------------------------------------------------------- /app/views/layouts/_navigation.html.erb: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_select.html.erb: -------------------------------------------------------------------------------- 1 | <%= render partial: "rapidfire/answers/errors", locals: {answer: answer} %> 2 | <% placeholder = answer.question.placeholder.present? ? answer.question.placeholder : "Select your answer" %> 3 |
4 | <%= f.label :answer_text, answer.question.question_text, class: "title is-6" %>
5 | <%= f.select :answer_text, answer.question.options, {include_blank: placeholder}, class: "button is-notification full-width" %> 6 |
7 | -------------------------------------------------------------------------------- /db/migrate/20190901101611_add_after_survey_content_to_survey.rapidfire.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rapidfire (originally 20170701191411) 2 | if Rails::VERSION::MAJOR >= 5 3 | version = [Rails::VERSION::MAJOR, Rails::VERSION::MINOR].join('.').to_f 4 | base = ActiveRecord::Migration[version] 5 | else 6 | base = ActiveRecord::Migration 7 | end 8 | 9 | class AddAfterSurveyContentToSurvey < base 10 | def change 11 | add_column :rapidfire_surveys, :after_survey_content, :text 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_short.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= f.label :answer_text, answer.question.question_text, class: "block text-sm font-medium leading-6 text-gray-900" %> 3 | <%= f.text_field :answer_text, value: answer.answer_text || answer.question.default_text, placeholder: answer.question.placeholder, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 4 | <%= render partial: "rapidfire/answers/errors", locals: {answer: answer} %> 5 |
6 | -------------------------------------------------------------------------------- /bin/webpack: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "rubygems" 11 | require "bundler/setup" 12 | 13 | require "webpacker" 14 | require "webpacker/webpack_runner" 15 | 16 | APP_ROOT = File.expand_path("..", __dir__) 17 | Dir.chdir(APP_ROOT) do 18 | Webpacker::WebpackRunner.run(ARGV) 19 | end 20 | -------------------------------------------------------------------------------- /bin/webpack-dev-server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "rubygems" 11 | require "bundler/setup" 12 | 13 | require "webpacker" 14 | require "webpacker/dev_server_runner" 15 | 16 | APP_ROOT = File.expand_path("..", __dir__) 17 | Dir.chdir(APP_ROOT) do 18 | Webpacker::DevServerRunner.run(ARGV) 19 | end 20 | -------------------------------------------------------------------------------- /app/views/rapidfire/attempts/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Taking Survey - <%=@survey.name%>

3 | 4 | <% if can_administer? %> 5 | <%= link_to "Back to surveys", surveys_path %> 6 | <% end %> 7 |
8 | 9 |
10 | 11 | <% if @survey.questions.count == 0 %> 12 |
13 | This Survey does not have any questions yet! 14 |
15 | <% else %> 16 | <%= render partial: 'form', locals: { submit_text: "Submit" } %> 17 | <% end %> 18 | -------------------------------------------------------------------------------- /app/views/rapidfire/questions/_question.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= question.question_text %>

3 |

4 | <%= question.type.split("::").last %> question 5 |

6 | 7 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = "1.0" 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in the app/assets 11 | # folder are already added. 12 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 13 | -------------------------------------------------------------------------------- /app/views/devise/unlocks/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend unlock instructions

2 | 3 | <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> 4 | <%= render "devise/shared/error_messages", resource: resource %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 9 |
10 | 11 |
12 | <%= f.submit "Resend unlock instructions" %> 13 |
14 | <% end %> 15 | 16 | <%= render "devise/shared/links" %> 17 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads Spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require 'rubygems' 8 | require 'bundler' 9 | 10 | lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) 11 | spring = lockfile.specs.detect { |spec| spec.name == 'spring' } 12 | if spring 13 | Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path 14 | gem 'spring', spring.version 15 | require 'spring/binstub' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/devise/passwords/new.html.erb: -------------------------------------------------------------------------------- 1 |

Forgot your password?

2 | 3 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %> 4 | <%= render "devise/shared/error_messages", resource: resource %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 9 |
10 | 11 |
12 | <%= f.submit "Send me reset password instructions" %> 13 |
14 | <% end %> 15 | 16 | <%= render "devise/shared/links" %> 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "private": "true", 4 | "scripts": { 5 | "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets", 6 | "build:css": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify" 7 | }, 8 | "dependencies": { 9 | "@hotwired/stimulus": "^3.2.1", 10 | "@hotwired/turbo-rails": "^7.3.0", 11 | "autoprefixer": "^10.4.14", 12 | "esbuild": "^0.17.15", 13 | "postcss": "^8.4.21", 14 | "tailwindcss": "^3.3.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | git_source(:github) { |repo| "https://github.com/#{repo}.git" } 3 | 4 | ruby "3.2.2" 5 | 6 | gem "rails" 7 | gem "sprockets-rails" 8 | gem "pg" 9 | gem "puma" 10 | gem "jsbundling-rails" 11 | gem "turbo-rails" 12 | gem "stimulus-rails" 13 | gem "cssbundling-rails" 14 | gem "jbuilder" 15 | 16 | gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] 17 | gem "bootsnap", require: false 18 | 19 | # App specific 20 | gem "rapidfire" 21 | gem "devise" 22 | gem "kaminari" 23 | 24 | group :development do 25 | gem "dockerfile-rails", ">= 1.2" 26 | end 27 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_checkbox.html.erb: -------------------------------------------------------------------------------- 1 | <%= render partial: "rapidfire/answers/errors", locals: {answer: answer} %> 2 | 3 |
4 | <%= f.label :answer_text, answer.question.question_text, class: "title is-6" %> 5 |
6 | <%= f.fields_for :answer_text do |af| %> 7 | <%- answer.question.options.each_with_index do |option, index| %> 8 | <%= af.label index, class: "checkbox full-width" do %> 9 | <%= af.check_box index, { checked: checkbox_checked?(answer, option) }, option %> 10 | <%= option %> 11 | <% end %> 12 | <% end %> 13 | <% end %> 14 |
15 | -------------------------------------------------------------------------------- /app/views/devise/shared/_error_messages.html.erb: -------------------------------------------------------------------------------- 1 | <% if resource.errors.any? %> 2 |
3 |

4 | <%= I18n.t("errors.messages.not_saved", 5 | count: resource.errors.count, 6 | resource: resource.class.model_name.human.downcase) 7 | %> 8 |

9 |
10 | 15 |
16 |
17 | <% end %> 18 | -------------------------------------------------------------------------------- /app/views/rapidfire/surveys/_survey.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= survey.name %>

3 |

4 | <%= survey.introduction %> 5 |

6 | 7 | 15 |
16 |
17 | -------------------------------------------------------------------------------- /app/views/rapidfire/questions/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 | Edit Question 6 |

7 |
8 |
9 |
10 | <%= link_to "Back to Questions", survey_questions_path(@survey), class: "button" %> 11 |
12 |
13 |
14 | <%= render partial: 'form', locals: { form: @question_form, url: survey_question_path(@survey, @question), method: :put, submit_text: 'Update Question' } %> 15 |
16 | -------------------------------------------------------------------------------- /app/views/rapidfire/answers/_radio.html.erb: -------------------------------------------------------------------------------- 1 | <%= render partial: "rapidfire/answers/errors", locals: {answer: answer} %> 2 | 3 |
4 | <%= f.label :answer_text, answer.question.question_text, class: "title is-6" %> 5 |
6 | <%- answer.question.options.each_with_index do |option, index| %> 7 | 8 | <%= f.label "answer_text_#{index}", class: "radio" do %> 9 | <%= f.radio_button :answer_text, option, id: "#{f.object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")}_answer_text_#{index}" %> 10 | <%= option %> 11 | <% end %> 12 | 13 |
14 | <% end %> 15 |
16 | -------------------------------------------------------------------------------- /app/views/devise/confirmations/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend confirmation instructions

2 | 3 | <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> 4 | <%= render "devise/shared/error_messages", resource: resource %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %> 9 |
10 | 11 |
12 | <%= f.submit "Resend confirmation instructions" %> 13 |
14 | <% end %> 15 | 16 | <%= render "devise/shared/links" %> 17 | -------------------------------------------------------------------------------- /app/views/rapidfire/attempts/_form.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @survey.introduction -%>

2 | 3 | <%= form_for([@survey, @attempt_builder], html: { class: "space-y-3" }, data: { turbo: false } ) do |f| %> 4 | <%- @attempt_builder.answers.each do |answer| %> 5 | <%= f.fields_for("#{answer.question.id}", answer) do |answer_form| %> 6 | <%= render_answer_form_helper(answer, answer_form) %> 7 | <% end %> 8 | <% end %> 9 |
10 | <%= f.submit submit_text, class: "cursor-pointer rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" %> 11 |
12 | <% end %> 13 | -------------------------------------------------------------------------------- /app/views/rapidfire/surveys/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

<%= @surveys.count %> Survey(s)

3 | 4 | <% if can_administer? %> 5 | <%= link_to "New Survey", new_survey_path %> 6 | <% end %> 7 |
8 | 9 |
10 | 11 | <% if @surveys.count == 0 %> 12 | <% if can_administer? %> 13 |
It feels a bit lonely here. Add a new survey to continue.
14 | <% else %> 15 |
All clear here! No suveys available yet.
16 | <% end %> 17 | <% else %> 18 | <%= render partial: "survey", collection: @surveys.order(created_at: :desc) %> 19 | <%= paginate @surveys %> 20 | <% end %> 21 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's 6 | * vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS 10 | * files in this directory. Styles in this file should be added after the last require_* statement. 11 | * It is generally better to create a new file per style scope. 12 | * 13 | *= require_self 14 | */ 15 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Rapidfire App 5 | 6 | <%= csrf_meta_tags %> 7 | <%= csp_meta_tag %> 8 | 9 | <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> 10 | <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %> 11 | 12 | 13 | 14 | <%= render 'layouts/navigation'%> 15 | 16 | <% if alert %> 17 | <%= alert %> 18 | <% end %> 19 | <% if notice %> 20 | <%= notice %> 21 | <% end %> 22 | 23 |
24 | <%= yield %> 25 |
26 | 27 | <%= render 'layouts/footer'%> 28 | 29 | 30 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails/all" 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module RapidfireApp 10 | class Application < Rails::Application 11 | # Initialize configuration defaults for originally generated Rails version. 12 | config.load_defaults 7.0 13 | 14 | # Configuration for the application, engines, and railties goes here. 15 | # 16 | # These settings can be overridden in specific environments using the files 17 | # in config/environments, which are processed later. 18 | # 19 | # config.time_zone = "Central Time (US & Canada)" 20 | # config.eager_load_paths << Rails.root.join("extras") 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/javascript/packs/application.js: -------------------------------------------------------------------------------- 1 | // This file is automatically compiled by Webpack, along with any other files 2 | // present in this directory. You're encouraged to place your actual application logic in 3 | // a relevant structure within app/javascript and only use these pack files to reference 4 | // that code so it'll be compiled. 5 | 6 | require("@rails/ujs").start() 7 | require("turbolinks").start() 8 | require("channels") 9 | import "../src/layout.scss" 10 | 11 | // Uncomment to copy all static images under ../images to the output folder and reference 12 | // them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) 13 | // or the `imagePath` JavaScript helper below. 14 | // 15 | // const images = require.context('../images', true) 16 | // const imagePath = (name) => images(name, true) 17 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. 2 | 3 | # Ignore git directory. 4 | /.git/ 5 | 6 | # Ignore bundler config. 7 | /.bundle 8 | 9 | # Ignore all default key files. 10 | /config/master.key 11 | /config/credentials/*.key 12 | 13 | # Ignore all environment files. 14 | /.env* 15 | !/.env.example 16 | 17 | # Ignore all logfiles and tempfiles. 18 | /log/* 19 | /tmp/* 20 | !/log/.keep 21 | !/tmp/.keep 22 | 23 | # Ignore pidfiles, but keep the directory. 24 | /tmp/pids/* 25 | !/tmp/pids/ 26 | !/tmp/pids/.keep 27 | 28 | # Ignore storage (uploaded files in development and any SQLite databases). 29 | /storage/* 30 | !/storage/.keep 31 | /tmp/storage/* 32 | !/tmp/storage/ 33 | !/tmp/storage/.keep 34 | 35 | # Ignore assets. 36 | /node_modules/ 37 | /app/assets/builds/* 38 | !/app/assets/builds/.keep 39 | /public/assets 40 | -------------------------------------------------------------------------------- /fly.toml: -------------------------------------------------------------------------------- 1 | # fly.toml file generated for rapidfire on 2023-04-03T00:31:10+05:30 2 | 3 | app = "rapidfire" 4 | kill_signal = "SIGINT" 5 | kill_timeout = 5 6 | primary_region = "bos" 7 | processes = [] 8 | 9 | [env] 10 | 11 | [experimental] 12 | auto_rollback = true 13 | 14 | [[services]] 15 | http_checks = [] 16 | internal_port = 3000 17 | processes = ["app"] 18 | protocol = "tcp" 19 | script_checks = [] 20 | [services.concurrency] 21 | hard_limit = 25 22 | soft_limit = 20 23 | type = "connections" 24 | 25 | [[services.ports]] 26 | force_https = true 27 | handlers = ["http"] 28 | port = 80 29 | 30 | [[services.ports]] 31 | handlers = ["tls", "http"] 32 | port = 443 33 | 34 | [[services.tcp_checks]] 35 | grace_period = "1s" 36 | interval = "15s" 37 | restart_limit = 0 38 | timeout = "2s" 39 | 40 | [[statics]] 41 | guest_path = "/rails/public" 42 | url_prefix = "/" 43 | -------------------------------------------------------------------------------- /app/views/devise/passwords/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Change your password

2 | 3 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> 4 | <%= render "devise/shared/error_messages", resource: resource %> 5 | <%= f.hidden_field :reset_password_token %> 6 | 7 |
8 | <%= f.label :password, "New password" %>
9 | <% if @minimum_password_length %> 10 | (<%= @minimum_password_length %> characters minimum)
11 | <% end %> 12 | <%= f.password_field :password, autofocus: true, autocomplete: "new-password" %> 13 |
14 | 15 |
16 | <%= f.label :password_confirmation, "Confirm new password" %>
17 | <%= f.password_field :password_confirmation, autocomplete: "new-password" %> 18 |
19 | 20 |
21 | <%= f.submit "Change my password" %> 22 |
23 | <% end %> 24 | 25 | <%= render "devise/shared/links" %> 26 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t "hello" 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t("hello") %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # "true": "foo" 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at https://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | 4 | # path to your application root. 5 | APP_ROOT = File.expand_path("..", __dir__) 6 | 7 | def system!(*args) 8 | system(*args) || abort("\n== Command #{args} failed ==") 9 | end 10 | 11 | FileUtils.chdir APP_ROOT do 12 | # This script is a way to set up or update your development environment automatically. 13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome. 14 | # Add necessary setup steps to this file. 15 | 16 | puts "== Installing dependencies ==" 17 | system! "gem install bundler --conservative" 18 | system("bundle check") || system!("bundle install") 19 | 20 | # puts "\n== Copying sample files ==" 21 | # unless File.exist?("config/database.yml") 22 | # FileUtils.cp "config/database.yml.sample", "config/database.yml" 23 | # end 24 | 25 | puts "\n== Preparing database ==" 26 | system! "bin/rails db:prepare" 27 | 28 | puts "\n== Removing old logs and tempfiles ==" 29 | system! "bin/rails log:clear tmp:clear" 30 | 31 | puts "\n== Restarting application server ==" 32 | system! "bin/rails restart" 33 | end 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | # See http://help.github.com/ignore-files/ for more about ignoring files. 9 | 10 | /.bundle 11 | 12 | # Ignore the default SQLite database. 13 | /db/*.sqlite3 14 | /db/*.sqlite3-journal 15 | 16 | # Ignore all logfiles and tempfiles. 17 | /log/* 18 | /tmp/* 19 | !/log/.keep 20 | !/tmp/.keep 21 | 22 | # Ignore uploaded files in development. 23 | /storage/* 24 | !/storage/.keep 25 | 26 | /public/assets 27 | .byebug_history 28 | 29 | # Ignore master key for decrypting credentials and more. 30 | /config/master.key 31 | 32 | /public/packs 33 | /public/packs-test 34 | /node_modules 35 | /yarn-error.log 36 | yarn-debug.log* 37 | .yarn-integrity 38 | /postgres-local-data 39 | 40 | # Ignore all logfiles and tempfiles. 41 | /config/database.yml 42 | /public/assets/ 43 | 44 | /app/assets/builds/* 45 | !/app/assets/builds/.keep -------------------------------------------------------------------------------- /config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy. 4 | # See the Securing Rails Applications Guide for more information: 5 | # https://guides.rubyonrails.org/security.html#content-security-policy-header 6 | 7 | # Rails.application.configure do 8 | # config.content_security_policy do |policy| 9 | # policy.default_src :self, :https 10 | # policy.font_src :self, :https, :data 11 | # policy.img_src :self, :https, :data 12 | # policy.object_src :none 13 | # policy.script_src :self, :https 14 | # policy.style_src :self, :https 15 | # # Specify URI for violation reports 16 | # # policy.report_uri "/csp-violation-report-endpoint" 17 | # end 18 | # 19 | # # Generate session nonces for permitted importmap and inline scripts 20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } 21 | # config.content_security_policy_nonce_directives = %w(script-src) 22 | # 23 | # # Report violations without enforcing the policy. 24 | # # config.content_security_policy_report_only = true 25 | # end 26 | -------------------------------------------------------------------------------- /app/views/devise/shared/_links.html.erb: -------------------------------------------------------------------------------- 1 | <%- if controller_name != 'sessions' %> 2 | <%= link_to "Log in", new_session_path(resource_name) %>
3 | <% end %> 4 | 5 | <%- if devise_mapping.registerable? && controller_name != 'registrations' %> 6 | <%= link_to "Sign up", new_registration_path(resource_name) %>
7 | <% end %> 8 | 9 | <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> 10 | <%= link_to "Forgot your password?", new_password_path(resource_name) %>
11 | <% end %> 12 | 13 | <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> 14 | <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
15 | <% end %> 16 | 17 | <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> 18 | <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
19 | <% end %> 20 | 21 | <%- if devise_mapping.omniauthable? %> 22 | <%- resource_class.omniauth_providers.each do |provider| %> 23 | <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %>
24 | <% end %> 25 | <% end %> 26 | -------------------------------------------------------------------------------- /config/storage.yml: -------------------------------------------------------------------------------- 1 | test: 2 | service: Disk 3 | root: <%= Rails.root.join("tmp/storage") %> 4 | 5 | local: 6 | service: Disk 7 | root: <%= Rails.root.join("storage") %> 8 | 9 | # Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) 10 | # amazon: 11 | # service: S3 12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> 13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> 14 | # region: us-east-1 15 | # bucket: your_own_bucket-<%= Rails.env %> 16 | 17 | # Remember not to checkin your GCS keyfile to a repository 18 | # google: 19 | # service: GCS 20 | # project: your_project 21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> 22 | # bucket: your_own_bucket-<%= Rails.env %> 23 | 24 | # Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) 25 | # microsoft: 26 | # service: AzureStorage 27 | # storage_account_name: your_account_name 28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> 29 | # container: your_container_name-<%= Rails.env %> 30 | 31 | # mirror: 32 | # service: Mirror 33 | # primary: local 34 | # mirrors: [ amazon, google, microsoft ] 35 | -------------------------------------------------------------------------------- /app/views/rapidfire/surveys/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for survey, html: { class: "space-y-3" }, data: { turbo: false } do |f| %> 2 | <%- if survey.errors.any? %> 3 | 8 | <% end %> 9 | 10 |
11 | <%= f.label :name, class: "block text-sm font-medium leading-6 text-gray-900" %> 12 | <%= f.text_field :name, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 13 |
14 | 15 |
16 | <%= f.label :introduction, class: "block text-sm font-medium leading-6 text-gray-900" %> 17 | <%= f.text_area :introduction, rows: 5, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 18 |
19 | 20 |
21 | <%= f.label :after_survey_content, class: "block text-sm font-medium leading-6 text-gray-900" %> 22 | <%= f.text_area :after_survey_content, rows: 5, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 23 |
24 | 25 |
26 | <%= f.submit "Submit", class: "cursor-pointer rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" %> 27 |
28 | <% end %> 29 | -------------------------------------------------------------------------------- /app/views/devise/sessions/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Login

6 |
7 | 8 |
9 | <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> 10 |
11 | <%= f.label :email, class: "title is-6"%> 12 | <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "input", placeholder: "Email" %> 13 |
14 | 15 |
16 | <%= f.label :password, class: "title is-6"%> 17 | <%= f.password_field :password, autocomplete: "current-password", class: "input", placeholder: "Password" %> 18 |
19 | 20 | <% if devise_mapping.rememberable? %> 21 |
22 | <%= f.check_box :remember_me %> 23 | <%= f.label :remember_me %> 24 |
25 | <% end %> 26 | 27 |
28 |
29 | <%= link_to("Not yet registered?", new_user_registration_path) %> 30 |
31 | 34 |
35 | <% end %> 36 |
37 |
38 |
39 |
40 | 41 | -------------------------------------------------------------------------------- /db/migrate/20190831191544_devise_create_users.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class DeviseCreateUsers < ActiveRecord::Migration[6.0] 4 | def change 5 | create_table :users do |t| 6 | ## Database authenticatable 7 | t.string :email, null: false, default: "" 8 | t.string :encrypted_password, null: false, default: "" 9 | 10 | ## Recoverable 11 | t.string :reset_password_token 12 | t.datetime :reset_password_sent_at 13 | 14 | ## Rememberable 15 | t.datetime :remember_created_at 16 | 17 | ## Trackable 18 | # t.integer :sign_in_count, default: 0, null: false 19 | # t.datetime :current_sign_in_at 20 | # t.datetime :last_sign_in_at 21 | # t.inet :current_sign_in_ip 22 | # t.inet :last_sign_in_ip 23 | 24 | ## Confirmable 25 | # t.string :confirmation_token 26 | # t.datetime :confirmed_at 27 | # t.datetime :confirmation_sent_at 28 | # t.string :unconfirmed_email # Only if using reconfirmable 29 | 30 | ## Lockable 31 | # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts 32 | # t.string :unlock_token # Only if unlock strategy is :email or :both 33 | # t.datetime :locked_at 34 | 35 | 36 | t.timestamps null: false 37 | end 38 | 39 | add_index :users, :email, unique: true 40 | add_index :users, :reset_password_token, unique: true 41 | # add_index :users, :confirmation_token, unique: true 42 | # add_index :users, :unlock_token, unique: true 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /db/migrate/20190901101610_create_rapidfire_tables.rapidfire.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from rapidfire (originally 20130502170733) 2 | if Rails::VERSION::MAJOR >= 5 3 | version = [Rails::VERSION::MAJOR, Rails::VERSION::MINOR].join('.').to_f 4 | base = ActiveRecord::Migration[version] 5 | else 6 | base = ActiveRecord::Migration 7 | end 8 | 9 | class CreateRapidfireTables < base 10 | def change 11 | create_table :rapidfire_surveys do |t| 12 | t.string :name 13 | t.text :introduction 14 | t.timestamps 15 | end 16 | 17 | create_table :rapidfire_questions do |t| 18 | t.references :survey 19 | t.string :type 20 | t.string :question_text 21 | t.string :default_text 22 | t.string :placeholder 23 | t.integer :position 24 | t.text :answer_options 25 | t.text :validation_rules 26 | 27 | t.timestamps 28 | end 29 | add_index :rapidfire_questions, :survey_id if Rails::VERSION::MAJOR < 5 30 | 31 | create_table :rapidfire_attempts do |t| 32 | t.references :survey 33 | t.references :user, polymorphic: true 34 | 35 | t.timestamps 36 | end 37 | add_index :rapidfire_attempts, :survey_id if Rails::VERSION::MAJOR < 5 38 | add_index :rapidfire_attempts, [:user_id, :user_type] 39 | 40 | create_table :rapidfire_answers do |t| 41 | t.references :attempt 42 | t.references :question 43 | t.text :answer_text 44 | 45 | t.timestamps 46 | end 47 | if Rails::VERSION::MAJOR < 5 48 | add_index :rapidfire_answers, :attempt_id 49 | add_index :rapidfire_answers, :question_id 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /app/views/devise/registrations/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Edit <%= resource_name.to_s.humanize %>

2 | 3 | <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> 4 | <%= render "devise/shared/error_messages", resource: resource %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %> 9 |
10 | 11 | <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> 12 |
Currently waiting confirmation for: <%= resource.unconfirmed_email %>
13 | <% end %> 14 | 15 |
16 | <%= f.label :password %> (leave blank if you don't want to change it)
17 | <%= f.password_field :password, autocomplete: "new-password" %> 18 | <% if @minimum_password_length %> 19 |
20 | <%= @minimum_password_length %> characters minimum 21 | <% end %> 22 |
23 | 24 |
25 | <%= f.label :password_confirmation %>
26 | <%= f.password_field :password_confirmation, autocomplete: "new-password" %> 27 |
28 | 29 |
30 | <%= f.label :current_password %> (we need your current password to confirm your changes)
31 | <%= f.password_field :current_password, autocomplete: "current-password" %> 32 |
33 | 34 |
35 | <%= f.submit "Update" %> 36 |
37 | <% end %> 38 | 39 |

Cancel my account

40 | 41 |

Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %>

42 | 43 | <%= link_to "Back", :back %> 44 | -------------------------------------------------------------------------------- /app/views/devise/registrations/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Sign Up

6 |
7 | 8 |
9 | <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> 10 | <%= render "devise/shared/error_messages", resource: resource %> 11 | 12 |
13 | <%= f.label :email, class: "title is-6" %> 14 | <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "input", placeholder: "Email" %> 15 |
16 | 17 |
18 | <%= f.label :password, class: "title is-6"%> 19 | <% if @minimum_password_length %> 20 | (<%= @minimum_password_length %> characters minimum) 21 | <% end %>
22 | <%= f.password_field :password, autocomplete: "new-password", class: "input", placeholder: "Password" %> 23 |
24 | 25 |
26 | <%= f.label :password_confirmation, class: "title is-6" %> 27 | <%= f.password_field :password_confirmation, autocomplete: "new-password", class: "input", placeholder: "Password Confirmation" %> 28 |
29 | 30 |
31 |
32 | <%= link_to("Already registered?", user_session_path) %> 33 |
34 | 37 |
38 | <% end %> 39 |
40 |
41 |
42 |
43 | -------------------------------------------------------------------------------- /app/views/rapidfire/surveys/results.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 | Results 6 |

7 |
8 |
9 |
10 | <%= link_to "Back to Surveys", surveys_path, class: "button" %> 11 |
12 |
13 |
14 | 15 |
16 |

17 | Page under construction. Results will be available soon!! 18 |

19 |
20 |
21 |
22 | 23 | <%#

Results

%> 24 | 25 | <%# <%- @survey_results.each do |result| %1> %> 26 | <%#
%> 27 | <%#

<%= result.question.question_text %1>

%> 28 | <%#

%> 29 | <%# <%- if result.results.is_a?(Array) %1> %> 30 | <%#

    %> 31 | <%# <%- result.results.each do |answer| %1> %> 32 | <%#
  1. <%= answer %1>
  2. %> 33 | <%# <% end %1> %> 34 | <%#
%> 35 | <%# <% elsif result.results.is_a?(Hash) %1> %> 36 | <%# %> 37 | <%# %> 38 | <%# %> 39 | <%# %> 40 | <%# %> 41 | <%# %> 42 | <%# %> 43 | <%# %> 44 | <%# <%- result.results.each do |option, count| %1> %> 45 | <%# %> 46 | <%# %> 47 | <%# %> 48 | <%# %> 49 | <%# <% end %1> %> 50 | <%# %> 51 | <%#
OptionCount
<%= option %1><%= count %1>
%> 52 | <%# <% end %1> %> 53 | <%#
%> 54 | <%# <% end %1> %> 55 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 8 | min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } 9 | threads min_threads_count, max_threads_count 10 | 11 | # Specifies the `worker_timeout` threshold that Puma will use to wait before 12 | # terminating a worker in development environments. 13 | # 14 | worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" 15 | 16 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 17 | # 18 | port ENV.fetch("PORT") { 3000 } 19 | 20 | # Specifies the `environment` that Puma will run in. 21 | # 22 | environment ENV.fetch("RAILS_ENV") { "development" } 23 | 24 | # Specifies the `pidfile` that Puma will use. 25 | pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } 26 | 27 | # Specifies the number of `workers` to boot in clustered mode. 28 | # Workers are forked web server processes. If using threads and workers together 29 | # the concurrency of the application would be max `threads` * `workers`. 30 | # Workers do not work on JRuby or Windows (both of which do not support 31 | # processes). 32 | # 33 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 34 | 35 | # Use the `preload_app!` method when specifying a `workers` number. 36 | # This directive tells Puma to first boot the application and load code 37 | # before forking the application. This takes advantage of Copy On Write 38 | # process behavior so workers use less memory. 39 | # 40 | # preload_app! 41 | 42 | # Allow puma to be restarted by `bin/rails restart` command. 43 | plugin :tmp_restart 44 | -------------------------------------------------------------------------------- /app/javascript/src/layout.scss: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Ubuntu'); 2 | $family-primary:'Ubuntu', sans-serif; 3 | @import "~bulma"; 4 | body { 5 | display:flex; 6 | flex-direction:column; 7 | justify-content:space-between; 8 | height:100vh; 9 | } 10 | .header { 11 | background-color:#342E37; 12 | color:#fafafa; 13 | padding:1rem 1rem; 14 | } 15 | .section { 16 | display:flex; 17 | flex:1 0 auto; 18 | } 19 | .footer { 20 | background-color:#342E37; 21 | padding:2rem 1rem; 22 | color:#fafafa; 23 | text-align:center; 24 | } 25 | .is-ancestor { 26 | align-items:center; 27 | } 28 | 29 | .signup-button { 30 | padding-top:0.5em; 31 | } 32 | .logo { 33 | color:#fafafa; 34 | } 35 | .logo:hover { 36 | color:#fafafa 37 | } 38 | .heroku-button { 39 | background-color:#7056BF 40 | } 41 | .align-content-center { 42 | display:flex; 43 | align-items:center; 44 | justify-content:center; 45 | height:100%; 46 | } 47 | .full-height { 48 | height: 100%; 49 | } 50 | .height-fit-content { 51 | height:fit-content; 52 | } 53 | .margin-top-5 { 54 | margin-top: 5em; 55 | } 56 | .full-width { 57 | width: 100%; 58 | } 59 | .level-separator { 60 | margin-top: 2em; 61 | } 62 | .width-fix-content { 63 | width: fit-content; 64 | } 65 | .fixed-footer-item { 66 | max-width:fit-content; 67 | } 68 | @media screen and (min-width: 700px) { 69 | .level-separator { 70 | margin:3em; 71 | } 72 | .create-button-margin { 73 | margin-top: 3em; 74 | } 75 | } 76 | @media screen and (min-width: 1080px) { 77 | .fixed-footer-item { 78 | max-width: 200px; 79 | } 80 | } 81 | @media screen and (min-width: 500px) { 82 | .tile.is-parent { 83 | min-width:500px; 84 | padding:3em; 85 | } 86 | } 87 | @media screen and (max-width: 350px) { 88 | .no-padding-section { 89 | padding: 0em; 90 | } 91 | } 92 | @media screen and (min-width: 500px) { 93 | .tile.is-parent { 94 | padding-top:1em; 95 | padding-bottom:1em; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | var validEnv = ['development', 'test', 'production'] 3 | var currentEnv = api.env() 4 | var isDevelopmentEnv = api.env('development') 5 | var isProductionEnv = api.env('production') 6 | var isTestEnv = api.env('test') 7 | 8 | if (!validEnv.includes(currentEnv)) { 9 | throw new Error( 10 | 'Please specify a valid `NODE_ENV` or ' + 11 | '`BABEL_ENV` environment variables. Valid values are "development", ' + 12 | '"test", and "production". Instead, received: ' + 13 | JSON.stringify(currentEnv) + 14 | '.' 15 | ) 16 | } 17 | 18 | return { 19 | presets: [ 20 | isTestEnv && [ 21 | require('@babel/preset-env').default, 22 | { 23 | targets: { 24 | node: 'current' 25 | } 26 | } 27 | ], 28 | (isProductionEnv || isDevelopmentEnv) && [ 29 | require('@babel/preset-env').default, 30 | { 31 | forceAllTransforms: true, 32 | useBuiltIns: 'entry', 33 | corejs: 3, 34 | modules: false, 35 | exclude: ['transform-typeof-symbol'] 36 | } 37 | ] 38 | ].filter(Boolean), 39 | plugins: [ 40 | require('babel-plugin-macros'), 41 | require('@babel/plugin-syntax-dynamic-import').default, 42 | isTestEnv && require('babel-plugin-dynamic-import-node'), 43 | require('@babel/plugin-transform-destructuring').default, 44 | [ 45 | require('@babel/plugin-proposal-class-properties').default, 46 | { 47 | loose: true 48 | } 49 | ], 50 | [ 51 | require('@babel/plugin-proposal-object-rest-spread').default, 52 | { 53 | useBuiltIns: true 54 | } 55 | ], 56 | [ 57 | require('@babel/plugin-transform-runtime').default, 58 | { 59 | helpers: false, 60 | regenerator: true, 61 | corejs: false 62 | } 63 | ], 64 | [ 65 | require('@babel/plugin-transform-regenerator').default, 66 | { 67 | async: false 68 | } 69 | ] 70 | ].filter(Boolean) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /config/webpacker.yml: -------------------------------------------------------------------------------- 1 | # Note: You must restart bin/webpack-dev-server for changes to take effect 2 | 3 | default: &default 4 | source_path: app/javascript 5 | source_entry_path: packs 6 | public_root_path: public 7 | public_output_path: packs 8 | cache_path: tmp/cache/webpacker 9 | check_yarn_integrity: false 10 | webpack_compile_output: false 11 | 12 | # Additional paths webpack should lookup modules 13 | # ['app/assets', 'engine/foo/app/assets'] 14 | resolved_paths: [] 15 | 16 | # Reload manifest.json on all requests so we reload latest compiled packs 17 | cache_manifest: false 18 | 19 | # Extract and emit a css file 20 | extract_css: false 21 | 22 | static_assets_extensions: 23 | - .jpg 24 | - .jpeg 25 | - .png 26 | - .gif 27 | - .tiff 28 | - .ico 29 | - .svg 30 | - .eot 31 | - .otf 32 | - .ttf 33 | - .woff 34 | - .woff2 35 | 36 | extensions: 37 | - .mjs 38 | - .js 39 | - .sass 40 | - .scss 41 | - .css 42 | - .module.sass 43 | - .module.scss 44 | - .module.css 45 | - .png 46 | - .svg 47 | - .gif 48 | - .jpeg 49 | - .jpg 50 | 51 | development: 52 | <<: *default 53 | compile: true 54 | 55 | # Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules 56 | check_yarn_integrity: true 57 | 58 | # Reference: https://webpack.js.org/configuration/dev-server/ 59 | dev_server: 60 | https: false 61 | host: localhost 62 | port: 3035 63 | public: localhost:3035 64 | hmr: false 65 | # Inline should be set to true if using HMR 66 | inline: true 67 | overlay: true 68 | compress: true 69 | disable_host_check: true 70 | use_local_ip: false 71 | quiet: false 72 | headers: 73 | 'Access-Control-Allow-Origin': '*' 74 | watch_options: 75 | ignored: '**/node_modules/**' 76 | 77 | 78 | test: 79 | <<: *default 80 | compile: true 81 | 82 | # Compile test packs to a separate directory 83 | public_output_path: packs-test 84 | 85 | production: 86 | <<: *default 87 | 88 | # Production depends on precompilation of packs prior to booting for performance. 89 | compile: false 90 | 91 | # Extract and emit a css file 92 | extract_css: true 93 | 94 | # Cache manifest.json for performance 95 | cache_manifest: true 96 | -------------------------------------------------------------------------------- /db/migrate/20230402174122_create_active_storage_tables.active_storage.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from active_storage (originally 20170806125915) 2 | class CreateActiveStorageTables < ActiveRecord::Migration[5.2] 3 | def change 4 | # Use Active Record's configured type for primary and foreign keys 5 | primary_key_type, foreign_key_type = primary_and_foreign_key_types 6 | 7 | create_table :active_storage_blobs, id: primary_key_type do |t| 8 | t.string :key, null: false 9 | t.string :filename, null: false 10 | t.string :content_type 11 | t.text :metadata 12 | t.string :service_name, null: false 13 | t.bigint :byte_size, null: false 14 | t.string :checksum 15 | 16 | if connection.supports_datetime_with_precision? 17 | t.datetime :created_at, precision: 6, null: false 18 | else 19 | t.datetime :created_at, null: false 20 | end 21 | 22 | t.index [ :key ], unique: true 23 | end 24 | 25 | create_table :active_storage_attachments, id: primary_key_type do |t| 26 | t.string :name, null: false 27 | t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type 28 | t.references :blob, null: false, type: foreign_key_type 29 | 30 | if connection.supports_datetime_with_precision? 31 | t.datetime :created_at, precision: 6, null: false 32 | else 33 | t.datetime :created_at, null: false 34 | end 35 | 36 | t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true 37 | t.foreign_key :active_storage_blobs, column: :blob_id 38 | end 39 | 40 | create_table :active_storage_variant_records, id: primary_key_type do |t| 41 | t.belongs_to :blob, null: false, index: false, type: foreign_key_type 42 | t.string :variation_digest, null: false 43 | 44 | t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true 45 | t.foreign_key :active_storage_blobs, column: :blob_id 46 | end 47 | end 48 | 49 | private 50 | def primary_and_foreign_key_types 51 | config = Rails.configuration.generators 52 | setting = config.options[config.orm][:primary_key_type] 53 | primary_key_type = setting || :primary_key 54 | foreign_key_type = setting || :bigint 55 | [primary_key_type, foreign_key_type] 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | # The test environment is used exclusively to run your application's 4 | # test suite. You never need to work with it otherwise. Remember that 5 | # your test database is "scratch space" for the test suite and is wiped 6 | # and recreated between test runs. Don't rely on the data there! 7 | 8 | Rails.application.configure do 9 | # Settings specified here will take precedence over those in config/application.rb. 10 | 11 | # Turn false under Spring and add config.action_view.cache_template_loading = true. 12 | config.cache_classes = true 13 | 14 | # Eager loading loads your whole application. When running a single test locally, 15 | # this probably isn't necessary. It's a good idea to do in a continuous integration 16 | # system, or in some way before deploying your code. 17 | config.eager_load = ENV["CI"].present? 18 | 19 | # Configure public file server for tests with Cache-Control for performance. 20 | config.public_file_server.enabled = true 21 | config.public_file_server.headers = { 22 | "Cache-Control" => "public, max-age=#{1.hour.to_i}" 23 | } 24 | 25 | # Show full error reports and disable caching. 26 | config.consider_all_requests_local = true 27 | config.action_controller.perform_caching = false 28 | config.cache_store = :null_store 29 | 30 | # Raise exceptions instead of rendering exception templates. 31 | config.action_dispatch.show_exceptions = false 32 | 33 | # Disable request forgery protection in test environment. 34 | config.action_controller.allow_forgery_protection = false 35 | 36 | # Store uploaded files on the local file system in a temporary directory. 37 | config.active_storage.service = :test 38 | 39 | config.action_mailer.perform_caching = false 40 | 41 | # Tell Action Mailer not to deliver emails to the real world. 42 | # The :test delivery method accumulates sent emails in the 43 | # ActionMailer::Base.deliveries array. 44 | config.action_mailer.delivery_method = :test 45 | 46 | # Print deprecation notices to the stderr. 47 | config.active_support.deprecation = :stderr 48 | 49 | # Raise exceptions for disallowed deprecations. 50 | config.active_support.disallowed_deprecation = :raise 51 | 52 | # Tell Active Support which deprecation messages to disallow. 53 | config.active_support.disallowed_deprecation_warnings = [] 54 | 55 | # Raises error for missing translations. 56 | # config.i18n.raise_on_missing_translations = true 57 | 58 | # Annotate rendered view with file names. 59 | # config.action_view.annotate_rendered_view_with_filenames = true 60 | end 61 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # In the development environment your application's code is reloaded any time 7 | # it changes. This slows down response time but is perfect for development 8 | # since you don't have to restart the web server when you make code changes. 9 | config.cache_classes = false 10 | 11 | # Do not eager load code on boot. 12 | config.eager_load = false 13 | 14 | # Show full error reports. 15 | config.consider_all_requests_local = true 16 | 17 | # Enable server timing 18 | config.server_timing = true 19 | 20 | # Enable/disable caching. By default caching is disabled. 21 | # Run rails dev:cache to toggle caching. 22 | if Rails.root.join("tmp/caching-dev.txt").exist? 23 | config.action_controller.perform_caching = true 24 | config.action_controller.enable_fragment_cache_logging = true 25 | 26 | config.cache_store = :memory_store 27 | config.public_file_server.headers = { 28 | "Cache-Control" => "public, max-age=#{2.days.to_i}" 29 | } 30 | else 31 | config.action_controller.perform_caching = false 32 | 33 | config.cache_store = :null_store 34 | end 35 | 36 | # Store uploaded files on the local file system (see config/storage.yml for options). 37 | config.active_storage.service = :local 38 | 39 | # Don't care if the mailer can't send. 40 | config.action_mailer.raise_delivery_errors = false 41 | 42 | config.action_mailer.perform_caching = false 43 | 44 | # Print deprecation notices to the Rails logger. 45 | config.active_support.deprecation = :log 46 | 47 | # Raise exceptions for disallowed deprecations. 48 | config.active_support.disallowed_deprecation = :raise 49 | 50 | # Tell Active Support which deprecation messages to disallow. 51 | config.active_support.disallowed_deprecation_warnings = [] 52 | 53 | # Raise an error on page load if there are pending migrations. 54 | config.active_record.migration_error = :page_load 55 | 56 | # Highlight code that triggered database queries in logs. 57 | config.active_record.verbose_query_logs = true 58 | 59 | # Suppress logger output for asset requests. 60 | config.assets.quiet = true 61 | 62 | # Raises error for missing translations. 63 | # config.i18n.raise_on_missing_translations = true 64 | 65 | # Annotate rendered view with file names. 66 | # config.action_view.annotate_rendered_view_with_filenames = true 67 | 68 | # Uncomment if you wish to allow Action Cable access from any origin. 69 | # config.action_cable.disable_request_forgery_protection = true 70 | end 71 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile 4 | ARG RUBY_VERSION=3.2.2 5 | FROM ruby:$RUBY_VERSION-slim as base 6 | 7 | LABEL fly_launch_runtime="rails" 8 | 9 | # Rails app lives here 10 | WORKDIR /rails 11 | 12 | # Set production environment 13 | ENV RAILS_ENV="production" \ 14 | BUNDLE_WITHOUT="development:test" \ 15 | BUNDLE_DEPLOYMENT="1" 16 | 17 | # Update gems and bundler 18 | RUN gem update --system --no-document && \ 19 | gem install -N bundler 20 | 21 | 22 | # Throw-away build stage to reduce size of final image 23 | FROM base as build 24 | 25 | # Install packages needed to build gems and node modules 26 | RUN apt-get update -qq && \ 27 | apt-get install --no-install-recommends -y build-essential curl git libpq-dev node-gyp pkg-config python-is-python3 28 | 29 | # Install JavaScript dependencies 30 | ARG NODE_VERSION=18.16.0 31 | ENV PATH=/usr/local/node/bin:$PATH 32 | RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \ 33 | /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \ 34 | rm -rf /tmp/node-build-master 35 | 36 | # Install application gems 37 | COPY --link Gemfile Gemfile.lock ./ 38 | RUN bundle install && \ 39 | bundle exec bootsnap precompile --gemfile && \ 40 | rm -rf ~/.bundle/ $BUNDLE_PATH/ruby/*/cache $BUNDLE_PATH/ruby/*/bundler/gems/*/.git 41 | 42 | # Install node modules 43 | COPY --link package.json package-lock.json ./ 44 | RUN npm ci 45 | 46 | # Copy application code 47 | COPY --link . . 48 | 49 | # Precompile bootsnap code for faster boot times 50 | RUN bundle exec bootsnap precompile app/ lib/ 51 | 52 | # Precompiling assets for production without requiring secret RAILS_MASTER_KEY 53 | RUN SECRET_KEY_BASE=DUMMY ./bin/rails assets:precompile 54 | 55 | 56 | # Final stage for app image 57 | FROM base 58 | 59 | # Install packages needed for deployment 60 | RUN apt-get update -qq && \ 61 | apt-get install --no-install-recommends -y postgresql-client && \ 62 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 63 | 64 | # Run and own the application files as a non-root user for security 65 | RUN useradd rails --home /rails --shell /bin/bash 66 | USER rails:rails 67 | 68 | # Copy built artifacts: gems, application 69 | COPY --from=build /usr/local/bundle /usr/local/bundle 70 | COPY --from=build --chown=rails:rails /rails /rails 71 | 72 | # Deployment options 73 | ENV RAILS_LOG_TO_STDOUT="1" \ 74 | RAILS_SERVE_STATIC_FILES="true" 75 | 76 | # Entrypoint prepares the database. 77 | ENTRYPOINT ["/rails/bin/docker-entrypoint"] 78 | 79 | # Start the server by default, this can be overwritten at runtime 80 | EXPOSE 3000 81 | CMD ["./bin/rails", "server"] 82 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundle' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | require "rubygems" 12 | 13 | m = Module.new do 14 | module_function 15 | 16 | def invoked_as_script? 17 | File.expand_path($0) == File.expand_path(__FILE__) 18 | end 19 | 20 | def env_var_version 21 | ENV["BUNDLER_VERSION"] 22 | end 23 | 24 | def cli_arg_version 25 | return unless invoked_as_script? # don't want to hijack other binstubs 26 | return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` 27 | bundler_version = nil 28 | update_index = nil 29 | ARGV.each_with_index do |a, i| 30 | if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN 31 | bundler_version = a 32 | end 33 | next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ 34 | bundler_version = $1 35 | update_index = i 36 | end 37 | bundler_version 38 | end 39 | 40 | def gemfile 41 | gemfile = ENV["BUNDLE_GEMFILE"] 42 | return gemfile if gemfile && !gemfile.empty? 43 | 44 | File.expand_path("../Gemfile", __dir__) 45 | end 46 | 47 | def lockfile 48 | lockfile = 49 | case File.basename(gemfile) 50 | when "gems.rb" then gemfile.sub(/\.rb$/, gemfile) 51 | else "#{gemfile}.lock" 52 | end 53 | File.expand_path(lockfile) 54 | end 55 | 56 | def lockfile_version 57 | return unless File.file?(lockfile) 58 | lockfile_contents = File.read(lockfile) 59 | return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ 60 | Regexp.last_match(1) 61 | end 62 | 63 | def bundler_requirement 64 | @bundler_requirement ||= 65 | env_var_version || 66 | cli_arg_version || 67 | bundler_requirement_for(lockfile_version) 68 | end 69 | 70 | def bundler_requirement_for(version) 71 | return "#{Gem::Requirement.default}.a" unless version 72 | 73 | bundler_gem_version = Gem::Version.new(version) 74 | 75 | bundler_gem_version.approximate_recommendation 76 | end 77 | 78 | def load_bundler! 79 | ENV["BUNDLE_GEMFILE"] ||= gemfile 80 | 81 | activate_bundler 82 | end 83 | 84 | def activate_bundler 85 | gem_error = activation_error_handling do 86 | gem "bundler", bundler_requirement 87 | end 88 | return if gem_error.nil? 89 | require_error = activation_error_handling do 90 | require "bundler/version" 91 | end 92 | return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) 93 | 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}'`" 94 | exit 42 95 | end 96 | 97 | def activation_error_handling 98 | yield 99 | nil 100 | rescue StandardError, LoadError => e 101 | e 102 | end 103 | end 104 | 105 | m.load_bundler! 106 | 107 | if m.invoked_as_script? 108 | load Gem.bin_path("bundler", "bundle") 109 | end 110 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # PostgreSQL. Versions 9.3 and up are supported. 2 | # 3 | # Install the pg driver: 4 | # gem install pg 5 | # On macOS with Homebrew: 6 | # gem install pg -- --with-pg-config=/usr/local/bin/pg_config 7 | # On macOS with MacPorts: 8 | # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config 9 | # On Windows: 10 | # gem install pg 11 | # Choose the win32 build. 12 | # Install PostgreSQL and put its /bin directory on your path. 13 | # 14 | # Configure Using Gemfile 15 | # gem "pg" 16 | # 17 | default: &default 18 | adapter: postgresql 19 | encoding: unicode 20 | # For details on connection pooling, see Rails configuration guide 21 | # https://guides.rubyonrails.org/configuring.html#database-pooling 22 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 23 | 24 | development: 25 | <<: *default 26 | database: rapidfire_app_development 27 | 28 | # The specified database role being used to connect to postgres. 29 | # To create additional roles in postgres see `$ createuser --help`. 30 | # When left blank, postgres will use the default role. This is 31 | # the same name as the operating system user running Rails. 32 | #username: rapidfire_app 33 | 34 | # The password associated with the postgres role (username). 35 | #password: 36 | 37 | # Connect on a TCP socket. Omitted by default since the client uses a 38 | # domain socket that doesn't need configuration. Windows does not have 39 | # domain sockets, so uncomment these lines. 40 | #host: localhost 41 | 42 | # The TCP port the server listens on. Defaults to 5432. 43 | # If your server runs on a different port number, change accordingly. 44 | #port: 5432 45 | 46 | # Schema search path. The server defaults to $user,public 47 | #schema_search_path: myapp,sharedapp,public 48 | 49 | # Minimum log levels, in increasing order: 50 | # debug5, debug4, debug3, debug2, debug1, 51 | # log, notice, warning, error, fatal, and panic 52 | # Defaults to warning. 53 | #min_messages: notice 54 | 55 | # Warning: The database defined as "test" will be erased and 56 | # re-generated from your development database when you run "rake". 57 | # Do not set this db to the same as development or production. 58 | test: 59 | <<: *default 60 | database: rapidfire_app_test 61 | 62 | # As with config/credentials.yml, you never want to store sensitive information, 63 | # like your database password, in your source code. If your source code is 64 | # ever seen by anyone, they now have access to your database. 65 | # 66 | # Instead, provide the password or a full connection URL as an environment 67 | # variable when you boot the app. For example: 68 | # 69 | # DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" 70 | # 71 | # If the connection URL is provided in the special DATABASE_URL environment 72 | # variable, Rails will automatically merge its configuration values on top of 73 | # the values provided in this file. Alternatively, you can specify a connection 74 | # URL environment variable explicitly: 75 | # 76 | # production: 77 | # url: <%= ENV["MY_APP_DATABASE_URL"] %> 78 | # 79 | # Read https://guides.rubyonrails.org/configuring.html#configuring-a-database 80 | # for a full overview on how database connection configuration can be specified. 81 | # 82 | production: 83 | <<: *default 84 | database: rapidfire_app_production 85 | username: rapidfire_app 86 | password: <%= ENV["RAPIDFIRE_APP_DATABASE_PASSWORD"] %> 87 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # Code is not reloaded between requests. 7 | config.cache_classes = true 8 | 9 | # Eager load code on boot. This eager loads most of Rails and 10 | # your application in memory, allowing both threaded web servers 11 | # and those relying on copy on write to perform better. 12 | # Rake tasks automatically ignore this option for performance. 13 | config.eager_load = true 14 | 15 | # Full error reports are disabled and caching is turned on. 16 | config.consider_all_requests_local = false 17 | config.action_controller.perform_caching = true 18 | 19 | # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] 20 | # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). 21 | # config.require_master_key = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? 26 | 27 | # Compress CSS using a preprocessor. 28 | # config.assets.css_compressor = :sass 29 | 30 | # Do not fallback to assets pipeline if a precompiled asset is missed. 31 | config.assets.compile = false 32 | 33 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 34 | # config.asset_host = "http://assets.example.com" 35 | 36 | # Specifies the header that your server uses for sending files. 37 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache 38 | # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX 39 | 40 | # Store uploaded files on the local file system (see config/storage.yml for options). 41 | config.active_storage.service = :local 42 | 43 | # Mount Action Cable outside main process or domain. 44 | # config.action_cable.mount_path = nil 45 | # config.action_cable.url = "wss://example.com/cable" 46 | # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] 47 | 48 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 49 | # config.force_ssl = true 50 | 51 | # Include generic and useful information about system operation, but avoid logging too much 52 | # information to avoid inadvertent exposure of personally identifiable information (PII). 53 | config.log_level = :info 54 | 55 | # Prepend all log lines with the following tags. 56 | config.log_tags = [ :request_id ] 57 | 58 | # Use a different cache store in production. 59 | # config.cache_store = :mem_cache_store 60 | 61 | # Use a real queuing backend for Active Job (and separate queues per environment). 62 | # config.active_job.queue_adapter = :resque 63 | # config.active_job.queue_name_prefix = "rapidfire_app_production" 64 | 65 | config.action_mailer.perform_caching = false 66 | 67 | # Ignore bad email addresses and do not raise email delivery errors. 68 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 69 | # config.action_mailer.raise_delivery_errors = false 70 | 71 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 72 | # the I18n.default_locale when a translation cannot be found). 73 | config.i18n.fallbacks = true 74 | 75 | # Don't log any deprecations. 76 | config.active_support.report_deprecations = false 77 | 78 | # Use default logging formatter so that PID and timestamp are not suppressed. 79 | config.log_formatter = ::Logger::Formatter.new 80 | 81 | # Use a different logger for distributed setups. 82 | # require "syslog/logger" 83 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name") 84 | 85 | if ENV["RAILS_LOG_TO_STDOUT"].present? 86 | logger = ActiveSupport::Logger.new(STDOUT) 87 | logger.formatter = config.log_formatter 88 | config.logger = ActiveSupport::TaggedLogging.new(logger) 89 | end 90 | 91 | # Do not dump schema after migrations. 92 | config.active_record.dump_schema_after_migration = false 93 | end 94 | -------------------------------------------------------------------------------- /app/views/rapidfire/questions/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for form, as: :question, url: url, method: method, html: { class: "grid grid-cols-1 lg:grid-cols-2 gap-6" }, data: { turbo: false } do |f| %> 2 | <%- if form.errors.any? %> 3 | 8 | <% end %> 9 | 10 |
11 |

Details

12 |
13 | <%= f.label :type, class: "block text-sm font-medium leading-6 text-gray-900" %> 14 | <%= f.select :type, ::Rapidfire::QuestionForm::QUESTION_TYPES, {include_blank: "Select question Type"}, id: "question_type", class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 15 |
16 | 17 |
18 | <%= f.label :question_text, class: "block text-sm font-medium leading-6 text-gray-900" %> 19 | <%= f.text_field :question_text, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 20 |
21 | 22 |
23 | <%= f.label :position, class: "block text-sm font-medium leading-6 text-gray-900" %> 24 | <%= f.number_field :position, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 25 |
26 | 27 |
28 | <%= f.label :placeholder, class: "block text-sm font-medium leading-6 text-gray-900" %> 29 | <%= f.text_field :placeholder, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 30 |
31 | 32 |
33 | <%= f.label :default_text, class: "block text-sm font-medium leading-6 text-gray-900" %> 34 | <%= f.text_field :default_text, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 35 |
36 | 37 |
38 | <%= f.label :answer_options, class: "block text-sm font-medium leading-6 text-gray-900" %> 39 | <%= f.text_area :answer_options, rows: 5, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 40 |
41 |
42 | 43 |
44 |

Other options

45 | 46 |
47 | <%= f.label :answer_minimum_length, class: "block text-sm font-medium leading-6 text-gray-900" %> 48 | <%= f.text_field :answer_minimum_length, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 49 |
50 | 51 |
52 | <%= f.label :answer_maximum_length, class: "block text-sm font-medium leading-6 text-gray-900" %> 53 | <%= f.text_field :answer_maximum_length, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 54 |
55 | 56 |
57 | <%= f.label :answer_greater_than_or_equal_to, class: "block text-sm font-medium leading-6 text-gray-900" %> 58 | <%= f.text_field :answer_greater_than_or_equal_to, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 59 |
60 | 61 |
62 | <%= f.label :answer_less_than_or_equal_to, class: "block text-sm font-medium leading-6 text-gray-900" %> 63 | <%= f.text_field :answer_less_than_or_equal_to, class: "block w-full p-1 mt-2 rounded-md border-0 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm sm:leading-6" %> 64 |
65 | 66 |
67 | <%= f.check_box :answer_presence %> 68 | <%= f.label :answer_presence, class: "ml-1 cursor-pointer inline-block text-sm font-medium leading-6 text-gray-900" %> 69 |
70 |
71 | 72 |
73 | <%= f.submit submit_text, class: "cursor-pointer rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" %> 74 |
75 | <% end %> 76 | -------------------------------------------------------------------------------- /config/locales/devise.en.yml: -------------------------------------------------------------------------------- 1 | # Additional translations at https://github.com/plataformatec/devise/wiki/I18n 2 | 3 | en: 4 | devise: 5 | confirmations: 6 | confirmed: "Your email address has been successfully confirmed." 7 | send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." 8 | send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes." 9 | failure: 10 | already_authenticated: "You are already signed in." 11 | inactive: "Your account is not activated yet." 12 | invalid: "Invalid %{authentication_keys} or password." 13 | locked: "Your account is locked." 14 | last_attempt: "You have one more attempt before your account is locked." 15 | not_found_in_database: "Invalid %{authentication_keys} or password." 16 | timeout: "Your session expired. Please sign in again to continue." 17 | unauthenticated: "You need to sign in or sign up before continuing." 18 | unconfirmed: "You have to confirm your email address before continuing." 19 | mailer: 20 | confirmation_instructions: 21 | subject: "Confirmation instructions" 22 | reset_password_instructions: 23 | subject: "Reset password instructions" 24 | unlock_instructions: 25 | subject: "Unlock instructions" 26 | email_changed: 27 | subject: "Email Changed" 28 | password_change: 29 | subject: "Password Changed" 30 | omniauth_callbacks: 31 | failure: "Could not authenticate you from %{kind} because \"%{reason}\"." 32 | success: "Successfully authenticated from %{kind} account." 33 | passwords: 34 | 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." 35 | send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." 36 | 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." 37 | updated: "Your password has been changed successfully. You are now signed in." 38 | updated_not_active: "Your password has been changed successfully." 39 | registrations: 40 | destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon." 41 | signed_up: "Welcome! You have signed up successfully." 42 | signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." 43 | signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." 44 | signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account." 45 | update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address." 46 | updated: "Your account has been updated successfully." 47 | updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again" 48 | sessions: 49 | signed_in: "Signed in successfully." 50 | signed_out: "Signed out successfully." 51 | already_signed_out: "Signed out successfully." 52 | unlocks: 53 | send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes." 54 | send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes." 55 | unlocked: "Your account has been unlocked successfully. Please sign in to continue." 56 | errors: 57 | messages: 58 | already_confirmed: "was already confirmed, please try signing in" 59 | confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" 60 | expired: "has expired, please request a new one" 61 | not_found: "not found" 62 | not_locked: "was not locked" 63 | not_saved: 64 | one: "1 error prohibited this %{resource} from being saved:" 65 | other: "%{count} errors prohibited this %{resource} from being saved:" 66 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # This file is the source Rails uses to define your schema when running `bin/rails 6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to 7 | # be faster and is potentially less error prone than running all of your 8 | # migrations from scratch. Old migrations may fail to apply correctly if those 9 | # migrations use external dependencies or application code. 10 | # 11 | # It's strongly recommended that you check this file into your version control system. 12 | 13 | ActiveRecord::Schema[7.0].define(version: 2023_04_02_174122) do 14 | # These are extensions that must be enabled in order to support this database 15 | enable_extension "plpgsql" 16 | 17 | create_table "active_storage_attachments", force: :cascade do |t| 18 | t.string "name", null: false 19 | t.string "record_type", null: false 20 | t.bigint "record_id", null: false 21 | t.bigint "blob_id", null: false 22 | t.datetime "created_at", null: false 23 | t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" 24 | t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true 25 | end 26 | 27 | create_table "active_storage_blobs", force: :cascade do |t| 28 | t.string "key", null: false 29 | t.string "filename", null: false 30 | t.string "content_type" 31 | t.text "metadata" 32 | t.string "service_name", null: false 33 | t.bigint "byte_size", null: false 34 | t.string "checksum" 35 | t.datetime "created_at", null: false 36 | t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true 37 | end 38 | 39 | create_table "active_storage_variant_records", force: :cascade do |t| 40 | t.bigint "blob_id", null: false 41 | t.string "variation_digest", null: false 42 | t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true 43 | end 44 | 45 | create_table "rapidfire_answers", force: :cascade do |t| 46 | t.bigint "attempt_id" 47 | t.bigint "question_id" 48 | t.text "answer_text" 49 | t.datetime "created_at", null: false 50 | t.datetime "updated_at", null: false 51 | t.index ["attempt_id"], name: "index_rapidfire_answers_on_attempt_id" 52 | t.index ["question_id"], name: "index_rapidfire_answers_on_question_id" 53 | end 54 | 55 | create_table "rapidfire_attempts", force: :cascade do |t| 56 | t.bigint "survey_id" 57 | t.string "user_type" 58 | t.bigint "user_id" 59 | t.datetime "created_at", null: false 60 | t.datetime "updated_at", null: false 61 | t.index ["survey_id"], name: "index_rapidfire_attempts_on_survey_id" 62 | t.index ["user_id", "user_type"], name: "index_rapidfire_attempts_on_user_id_and_user_type" 63 | t.index ["user_type", "user_id"], name: "index_rapidfire_attempts_on_user" 64 | end 65 | 66 | create_table "rapidfire_questions", force: :cascade do |t| 67 | t.bigint "survey_id" 68 | t.string "type" 69 | t.string "question_text" 70 | t.string "default_text" 71 | t.string "placeholder" 72 | t.integer "position" 73 | t.text "answer_options" 74 | t.text "validation_rules" 75 | t.datetime "created_at", null: false 76 | t.datetime "updated_at", null: false 77 | t.index ["survey_id"], name: "index_rapidfire_questions_on_survey_id" 78 | end 79 | 80 | create_table "rapidfire_surveys", force: :cascade do |t| 81 | t.string "name" 82 | t.text "introduction" 83 | t.datetime "created_at", null: false 84 | t.datetime "updated_at", null: false 85 | t.text "after_survey_content" 86 | end 87 | 88 | create_table "users", force: :cascade do |t| 89 | t.string "email", default: "", null: false 90 | t.string "encrypted_password", default: "", null: false 91 | t.string "reset_password_token" 92 | t.datetime "reset_password_sent_at", precision: nil 93 | t.datetime "remember_created_at", precision: nil 94 | t.datetime "created_at", null: false 95 | t.datetime "updated_at", null: false 96 | t.boolean "admin" 97 | t.index ["email"], name: "index_users_on_email", unique: true 98 | t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true 99 | end 100 | 101 | add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" 102 | add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" 103 | end 104 | -------------------------------------------------------------------------------- /app/assets/builds/application.css: -------------------------------------------------------------------------------- 1 | /*! tailwindcss v3.3.1 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.static{position:static}.relative{position:relative}.my-3{margin-top:.75rem;margin-bottom:.75rem}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.table{display:table}.grid{display:grid}.w-full{width:100%}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-6{gap:1.5rem}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.rounded-md{border-radius:.375rem}.border-0{border-width:0}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.p-1{padding:.25rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-20{padding-top:5rem;padding-bottom:5rem}.text-center{text-align:center}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-6{line-height:1.5rem}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-inset{--tw-ring-inset:inset}.ring-gray-300{--tw-ring-opacity:1;--tw-ring-color:rgb(209 213 219/var(--tw-ring-opacity))}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}@media (min-width:640px){.sm\:text-sm{font-size:.875rem;line-height:1.25rem}.sm\:leading-6{line-height:1.5rem}}@media (min-width:768px){.md\:justify-normal{justify-content:normal}.md\:gap-6{gap:1.5rem}}@media (min-width:1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}} -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actioncable (7.0.4.3) 5 | actionpack (= 7.0.4.3) 6 | activesupport (= 7.0.4.3) 7 | nio4r (~> 2.0) 8 | websocket-driver (>= 0.6.1) 9 | actionmailbox (7.0.4.3) 10 | actionpack (= 7.0.4.3) 11 | activejob (= 7.0.4.3) 12 | activerecord (= 7.0.4.3) 13 | activestorage (= 7.0.4.3) 14 | activesupport (= 7.0.4.3) 15 | mail (>= 2.7.1) 16 | net-imap 17 | net-pop 18 | net-smtp 19 | actionmailer (7.0.4.3) 20 | actionpack (= 7.0.4.3) 21 | actionview (= 7.0.4.3) 22 | activejob (= 7.0.4.3) 23 | activesupport (= 7.0.4.3) 24 | mail (~> 2.5, >= 2.5.4) 25 | net-imap 26 | net-pop 27 | net-smtp 28 | rails-dom-testing (~> 2.0) 29 | actionpack (7.0.4.3) 30 | actionview (= 7.0.4.3) 31 | activesupport (= 7.0.4.3) 32 | rack (~> 2.0, >= 2.2.0) 33 | rack-test (>= 0.6.3) 34 | rails-dom-testing (~> 2.0) 35 | rails-html-sanitizer (~> 1.0, >= 1.2.0) 36 | actiontext (7.0.4.3) 37 | actionpack (= 7.0.4.3) 38 | activerecord (= 7.0.4.3) 39 | activestorage (= 7.0.4.3) 40 | activesupport (= 7.0.4.3) 41 | globalid (>= 0.6.0) 42 | nokogiri (>= 1.8.5) 43 | actionview (7.0.4.3) 44 | activesupport (= 7.0.4.3) 45 | builder (~> 3.1) 46 | erubi (~> 1.4) 47 | rails-dom-testing (~> 2.0) 48 | rails-html-sanitizer (~> 1.1, >= 1.2.0) 49 | active_model_serializers (0.10.13) 50 | actionpack (>= 4.1, < 7.1) 51 | activemodel (>= 4.1, < 7.1) 52 | case_transform (>= 0.2) 53 | jsonapi-renderer (>= 0.1.1.beta1, < 0.3) 54 | activejob (7.0.4.3) 55 | activesupport (= 7.0.4.3) 56 | globalid (>= 0.3.6) 57 | activemodel (7.0.4.3) 58 | activesupport (= 7.0.4.3) 59 | activerecord (7.0.4.3) 60 | activemodel (= 7.0.4.3) 61 | activesupport (= 7.0.4.3) 62 | activestorage (7.0.4.3) 63 | actionpack (= 7.0.4.3) 64 | activejob (= 7.0.4.3) 65 | activerecord (= 7.0.4.3) 66 | activesupport (= 7.0.4.3) 67 | marcel (~> 1.0) 68 | mini_mime (>= 1.1.0) 69 | activesupport (7.0.4.3) 70 | concurrent-ruby (~> 1.0, >= 1.0.2) 71 | i18n (>= 1.6, < 2) 72 | minitest (>= 5.1) 73 | tzinfo (~> 2.0) 74 | bcrypt (3.1.18) 75 | bootsnap (1.16.0) 76 | msgpack (~> 1.2) 77 | builder (3.2.4) 78 | case_transform (0.2) 79 | activesupport 80 | concurrent-ruby (1.2.2) 81 | crass (1.0.6) 82 | cssbundling-rails (1.1.2) 83 | railties (>= 6.0.0) 84 | date (3.3.3) 85 | devise (4.9.1) 86 | bcrypt (~> 3.0) 87 | orm_adapter (~> 0.1) 88 | railties (>= 4.1.0) 89 | responders 90 | warden (~> 1.2.3) 91 | dockerfile-rails (1.2.5) 92 | rails 93 | erubi (1.12.0) 94 | globalid (1.1.0) 95 | activesupport (>= 5.0) 96 | i18n (1.12.0) 97 | concurrent-ruby (~> 1.0) 98 | jbuilder (2.11.5) 99 | actionview (>= 5.0.0) 100 | activesupport (>= 5.0.0) 101 | jsbundling-rails (1.1.1) 102 | railties (>= 6.0.0) 103 | jsonapi-renderer (0.2.2) 104 | kaminari (1.2.2) 105 | activesupport (>= 4.1.0) 106 | kaminari-actionview (= 1.2.2) 107 | kaminari-activerecord (= 1.2.2) 108 | kaminari-core (= 1.2.2) 109 | kaminari-actionview (1.2.2) 110 | actionview 111 | kaminari-core (= 1.2.2) 112 | kaminari-activerecord (1.2.2) 113 | activerecord 114 | kaminari-core (= 1.2.2) 115 | kaminari-core (1.2.2) 116 | loofah (2.20.0) 117 | crass (~> 1.0.2) 118 | nokogiri (>= 1.5.9) 119 | mail (2.8.1) 120 | mini_mime (>= 0.1.1) 121 | net-imap 122 | net-pop 123 | net-smtp 124 | marcel (1.0.2) 125 | method_source (1.0.0) 126 | mini_mime (1.1.2) 127 | minitest (5.18.0) 128 | msgpack (1.7.0) 129 | net-imap (0.3.4) 130 | date 131 | net-protocol 132 | net-pop (0.1.2) 133 | net-protocol 134 | net-protocol (0.2.1) 135 | timeout 136 | net-smtp (0.3.3) 137 | net-protocol 138 | nio4r (2.5.8) 139 | nokogiri (1.14.2-aarch64-linux) 140 | racc (~> 1.4) 141 | nokogiri (1.14.2-arm64-darwin) 142 | racc (~> 1.4) 143 | nokogiri (1.14.2-x86_64-linux) 144 | racc (~> 1.4) 145 | orm_adapter (0.5.0) 146 | pg (1.4.6) 147 | puma (6.2.1) 148 | nio4r (~> 2.0) 149 | racc (1.6.2) 150 | rack (2.2.6.4) 151 | rack-test (2.1.0) 152 | rack (>= 1.3) 153 | rails (7.0.4.3) 154 | actioncable (= 7.0.4.3) 155 | actionmailbox (= 7.0.4.3) 156 | actionmailer (= 7.0.4.3) 157 | actionpack (= 7.0.4.3) 158 | actiontext (= 7.0.4.3) 159 | actionview (= 7.0.4.3) 160 | activejob (= 7.0.4.3) 161 | activemodel (= 7.0.4.3) 162 | activerecord (= 7.0.4.3) 163 | activestorage (= 7.0.4.3) 164 | activesupport (= 7.0.4.3) 165 | bundler (>= 1.15.0) 166 | railties (= 7.0.4.3) 167 | rails-dom-testing (2.0.3) 168 | activesupport (>= 4.2.0) 169 | nokogiri (>= 1.6) 170 | rails-html-sanitizer (1.5.0) 171 | loofah (~> 2.19, >= 2.19.1) 172 | railties (7.0.4.3) 173 | actionpack (= 7.0.4.3) 174 | activesupport (= 7.0.4.3) 175 | method_source 176 | rake (>= 12.2) 177 | thor (~> 1.0) 178 | zeitwerk (~> 2.5) 179 | rake (13.0.6) 180 | rapidfire (5.0.0) 181 | active_model_serializers (~> 0.10.0) 182 | rails (>= 3.2.13) 183 | responders (3.1.0) 184 | actionpack (>= 5.2) 185 | railties (>= 5.2) 186 | sprockets (4.2.0) 187 | concurrent-ruby (~> 1.0) 188 | rack (>= 2.2.4, < 4) 189 | sprockets-rails (3.4.2) 190 | actionpack (>= 5.2) 191 | activesupport (>= 5.2) 192 | sprockets (>= 3.0.0) 193 | stimulus-rails (1.2.1) 194 | railties (>= 6.0.0) 195 | thor (1.2.1) 196 | timeout (0.3.2) 197 | turbo-rails (1.4.0) 198 | actionpack (>= 6.0.0) 199 | activejob (>= 6.0.0) 200 | railties (>= 6.0.0) 201 | tzinfo (2.0.6) 202 | concurrent-ruby (~> 1.0) 203 | warden (1.2.9) 204 | rack (>= 2.0.9) 205 | websocket-driver (0.7.5) 206 | websocket-extensions (>= 0.1.0) 207 | websocket-extensions (0.1.5) 208 | zeitwerk (2.6.7) 209 | 210 | PLATFORMS 211 | aarch64-linux 212 | arm64-darwin-22 213 | x86_64-linux 214 | 215 | DEPENDENCIES 216 | bootsnap 217 | cssbundling-rails 218 | devise 219 | dockerfile-rails (>= 1.2) 220 | jbuilder 221 | jsbundling-rails 222 | kaminari 223 | pg 224 | puma 225 | rails 226 | rapidfire 227 | sprockets-rails 228 | stimulus-rails 229 | turbo-rails 230 | tzinfo-data 231 | 232 | RUBY VERSION 233 | ruby 3.2.2p53 234 | 235 | BUNDLED WITH 236 | 2.4.10 237 | -------------------------------------------------------------------------------- /config/initializers/devise.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Use this hook to configure devise mailer, warden hooks and so forth. 4 | # Many of these configuration options can be set straight in your model. 5 | Devise.setup do |config| 6 | # The secret key used by Devise. Devise uses this key to generate 7 | # random tokens. Changing this key will render invalid all existing 8 | # confirmation, reset password and unlock tokens in the database. 9 | # Devise will use the `secret_key_base` as its `secret_key` 10 | # by default. You can change it below and use your own secret key. 11 | # config.secret_key = '2acac85afaaebc37270229618f79f391079fdd9cbd4d654aa672f601b04dbad9ac0a13ffc20835837c17c9861bd80dbd19c92c20cbbf8045e4514b1657621918' 12 | 13 | # ==> Controller configuration 14 | # Configure the parent class to the devise controllers. 15 | # config.parent_controller = 'DeviseController' 16 | 17 | # ==> Mailer Configuration 18 | # Configure the e-mail address which will be shown in Devise::Mailer, 19 | # note that it will be overwritten if you use your own mailer class 20 | # with default "from" parameter. 21 | config.mailer_sender = 'team@codemancers.com' 22 | 23 | # Configure the class responsible to send e-mails. 24 | # config.mailer = 'Devise::Mailer' 25 | 26 | # Configure the parent class responsible to send e-mails. 27 | # config.parent_mailer = 'ActionMailer::Base' 28 | 29 | # ==> ORM configuration 30 | # Load and configure the ORM. Supports :active_record (default) and 31 | # :mongoid (bson_ext recommended) by default. Other ORMs may be 32 | # available as additional gems. 33 | require 'devise/orm/active_record' 34 | 35 | # ==> Configuration for any authentication mechanism 36 | # Configure which keys are used when authenticating a user. The default is 37 | # just :email. You can configure it to use [:username, :subdomain], so for 38 | # authenticating a user, both parameters are required. Remember that those 39 | # parameters are used only when authenticating and not when retrieving from 40 | # session. If you need permissions, you should implement that in a before filter. 41 | # You can also supply a hash where the value is a boolean determining whether 42 | # or not authentication should be aborted when the value is not present. 43 | # config.authentication_keys = [:email] 44 | 45 | # Configure parameters from the request object used for authentication. Each entry 46 | # given should be a request method and it will automatically be passed to the 47 | # find_for_authentication method and considered in your model lookup. For instance, 48 | # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. 49 | # The same considerations mentioned for authentication_keys also apply to request_keys. 50 | # config.request_keys = [] 51 | 52 | # Configure which authentication keys should be case-insensitive. 53 | # These keys will be downcased upon creating or modifying a user and when used 54 | # to authenticate or find a user. Default is :email. 55 | config.case_insensitive_keys = [:email] 56 | 57 | # Configure which authentication keys should have whitespace stripped. 58 | # These keys will have whitespace before and after removed upon creating or 59 | # modifying a user and when used to authenticate or find a user. Default is :email. 60 | config.strip_whitespace_keys = [:email] 61 | 62 | # Tell if authentication through request.params is enabled. True by default. 63 | # It can be set to an array that will enable params authentication only for the 64 | # given strategies, for example, `config.params_authenticatable = [:database]` will 65 | # enable it only for database (email + password) authentication. 66 | # config.params_authenticatable = true 67 | 68 | # Tell if authentication through HTTP Auth is enabled. False by default. 69 | # It can be set to an array that will enable http authentication only for the 70 | # given strategies, for example, `config.http_authenticatable = [:database]` will 71 | # enable it only for database authentication. The supported strategies are: 72 | # :database = Support basic authentication with authentication key + password 73 | # config.http_authenticatable = false 74 | 75 | # If 401 status code should be returned for AJAX requests. True by default. 76 | # config.http_authenticatable_on_xhr = true 77 | 78 | # The realm used in Http Basic Authentication. 'Application' by default. 79 | # config.http_authentication_realm = 'Application' 80 | 81 | # It will change confirmation, password recovery and other workflows 82 | # to behave the same regardless if the e-mail provided was right or wrong. 83 | # Does not affect registerable. 84 | # config.paranoid = true 85 | 86 | # By default Devise will store the user in session. You can skip storage for 87 | # particular strategies by setting this option. 88 | # Notice that if you are skipping storage for all authentication paths, you 89 | # may want to disable generating routes to Devise's sessions controller by 90 | # passing skip: :sessions to `devise_for` in your config/routes.rb 91 | config.skip_session_storage = [:http_auth] 92 | 93 | # By default, Devise cleans up the CSRF token on authentication to 94 | # avoid CSRF token fixation attacks. This means that, when using AJAX 95 | # requests for sign in and sign up, you need to get a new CSRF token 96 | # from the server. You can disable this option at your own risk. 97 | # config.clean_up_csrf_token_on_authentication = true 98 | 99 | # When false, Devise will not attempt to reload routes on eager load. 100 | # This can reduce the time taken to boot the app but if your application 101 | # requires the Devise mappings to be loaded during boot time the application 102 | # won't boot properly. 103 | # config.reload_routes = true 104 | 105 | # ==> Configuration for :database_authenticatable 106 | # For bcrypt, this is the cost for hashing the password and defaults to 11. If 107 | # using other algorithms, it sets how many times you want the password to be hashed. 108 | # 109 | # Limiting the stretches to just one in testing will increase the performance of 110 | # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use 111 | # a value less than 10 in other environments. Note that, for bcrypt (the default 112 | # algorithm), the cost increases exponentially with the number of stretches (e.g. 113 | # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). 114 | config.stretches = Rails.env.test? ? 1 : 11 115 | 116 | # Set up a pepper to generate the hashed password. 117 | # config.pepper = '5e6406da808cc06c31f5869c5e742d0d29c6a72d7e9cb09d01f6f9fe7f34ff761a2196c9113ca0c29ad5772f64ee125eb184e242fbcdb539a0d4739af8d75b29' 118 | 119 | # Send a notification to the original email when the user's email is changed. 120 | # config.send_email_changed_notification = false 121 | 122 | # Send a notification email when the user's password is changed. 123 | # config.send_password_change_notification = false 124 | 125 | # ==> Configuration for :confirmable 126 | # A period that the user is allowed to access the website even without 127 | # confirming their account. For instance, if set to 2.days, the user will be 128 | # able to access the website for two days without confirming their account, 129 | # access will be blocked just in the third day. 130 | # You can also set it to nil, which will allow the user to access the website 131 | # without confirming their account. 132 | # Default is 0.days, meaning the user cannot access the website without 133 | # confirming their account. 134 | # config.allow_unconfirmed_access_for = 2.days 135 | 136 | # A period that the user is allowed to confirm their account before their 137 | # token becomes invalid. For example, if set to 3.days, the user can confirm 138 | # their account within 3 days after the mail was sent, but on the fourth day 139 | # their account can't be confirmed with the token any more. 140 | # Default is nil, meaning there is no restriction on how long a user can take 141 | # before confirming their account. 142 | # config.confirm_within = 3.days 143 | 144 | # If true, requires any email changes to be confirmed (exactly the same way as 145 | # initial account confirmation) to be applied. Requires additional unconfirmed_email 146 | # db field (see migrations). Until confirmed, new email is stored in 147 | # unconfirmed_email column, and copied to email column on successful confirmation. 148 | config.reconfirmable = true 149 | 150 | # Defines which key will be used when confirming an account 151 | # config.confirmation_keys = [:email] 152 | 153 | # ==> Configuration for :rememberable 154 | # The time the user will be remembered without asking for credentials again. 155 | # config.remember_for = 2.weeks 156 | 157 | # Invalidates all the remember me tokens when the user signs out. 158 | config.expire_all_remember_me_on_sign_out = true 159 | 160 | # If true, extends the user's remember period when remembered via cookie. 161 | # config.extend_remember_period = false 162 | 163 | # Options to be passed to the created cookie. For instance, you can set 164 | # secure: true in order to force SSL only cookies. 165 | # config.rememberable_options = {} 166 | 167 | # ==> Configuration for :validatable 168 | # Range for password length. 169 | config.password_length = 6..128 170 | 171 | # Email regex used to validate email formats. It simply asserts that 172 | # one (and only one) @ exists in the given string. This is mainly 173 | # to give user feedback and not to assert the e-mail validity. 174 | config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ 175 | 176 | # ==> Configuration for :timeoutable 177 | # The time you want to timeout the user session without activity. After this 178 | # time the user will be asked for credentials again. Default is 30 minutes. 179 | # config.timeout_in = 30.minutes 180 | 181 | # ==> Configuration for :lockable 182 | # Defines which strategy will be used to lock an account. 183 | # :failed_attempts = Locks an account after a number of failed attempts to sign in. 184 | # :none = No lock strategy. You should handle locking by yourself. 185 | # config.lock_strategy = :failed_attempts 186 | 187 | # Defines which key will be used when locking and unlocking an account 188 | # config.unlock_keys = [:email] 189 | 190 | # Defines which strategy will be used to unlock an account. 191 | # :email = Sends an unlock link to the user email 192 | # :time = Re-enables login after a certain amount of time (see :unlock_in below) 193 | # :both = Enables both strategies 194 | # :none = No unlock strategy. You should handle unlocking by yourself. 195 | # config.unlock_strategy = :both 196 | 197 | # Number of authentication tries before locking an account if lock_strategy 198 | # is failed attempts. 199 | # config.maximum_attempts = 20 200 | 201 | # Time interval to unlock the account if :time is enabled as unlock_strategy. 202 | # config.unlock_in = 1.hour 203 | 204 | # Warn on the last attempt before the account is locked. 205 | # config.last_attempt_warning = true 206 | 207 | # ==> Configuration for :recoverable 208 | # 209 | # Defines which key will be used when recovering the password for an account 210 | # config.reset_password_keys = [:email] 211 | 212 | # Time interval you can reset your password with a reset password key. 213 | # Don't put a too small interval or your users won't have the time to 214 | # change their passwords. 215 | config.reset_password_within = 6.hours 216 | 217 | # When set to false, does not sign a user in automatically after their password is 218 | # reset. Defaults to true, so a user is signed in automatically after a reset. 219 | # config.sign_in_after_reset_password = true 220 | 221 | # ==> Configuration for :encryptable 222 | # Allow you to use another hashing or encryption algorithm besides bcrypt (default). 223 | # You can use :sha1, :sha512 or algorithms from others authentication tools as 224 | # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 225 | # for default behavior) and :restful_authentication_sha1 (then you should set 226 | # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). 227 | # 228 | # Require the `devise-encryptable` gem when using anything other than bcrypt 229 | # config.encryptor = :sha512 230 | 231 | # ==> Scopes configuration 232 | # Turn scoped views on. Before rendering "sessions/new", it will first check for 233 | # "users/sessions/new". It's turned off by default because it's slower if you 234 | # are using only default views. 235 | # config.scoped_views = false 236 | 237 | # Configure the default scope given to Warden. By default it's the first 238 | # devise role declared in your routes (usually :user). 239 | # config.default_scope = :user 240 | 241 | # Set this configuration to false if you want /users/sign_out to sign out 242 | # only the current scope. By default, Devise signs out all scopes. 243 | # config.sign_out_all_scopes = true 244 | 245 | # ==> Navigation configuration 246 | # Lists the formats that should be treated as navigational. Formats like 247 | # :html, should redirect to the sign in page when the user does not have 248 | # access, but formats like :xml or :json, should return 401. 249 | # 250 | # If you have any extra navigational formats, like :iphone or :mobile, you 251 | # should add them to the navigational formats lists. 252 | # 253 | # The "*/*" below is required to match Internet Explorer requests. 254 | # config.navigational_formats = ['*/*', :html] 255 | 256 | # The default HTTP method used to sign out a resource. Default is :delete. 257 | config.sign_out_via = :delete 258 | 259 | # ==> OmniAuth 260 | # Add a new OmniAuth provider. Check the wiki for more information on setting 261 | # up on your models and hooks. 262 | # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' 263 | 264 | # ==> Warden configuration 265 | # If you want to use other strategies, that are not supported by Devise, or 266 | # change the failure app, you can configure them inside the config.warden block. 267 | # 268 | # config.warden do |manager| 269 | # manager.intercept_401 = false 270 | # manager.default_strategies(scope: :user).unshift :some_external_strategy 271 | # end 272 | 273 | # ==> Mountable engine configurations 274 | # When using Devise inside an engine, let's call it `MyEngine`, and this engine 275 | # is mountable, there are some extra configurations to be taken into account. 276 | # The following options are available, assuming the engine is mounted as: 277 | # 278 | # mount MyEngine, at: '/my_engine' 279 | # 280 | # The router that invoked `devise_for`, in the example above, would be: 281 | # config.router_name = :my_engine 282 | # 283 | # When using OmniAuth, Devise cannot automatically set OmniAuth path, 284 | # so you need to do it manually. For the users scope, it would be: 285 | # config.omniauth_path_prefix = '/my_engine/users/auth' 286 | 287 | # ==> Turbolinks configuration 288 | # If your app is using Turbolinks, Turbolinks::Controller needs to be included to make redirection work correctly: 289 | # 290 | # ActiveSupport.on_load(:devise_failure_app) do 291 | # include Turbolinks::Controller 292 | # end 293 | 294 | # ==> Configuration for :registerable 295 | 296 | # When set to false, does not sign a user in automatically after their password is 297 | # changed. Defaults to true, so a user is signed in automatically after changing a password. 298 | # config.sign_in_after_change_password = true 299 | end 300 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@esbuild/darwin-arm64@0.17.15": 6 | version "0.17.15" 7 | resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz" 8 | integrity sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA== 9 | 10 | "@hotwired/stimulus@^3.2.1": 11 | version "3.2.1" 12 | resolved "https://registry.npmjs.org/@hotwired/stimulus/-/stimulus-3.2.1.tgz" 13 | integrity sha512-HGlzDcf9vv/EQrMJ5ZG6VWNs8Z/xMN+1o2OhV1gKiSG6CqZt5MCBB1gRg5ILiN3U0jEAxuDTNPRfBcnZBDmupQ== 14 | 15 | "@hotwired/turbo-rails@^7.3.0": 16 | version "7.3.0" 17 | resolved "https://registry.npmjs.org/@hotwired/turbo-rails/-/turbo-rails-7.3.0.tgz" 18 | integrity sha512-fvhO64vp/a2UVQ3jue9WTc2JisMv9XilIC7ViZmXAREVwiQ2S4UC7Go8f9A1j4Xu7DBI6SbFdqILk5ImqVoqyA== 19 | dependencies: 20 | "@hotwired/turbo" "^7.3.0" 21 | "@rails/actioncable" "^7.0" 22 | 23 | "@hotwired/turbo@^7.3.0": 24 | version "7.3.0" 25 | resolved "https://registry.npmjs.org/@hotwired/turbo/-/turbo-7.3.0.tgz" 26 | integrity sha512-Dcu+NaSvHLT7EjrDrkEmH4qET2ZJZ5IcCWmNXxNQTBwlnE5tBZfN6WxZ842n5cHV52DH/AKNirbPBtcEXDLW4g== 27 | 28 | "@nodelib/fs.scandir@2.1.5": 29 | version "2.1.5" 30 | resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" 31 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 32 | dependencies: 33 | "@nodelib/fs.stat" "2.0.5" 34 | run-parallel "^1.1.9" 35 | 36 | "@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": 37 | version "2.0.5" 38 | resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" 39 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 40 | 41 | "@nodelib/fs.walk@^1.2.3": 42 | version "1.2.8" 43 | resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" 44 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 45 | dependencies: 46 | "@nodelib/fs.scandir" "2.1.5" 47 | fastq "^1.6.0" 48 | 49 | "@rails/actioncable@^7.0": 50 | version "7.0.4" 51 | resolved "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.0.4.tgz" 52 | integrity sha512-tz4oM+Zn9CYsvtyicsa/AwzKZKL+ITHWkhiu7x+xF77clh2b4Rm+s6xnOgY/sGDWoFWZmtKsE95hxBPkgQQNnQ== 53 | 54 | any-promise@^1.0.0: 55 | version "1.3.0" 56 | resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz" 57 | integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== 58 | 59 | anymatch@~3.1.2: 60 | version "3.1.3" 61 | resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" 62 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 63 | dependencies: 64 | normalize-path "^3.0.0" 65 | picomatch "^2.0.4" 66 | 67 | arg@^5.0.2: 68 | version "5.0.2" 69 | resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" 70 | integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== 71 | 72 | autoprefixer@^10.4.14: 73 | version "10.4.14" 74 | resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz" 75 | integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== 76 | dependencies: 77 | browserslist "^4.21.5" 78 | caniuse-lite "^1.0.30001464" 79 | fraction.js "^4.2.0" 80 | normalize-range "^0.1.2" 81 | picocolors "^1.0.0" 82 | postcss-value-parser "^4.2.0" 83 | 84 | balanced-match@^1.0.0: 85 | version "1.0.2" 86 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" 87 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 88 | 89 | binary-extensions@^2.0.0: 90 | version "2.2.0" 91 | resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" 92 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 93 | 94 | brace-expansion@^1.1.7: 95 | version "1.1.11" 96 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" 97 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 98 | dependencies: 99 | balanced-match "^1.0.0" 100 | concat-map "0.0.1" 101 | 102 | braces@^3.0.2, braces@~3.0.2: 103 | version "3.0.2" 104 | resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" 105 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 106 | dependencies: 107 | fill-range "^7.0.1" 108 | 109 | browserslist@^4.21.5, "browserslist@>= 4.21.0": 110 | version "4.21.5" 111 | resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz" 112 | integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== 113 | dependencies: 114 | caniuse-lite "^1.0.30001449" 115 | electron-to-chromium "^1.4.284" 116 | node-releases "^2.0.8" 117 | update-browserslist-db "^1.0.10" 118 | 119 | camelcase-css@^2.0.1: 120 | version "2.0.1" 121 | resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" 122 | integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== 123 | 124 | caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: 125 | version "1.0.30001473" 126 | resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001473.tgz" 127 | integrity sha512-ewDad7+D2vlyy+E4UJuVfiBsU69IL+8oVmTuZnH5Q6CIUbxNfI50uVpRHbUPDD6SUaN2o0Lh4DhTrvLG/Tn1yg== 128 | 129 | chokidar@^3.5.3: 130 | version "3.5.3" 131 | resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" 132 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 133 | dependencies: 134 | anymatch "~3.1.2" 135 | braces "~3.0.2" 136 | glob-parent "~5.1.2" 137 | is-binary-path "~2.1.0" 138 | is-glob "~4.0.1" 139 | normalize-path "~3.0.0" 140 | readdirp "~3.6.0" 141 | optionalDependencies: 142 | fsevents "~2.3.2" 143 | 144 | color-name@^1.1.4: 145 | version "1.1.4" 146 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" 147 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 148 | 149 | commander@^4.0.0: 150 | version "4.1.1" 151 | resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" 152 | integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== 153 | 154 | concat-map@0.0.1: 155 | version "0.0.1" 156 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" 157 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 158 | 159 | cssesc@^3.0.0: 160 | version "3.0.0" 161 | resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" 162 | integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== 163 | 164 | didyoumean@^1.2.2: 165 | version "1.2.2" 166 | resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" 167 | integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== 168 | 169 | dlv@^1.1.3: 170 | version "1.1.3" 171 | resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" 172 | integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== 173 | 174 | electron-to-chromium@^1.4.284: 175 | version "1.4.348" 176 | resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.348.tgz" 177 | integrity sha512-gM7TdwuG3amns/1rlgxMbeeyNoBFPa+4Uu0c7FeROWh4qWmvSOnvcslKmWy51ggLKZ2n/F/4i2HJ+PVNxH9uCQ== 178 | 179 | esbuild@^0.17.15: 180 | version "0.17.15" 181 | resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz" 182 | integrity sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw== 183 | optionalDependencies: 184 | "@esbuild/android-arm" "0.17.15" 185 | "@esbuild/android-arm64" "0.17.15" 186 | "@esbuild/android-x64" "0.17.15" 187 | "@esbuild/darwin-arm64" "0.17.15" 188 | "@esbuild/darwin-x64" "0.17.15" 189 | "@esbuild/freebsd-arm64" "0.17.15" 190 | "@esbuild/freebsd-x64" "0.17.15" 191 | "@esbuild/linux-arm" "0.17.15" 192 | "@esbuild/linux-arm64" "0.17.15" 193 | "@esbuild/linux-ia32" "0.17.15" 194 | "@esbuild/linux-loong64" "0.17.15" 195 | "@esbuild/linux-mips64el" "0.17.15" 196 | "@esbuild/linux-ppc64" "0.17.15" 197 | "@esbuild/linux-riscv64" "0.17.15" 198 | "@esbuild/linux-s390x" "0.17.15" 199 | "@esbuild/linux-x64" "0.17.15" 200 | "@esbuild/netbsd-x64" "0.17.15" 201 | "@esbuild/openbsd-x64" "0.17.15" 202 | "@esbuild/sunos-x64" "0.17.15" 203 | "@esbuild/win32-arm64" "0.17.15" 204 | "@esbuild/win32-ia32" "0.17.15" 205 | "@esbuild/win32-x64" "0.17.15" 206 | 207 | escalade@^3.1.1: 208 | version "3.1.1" 209 | resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" 210 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 211 | 212 | fast-glob@^3.2.12: 213 | version "3.2.12" 214 | resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" 215 | integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== 216 | dependencies: 217 | "@nodelib/fs.stat" "^2.0.2" 218 | "@nodelib/fs.walk" "^1.2.3" 219 | glob-parent "^5.1.2" 220 | merge2 "^1.3.0" 221 | micromatch "^4.0.4" 222 | 223 | fastq@^1.6.0: 224 | version "1.15.0" 225 | resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" 226 | integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== 227 | dependencies: 228 | reusify "^1.0.4" 229 | 230 | fill-range@^7.0.1: 231 | version "7.0.1" 232 | resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" 233 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 234 | dependencies: 235 | to-regex-range "^5.0.1" 236 | 237 | fraction.js@^4.2.0: 238 | version "4.2.0" 239 | resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" 240 | integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== 241 | 242 | fs.realpath@^1.0.0: 243 | version "1.0.0" 244 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" 245 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 246 | 247 | fsevents@~2.3.2: 248 | version "2.3.2" 249 | resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" 250 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 251 | 252 | function-bind@^1.1.1: 253 | version "1.1.1" 254 | resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" 255 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 256 | 257 | glob-parent@^5.1.2: 258 | version "5.1.2" 259 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" 260 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 261 | dependencies: 262 | is-glob "^4.0.1" 263 | 264 | glob-parent@^6.0.2: 265 | version "6.0.2" 266 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" 267 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== 268 | dependencies: 269 | is-glob "^4.0.3" 270 | 271 | glob-parent@~5.1.2: 272 | version "5.1.2" 273 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" 274 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 275 | dependencies: 276 | is-glob "^4.0.1" 277 | 278 | glob@7.1.6: 279 | version "7.1.6" 280 | resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" 281 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 282 | dependencies: 283 | fs.realpath "^1.0.0" 284 | inflight "^1.0.4" 285 | inherits "2" 286 | minimatch "^3.0.4" 287 | once "^1.3.0" 288 | path-is-absolute "^1.0.0" 289 | 290 | has@^1.0.3: 291 | version "1.0.3" 292 | resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" 293 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 294 | dependencies: 295 | function-bind "^1.1.1" 296 | 297 | inflight@^1.0.4: 298 | version "1.0.6" 299 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" 300 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 301 | dependencies: 302 | once "^1.3.0" 303 | wrappy "1" 304 | 305 | inherits@2: 306 | version "2.0.4" 307 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 308 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 309 | 310 | is-binary-path@~2.1.0: 311 | version "2.1.0" 312 | resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" 313 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 314 | dependencies: 315 | binary-extensions "^2.0.0" 316 | 317 | is-core-module@^2.9.0: 318 | version "2.11.0" 319 | resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz" 320 | integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== 321 | dependencies: 322 | has "^1.0.3" 323 | 324 | is-extglob@^2.1.1: 325 | version "2.1.1" 326 | resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" 327 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 328 | 329 | is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: 330 | version "4.0.3" 331 | resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" 332 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 333 | dependencies: 334 | is-extglob "^2.1.1" 335 | 336 | is-number@^7.0.0: 337 | version "7.0.0" 338 | resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" 339 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 340 | 341 | jiti@^1.17.2: 342 | version "1.18.2" 343 | resolved "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz" 344 | integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== 345 | 346 | lilconfig@^2.0.5, lilconfig@^2.0.6: 347 | version "2.1.0" 348 | resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" 349 | integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== 350 | 351 | lines-and-columns@^1.1.6: 352 | version "1.2.4" 353 | resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" 354 | integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== 355 | 356 | merge2@^1.3.0: 357 | version "1.4.1" 358 | resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" 359 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 360 | 361 | micromatch@^4.0.4, micromatch@^4.0.5: 362 | version "4.0.5" 363 | resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" 364 | integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== 365 | dependencies: 366 | braces "^3.0.2" 367 | picomatch "^2.3.1" 368 | 369 | minimatch@^3.0.4: 370 | version "3.1.2" 371 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" 372 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 373 | dependencies: 374 | brace-expansion "^1.1.7" 375 | 376 | mz@^2.7.0: 377 | version "2.7.0" 378 | resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz" 379 | integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== 380 | dependencies: 381 | any-promise "^1.0.0" 382 | object-assign "^4.0.1" 383 | thenify-all "^1.0.0" 384 | 385 | nanoid@^3.3.4: 386 | version "3.3.6" 387 | resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" 388 | integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== 389 | 390 | node-releases@^2.0.8: 391 | version "2.0.10" 392 | resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz" 393 | integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== 394 | 395 | normalize-path@^3.0.0, normalize-path@~3.0.0: 396 | version "3.0.0" 397 | resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" 398 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 399 | 400 | normalize-range@^0.1.2: 401 | version "0.1.2" 402 | resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" 403 | integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== 404 | 405 | object-assign@^4.0.1: 406 | version "4.1.1" 407 | resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" 408 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 409 | 410 | object-hash@^3.0.0: 411 | version "3.0.0" 412 | resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" 413 | integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== 414 | 415 | once@^1.3.0: 416 | version "1.4.0" 417 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 418 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 419 | dependencies: 420 | wrappy "1" 421 | 422 | path-is-absolute@^1.0.0: 423 | version "1.0.1" 424 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" 425 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 426 | 427 | path-parse@^1.0.7: 428 | version "1.0.7" 429 | resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" 430 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 431 | 432 | picocolors@^1.0.0: 433 | version "1.0.0" 434 | resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" 435 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 436 | 437 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: 438 | version "2.3.1" 439 | resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" 440 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 441 | 442 | pify@^2.3.0: 443 | version "2.3.0" 444 | resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" 445 | integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== 446 | 447 | pirates@^4.0.1: 448 | version "4.0.5" 449 | resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz" 450 | integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== 451 | 452 | postcss-import@^14.1.0: 453 | version "14.1.0" 454 | resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz" 455 | integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== 456 | dependencies: 457 | postcss-value-parser "^4.0.0" 458 | read-cache "^1.0.0" 459 | resolve "^1.1.7" 460 | 461 | postcss-js@^4.0.0: 462 | version "4.0.1" 463 | resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz" 464 | integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== 465 | dependencies: 466 | camelcase-css "^2.0.1" 467 | 468 | postcss-load-config@^3.1.4: 469 | version "3.1.4" 470 | resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz" 471 | integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== 472 | dependencies: 473 | lilconfig "^2.0.5" 474 | yaml "^1.10.2" 475 | 476 | postcss-nested@6.0.0: 477 | version "6.0.0" 478 | resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz" 479 | integrity sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w== 480 | dependencies: 481 | postcss-selector-parser "^6.0.10" 482 | 483 | postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11: 484 | version "6.0.11" 485 | resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz" 486 | integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== 487 | dependencies: 488 | cssesc "^3.0.0" 489 | util-deprecate "^1.0.2" 490 | 491 | postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: 492 | version "4.2.0" 493 | resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" 494 | integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== 495 | 496 | postcss@^8.0.0, postcss@^8.0.9, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@>=8.0.9: 497 | version "8.4.21" 498 | resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz" 499 | integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== 500 | dependencies: 501 | nanoid "^3.3.4" 502 | picocolors "^1.0.0" 503 | source-map-js "^1.0.2" 504 | 505 | queue-microtask@^1.2.2: 506 | version "1.2.3" 507 | resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" 508 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 509 | 510 | quick-lru@^5.1.1: 511 | version "5.1.1" 512 | resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" 513 | integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== 514 | 515 | read-cache@^1.0.0: 516 | version "1.0.0" 517 | resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" 518 | integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== 519 | dependencies: 520 | pify "^2.3.0" 521 | 522 | readdirp@~3.6.0: 523 | version "3.6.0" 524 | resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" 525 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 526 | dependencies: 527 | picomatch "^2.2.1" 528 | 529 | resolve@^1.1.7, resolve@^1.22.1: 530 | version "1.22.1" 531 | resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" 532 | integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== 533 | dependencies: 534 | is-core-module "^2.9.0" 535 | path-parse "^1.0.7" 536 | supports-preserve-symlinks-flag "^1.0.0" 537 | 538 | reusify@^1.0.4: 539 | version "1.0.4" 540 | resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" 541 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 542 | 543 | run-parallel@^1.1.9: 544 | version "1.2.0" 545 | resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" 546 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 547 | dependencies: 548 | queue-microtask "^1.2.2" 549 | 550 | source-map-js@^1.0.2: 551 | version "1.0.2" 552 | resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" 553 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== 554 | 555 | sucrase@^3.29.0: 556 | version "3.31.0" 557 | resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.31.0.tgz" 558 | integrity sha512-6QsHnkqyVEzYcaiHsOKkzOtOgdJcb8i54x6AV2hDwyZcY9ZyykGZVw6L/YN98xC0evwTP6utsWWrKRaa8QlfEQ== 559 | dependencies: 560 | commander "^4.0.0" 561 | glob "7.1.6" 562 | lines-and-columns "^1.1.6" 563 | mz "^2.7.0" 564 | pirates "^4.0.1" 565 | ts-interface-checker "^0.1.9" 566 | 567 | supports-preserve-symlinks-flag@^1.0.0: 568 | version "1.0.0" 569 | resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" 570 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 571 | 572 | tailwindcss@^3.3.1: 573 | version "3.3.1" 574 | resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz" 575 | integrity sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g== 576 | dependencies: 577 | arg "^5.0.2" 578 | chokidar "^3.5.3" 579 | color-name "^1.1.4" 580 | didyoumean "^1.2.2" 581 | dlv "^1.1.3" 582 | fast-glob "^3.2.12" 583 | glob-parent "^6.0.2" 584 | is-glob "^4.0.3" 585 | jiti "^1.17.2" 586 | lilconfig "^2.0.6" 587 | micromatch "^4.0.5" 588 | normalize-path "^3.0.0" 589 | object-hash "^3.0.0" 590 | picocolors "^1.0.0" 591 | postcss "^8.0.9" 592 | postcss-import "^14.1.0" 593 | postcss-js "^4.0.0" 594 | postcss-load-config "^3.1.4" 595 | postcss-nested "6.0.0" 596 | postcss-selector-parser "^6.0.11" 597 | postcss-value-parser "^4.2.0" 598 | quick-lru "^5.1.1" 599 | resolve "^1.22.1" 600 | sucrase "^3.29.0" 601 | 602 | thenify-all@^1.0.0: 603 | version "1.6.0" 604 | resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz" 605 | integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== 606 | dependencies: 607 | thenify ">= 3.1.0 < 4" 608 | 609 | "thenify@>= 3.1.0 < 4": 610 | version "3.3.1" 611 | resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz" 612 | integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== 613 | dependencies: 614 | any-promise "^1.0.0" 615 | 616 | to-regex-range@^5.0.1: 617 | version "5.0.1" 618 | resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" 619 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 620 | dependencies: 621 | is-number "^7.0.0" 622 | 623 | ts-interface-checker@^0.1.9: 624 | version "0.1.13" 625 | resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" 626 | integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== 627 | 628 | update-browserslist-db@^1.0.10: 629 | version "1.0.10" 630 | resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz" 631 | integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== 632 | dependencies: 633 | escalade "^3.1.1" 634 | picocolors "^1.0.0" 635 | 636 | util-deprecate@^1.0.2: 637 | version "1.0.2" 638 | resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" 639 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 640 | 641 | wrappy@1: 642 | version "1.0.2" 643 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 644 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 645 | 646 | yaml@^1.10.2: 647 | version "1.10.2" 648 | resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" 649 | integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== 650 | --------------------------------------------------------------------------------