├── .gitignore
├── .rubocop.yml
├── .tool-versions
├── CHANGELOG.md
├── Gemfile
├── Gemfile.lock
├── MIT-LICENSE
├── Procfile.dev
├── README.md
├── Rakefile
├── app
├── assets
│ ├── config
│ │ └── deployed_manifest.js
│ ├── images
│ │ └── deployed
│ │ │ └── .keep
│ ├── javascripts
│ │ └── deployed
│ │ │ └── application.js
│ └── stylesheets
│ │ └── deployed
│ │ ├── deployed.css
│ │ └── src
│ │ └── input.css
├── controllers
│ ├── concerns
│ │ └── .keep
│ └── deployed
│ │ ├── application_controller.rb
│ │ ├── config_controller.rb
│ │ ├── git_controller.rb
│ │ ├── log_output_controller.rb
│ │ ├── run_controller.rb
│ │ ├── setup_controller.rb
│ │ └── welcome_controller.rb
├── helpers
│ └── deployed
│ │ ├── application_helper.rb
│ │ └── log_output_helper.rb
├── models
│ ├── concerns
│ │ └── .keep
│ └── deployed
│ │ ├── config.rb
│ │ └── current_execution.rb
└── views
│ ├── deployed
│ ├── git
│ │ └── uncommitted_check.html.erb
│ ├── setup
│ │ └── new.html.erb
│ └── welcome
│ │ └── index.html.erb
│ └── layouts
│ └── deployed
│ └── application.html.erb
├── bin
├── dev
├── rails
└── setup
├── config
└── routes.rb
├── deployed.gemspec
├── lib
├── deployed.rb
├── deployed
│ ├── engine.rb
│ └── version.rb
└── tasks
│ └── deployed_tasks.rake
├── package-lock.json
├── package.json
├── tailwind.config.js
└── test
├── controllers
└── .keep
├── dummy
├── Rakefile
├── app
│ ├── assets
│ │ ├── config
│ │ │ └── manifest.js
│ │ ├── images
│ │ │ └── .keep
│ │ └── stylesheets
│ │ │ └── application.css
│ ├── channels
│ │ └── application_cable
│ │ │ ├── channel.rb
│ │ │ └── connection.rb
│ ├── controllers
│ │ ├── application_controller.rb
│ │ └── concerns
│ │ │ └── .keep
│ ├── helpers
│ │ └── application_helper.rb
│ ├── jobs
│ │ └── application_job.rb
│ ├── mailers
│ │ └── application_mailer.rb
│ ├── models
│ │ ├── application_record.rb
│ │ └── concerns
│ │ │ └── .keep
│ └── views
│ │ └── layouts
│ │ ├── application.html.erb
│ │ ├── mailer.html.erb
│ │ └── mailer.text.erb
├── bin
│ ├── rails
│ ├── rake
│ └── setup
├── config.ru
├── config
│ ├── application.rb
│ ├── boot.rb
│ ├── cable.yml
│ ├── database.yml
│ ├── environment.rb
│ ├── environments
│ │ ├── development.rb
│ │ ├── production.rb
│ │ └── test.rb
│ ├── initializers
│ │ ├── assets.rb
│ │ ├── content_security_policy.rb
│ │ ├── filter_parameter_logging.rb
│ │ ├── inflections.rb
│ │ └── permissions_policy.rb
│ ├── locales
│ │ └── en.yml
│ ├── puma.rb
│ ├── routes.rb
│ ├── storage.yml
│ └── tailwind.config.js
├── lib
│ └── assets
│ │ └── .keep
├── log
│ └── .keep
└── public
│ ├── 404.html
│ ├── 422.html
│ ├── 500.html
│ ├── apple-touch-icon-precomposed.png
│ ├── apple-touch-icon.png
│ └── favicon.ico
├── fixtures
└── files
│ └── .keep
├── helpers
└── .keep
├── integration
├── .keep
└── navigation_test.rb
├── kamal_rails_test.rb
├── mailers
└── .keep
├── models
└── .keep
└── test_helper.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | /.bundle/
2 | /doc/
3 | /log/*.log
4 | /pkg/
5 | /tmp/
6 | /test/dummy/db/*.sqlite3
7 | /test/dummy/db/*.sqlite3-*
8 | /test/dummy/log/*.log
9 | /test/dummy/storage/
10 | /test/dummy/tmp/
11 | /test/dummy/.env
12 | /test/dummy/.deployed
13 | /test/dummy/config/deploy.yml
14 | /node_modules/**/*
15 | .DS_Store
16 |
--------------------------------------------------------------------------------
/.rubocop.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/.rubocop.yml
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | nodejs 18.18.2
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 | All notable changes to this project will be documented in this file.
3 |
4 | The format is based on [Keep a Changelog](http://keepachangelog.com/)
5 | and this project adheres to [Semantic Versioning](http://semver.org/).
6 |
7 | ## [0.1.3] October 26, 2023
8 |
9 | ### Changed
10 | - The way log output is generated and piped to the browser
11 | - Log persists if the user reloads the dashboard while process is still running
12 |
13 | ## [0.1.0 to 0.1.2]
14 |
15 | Initial release(s)
16 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 | git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5 |
6 | # Specify your gem's dependencies in deployed.gemspec.
7 | gemspec
8 |
9 | gem 'turbo-rails', '~> 1.5'
10 | gem 'puma'
11 | gem 'rubocop'
12 | gem 'sprockets-rails'
13 | gem 'sqlite3'
14 | gem 'kamal'
15 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | deployed (0.1.2)
5 | kamal (~> 1.0)
6 | rails (>= 7.1.1)
7 | turbo-rails (~> 1.5)
8 |
9 | GEM
10 | remote: https://rubygems.org/
11 | specs:
12 | actioncable (7.1.1)
13 | actionpack (= 7.1.1)
14 | activesupport (= 7.1.1)
15 | nio4r (~> 2.0)
16 | websocket-driver (>= 0.6.1)
17 | zeitwerk (~> 2.6)
18 | actionmailbox (7.1.1)
19 | actionpack (= 7.1.1)
20 | activejob (= 7.1.1)
21 | activerecord (= 7.1.1)
22 | activestorage (= 7.1.1)
23 | activesupport (= 7.1.1)
24 | mail (>= 2.7.1)
25 | net-imap
26 | net-pop
27 | net-smtp
28 | actionmailer (7.1.1)
29 | actionpack (= 7.1.1)
30 | actionview (= 7.1.1)
31 | activejob (= 7.1.1)
32 | activesupport (= 7.1.1)
33 | mail (~> 2.5, >= 2.5.4)
34 | net-imap
35 | net-pop
36 | net-smtp
37 | rails-dom-testing (~> 2.2)
38 | actionpack (7.1.1)
39 | actionview (= 7.1.1)
40 | activesupport (= 7.1.1)
41 | nokogiri (>= 1.8.5)
42 | rack (>= 2.2.4)
43 | rack-session (>= 1.0.1)
44 | rack-test (>= 0.6.3)
45 | rails-dom-testing (~> 2.2)
46 | rails-html-sanitizer (~> 1.6)
47 | actiontext (7.1.1)
48 | actionpack (= 7.1.1)
49 | activerecord (= 7.1.1)
50 | activestorage (= 7.1.1)
51 | activesupport (= 7.1.1)
52 | globalid (>= 0.6.0)
53 | nokogiri (>= 1.8.5)
54 | actionview (7.1.1)
55 | activesupport (= 7.1.1)
56 | builder (~> 3.1)
57 | erubi (~> 1.11)
58 | rails-dom-testing (~> 2.2)
59 | rails-html-sanitizer (~> 1.6)
60 | activejob (7.1.1)
61 | activesupport (= 7.1.1)
62 | globalid (>= 0.3.6)
63 | activemodel (7.1.1)
64 | activesupport (= 7.1.1)
65 | activerecord (7.1.1)
66 | activemodel (= 7.1.1)
67 | activesupport (= 7.1.1)
68 | timeout (>= 0.4.0)
69 | activestorage (7.1.1)
70 | actionpack (= 7.1.1)
71 | activejob (= 7.1.1)
72 | activerecord (= 7.1.1)
73 | activesupport (= 7.1.1)
74 | marcel (~> 1.0)
75 | activesupport (7.1.1)
76 | base64
77 | bigdecimal
78 | concurrent-ruby (~> 1.0, >= 1.0.2)
79 | connection_pool (>= 2.2.5)
80 | drb
81 | i18n (>= 1.6, < 2)
82 | minitest (>= 5.1)
83 | mutex_m
84 | tzinfo (~> 2.0)
85 | ast (2.4.2)
86 | base64 (0.1.1)
87 | bcrypt_pbkdf (1.1.0)
88 | bigdecimal (3.1.4)
89 | builder (3.2.4)
90 | concurrent-ruby (1.2.2)
91 | connection_pool (2.4.1)
92 | crass (1.0.6)
93 | date (3.3.3)
94 | dotenv (2.8.1)
95 | drb (2.1.1)
96 | ruby2_keywords
97 | ed25519 (1.3.0)
98 | erubi (1.12.0)
99 | globalid (1.2.1)
100 | activesupport (>= 6.1)
101 | i18n (1.14.1)
102 | concurrent-ruby (~> 1.0)
103 | io-console (0.6.0)
104 | irb (1.8.3)
105 | rdoc
106 | reline (>= 0.3.8)
107 | json (2.6.3)
108 | kamal (1.0.0)
109 | activesupport (>= 7.0)
110 | bcrypt_pbkdf (~> 1.0)
111 | concurrent-ruby (~> 1.2)
112 | dotenv (~> 2.8)
113 | ed25519 (~> 1.2)
114 | net-ssh (~> 7.0)
115 | sshkit (~> 1.21)
116 | thor (~> 1.2)
117 | zeitwerk (~> 2.5)
118 | language_server-protocol (3.17.0.3)
119 | loofah (2.21.4)
120 | crass (~> 1.0.2)
121 | nokogiri (>= 1.12.0)
122 | mail (2.8.1)
123 | mini_mime (>= 0.1.1)
124 | net-imap
125 | net-pop
126 | net-smtp
127 | marcel (1.0.2)
128 | mini_mime (1.1.5)
129 | minitest (5.20.0)
130 | mutex_m (0.1.2)
131 | net-imap (0.4.1)
132 | date
133 | net-protocol
134 | net-pop (0.1.2)
135 | net-protocol
136 | net-protocol (0.2.1)
137 | timeout
138 | net-scp (4.0.0)
139 | net-ssh (>= 2.6.5, < 8.0.0)
140 | net-smtp (0.4.0)
141 | net-protocol
142 | net-ssh (7.2.0)
143 | nio4r (2.5.9)
144 | nokogiri (1.15.4-arm64-darwin)
145 | racc (~> 1.4)
146 | nokogiri (1.15.4-x86_64-linux)
147 | racc (~> 1.4)
148 | parallel (1.23.0)
149 | parser (3.2.2.4)
150 | ast (~> 2.4.1)
151 | racc
152 | psych (5.1.1.1)
153 | stringio
154 | puma (6.4.0)
155 | nio4r (~> 2.0)
156 | racc (1.7.1)
157 | rack (3.0.8)
158 | rack-session (2.0.0)
159 | rack (>= 3.0.0)
160 | rack-test (2.1.0)
161 | rack (>= 1.3)
162 | rackup (2.1.0)
163 | rack (>= 3)
164 | webrick (~> 1.8)
165 | rails (7.1.1)
166 | actioncable (= 7.1.1)
167 | actionmailbox (= 7.1.1)
168 | actionmailer (= 7.1.1)
169 | actionpack (= 7.1.1)
170 | actiontext (= 7.1.1)
171 | actionview (= 7.1.1)
172 | activejob (= 7.1.1)
173 | activemodel (= 7.1.1)
174 | activerecord (= 7.1.1)
175 | activestorage (= 7.1.1)
176 | activesupport (= 7.1.1)
177 | bundler (>= 1.15.0)
178 | railties (= 7.1.1)
179 | rails-dom-testing (2.2.0)
180 | activesupport (>= 5.0.0)
181 | minitest
182 | nokogiri (>= 1.6)
183 | rails-html-sanitizer (1.6.0)
184 | loofah (~> 2.21)
185 | nokogiri (~> 1.14)
186 | railties (7.1.1)
187 | actionpack (= 7.1.1)
188 | activesupport (= 7.1.1)
189 | irb
190 | rackup (>= 1.0.0)
191 | rake (>= 12.2)
192 | thor (~> 1.0, >= 1.2.2)
193 | zeitwerk (~> 2.6)
194 | rainbow (3.1.1)
195 | rake (13.0.6)
196 | rdoc (6.5.0)
197 | psych (>= 4.0.0)
198 | regexp_parser (2.8.2)
199 | reline (0.3.9)
200 | io-console (~> 0.5)
201 | rexml (3.2.6)
202 | rubocop (1.57.1)
203 | base64 (~> 0.1.1)
204 | json (~> 2.3)
205 | language_server-protocol (>= 3.17.0)
206 | parallel (~> 1.10)
207 | parser (>= 3.2.2.4)
208 | rainbow (>= 2.2.2, < 4.0)
209 | regexp_parser (>= 1.8, < 3.0)
210 | rexml (>= 3.2.5, < 4.0)
211 | rubocop-ast (>= 1.28.1, < 2.0)
212 | ruby-progressbar (~> 1.7)
213 | unicode-display_width (>= 2.4.0, < 3.0)
214 | rubocop-ast (1.29.0)
215 | parser (>= 3.2.1.0)
216 | ruby-progressbar (1.13.0)
217 | ruby2_keywords (0.0.5)
218 | sprockets (4.2.1)
219 | concurrent-ruby (~> 1.0)
220 | rack (>= 2.2.4, < 4)
221 | sprockets-rails (3.4.2)
222 | actionpack (>= 5.2)
223 | activesupport (>= 5.2)
224 | sprockets (>= 3.0.0)
225 | sqlite3 (1.6.7-arm64-darwin)
226 | sqlite3 (1.6.7-x86_64-linux)
227 | sshkit (1.21.5)
228 | net-scp (>= 1.1.2)
229 | net-ssh (>= 2.8.0)
230 | stringio (3.0.8)
231 | thor (1.3.0)
232 | timeout (0.4.0)
233 | turbo-rails (1.5.0)
234 | actionpack (>= 6.0.0)
235 | activejob (>= 6.0.0)
236 | railties (>= 6.0.0)
237 | tzinfo (2.0.6)
238 | concurrent-ruby (~> 1.0)
239 | unicode-display_width (2.5.0)
240 | webrick (1.8.1)
241 | websocket-driver (0.7.6)
242 | websocket-extensions (>= 0.1.0)
243 | websocket-extensions (0.1.5)
244 | zeitwerk (2.6.12)
245 |
246 | PLATFORMS
247 | arm64-darwin-23
248 | x86_64-linux
249 |
250 | DEPENDENCIES
251 | deployed!
252 | kamal
253 | puma
254 | rubocop
255 | sprockets-rails
256 | sqlite3
257 | turbo-rails (~> 1.5)
258 |
259 | BUNDLED WITH
260 | 2.4.20
261 |
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | 2023 Copyright Simon Chiu
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/Procfile.dev:
--------------------------------------------------------------------------------
1 | tailwind: npx tailwindcss -i ./app/assets/stylesheets/deployed/src/input.css -o ./app/assets/stylesheets/deployed/deployed.css --watch
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Deployed
2 |
3 | [](https://badge.fury.io/rb/deployed)
4 |
5 | Deployed is a web interface for the deployment library, [Kamal](https://kamal-deploy.org).
6 |
7 | Here is a quick video demo: https://x.com/geetfun/status/1716109581619744781?s=20
8 |
9 | ## Requirements
10 |
11 | Ruby on Rails
12 |
13 | ## Installation
14 | Add this line to your application's Gemfile:
15 |
16 | ```ruby
17 | group :development do
18 | gem 'kamal'
19 | gem 'deployed'
20 | end
21 | ```
22 |
23 | ## Usage
24 |
25 | Add the following to your app's routes file:
26 |
27 | ```ruby
28 | Rails.application.routes.draw do
29 | if Rails.env.development? && defined?(Deployed)
30 | mount(Deployed::Engine => '/deployed')
31 | end
32 |
33 | # Your other routes...
34 | end
35 | ```
36 |
37 | Next, head to `http://localhost:3000/deployed`
38 |
39 | ## Development
40 |
41 | Run `bin/setup` to bootstrap the development environment.
42 |
43 | To run tests: `bundle exec rake app:test`. Currently there are no tests, but some will be added soon.
44 |
45 | ## License
46 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
47 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require "bundler/setup"
2 |
3 | APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4 | load "rails/tasks/engine.rake"
5 |
6 | load "rails/tasks/statistics.rake"
7 |
8 | require "bundler/gem_tasks"
9 |
--------------------------------------------------------------------------------
/app/assets/config/deployed_manifest.js:
--------------------------------------------------------------------------------
1 | //= link_directory ../stylesheets/deployed .css
2 |
--------------------------------------------------------------------------------
/app/assets/images/deployed/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/app/assets/images/deployed/.keep
--------------------------------------------------------------------------------
/app/assets/javascripts/deployed/application.js:
--------------------------------------------------------------------------------
1 | import 'https://cdn.skypack.dev/@hotwired/turbo-rails'
2 | import 'https://cdn.skypack.dev/alpine-turbo-drive-adapter'
3 | import Alpine from 'https://cdn.skypack.dev/alpinejs'
4 | window.Alpine = Alpine
5 | Alpine.start()
6 |
7 | const endMarker = '[Deployed Rails] End'
8 | const outputContainerEl = document.getElementById('deploy-output')
9 | const spinnerEl = document.getElementById('spinner')
10 |
11 | window.pipeLogs = () => {
12 | spinnerEl.classList.remove('hidden')
13 | window.logEventSource = new EventSource(`/deployed/log_output`)
14 |
15 | window.logEventSource.onmessage = (event) => {
16 | if (!Alpine.store('process').running) {
17 | window.logEventSource.close()
18 | } else {
19 | if (event.data.includes("[Deployed] End")) {
20 | window.stopPipeLogs()
21 | } else {
22 | outputContainerEl.innerHTML += event.data
23 | }
24 | }
25 |
26 | outputContainerEl.scrollIntoView({ behavior: "smooth", block: "end" })
27 | spinnerEl.scrollIntoView({ behavior: "smooth", block: "end" })
28 | }
29 | }
30 |
31 | window.stopPipeLogs = () => {
32 | if (typeof(window.logEventSource) !== 'undefined') {
33 | window.logEventSource.close()
34 | }
35 | spinnerEl.classList.add('hidden')
36 | Alpine.store('process').stop()
37 | }
38 |
39 | window.execDeployed = (commandToRun) => {
40 | Alpine.store('process').start()
41 |
42 | let endpoint = `/deployed/execute`
43 |
44 | // Create a data object with your payload (in this case, a command)
45 | const data = { command: commandToRun }
46 |
47 | // Define the fetch options for the POST request
48 | const options = {
49 | method: 'POST',
50 | headers: { 'Content-Type': 'application/json' },
51 | body: JSON.stringify(data)
52 | }
53 |
54 | // Perform the POST request using the fetch API
55 | fetch(endpoint, options)
56 | .then(response => {
57 | if (response.ok) {
58 | outputContainerEl.innerHTML += "
"
59 | outputContainerEl.innerHTML += `[Deployed] Command Received: kamal ${commandToRun}
`
60 | window.pipeLogs()
61 | return response.json(); // Parse the JSON response if needed
62 | } else {
63 | throw new Error('Network response was not ok');
64 | }
65 | })
66 | .catch(error => {
67 | console.error('Fetch error:', error)
68 | })
69 | }
70 |
71 | window.abortDeployed = () => {
72 | // Let the frontend know we're starting
73 | Alpine.store('process').startAbort()
74 |
75 | let outputContainerEl = document.getElementById('deploy-output')
76 | let spinnerEl = document.getElementById('spinner')
77 |
78 | outputContainerEl.innerHTML += `Aborting...
`
79 |
80 | let endpoint = `/deployed/cancel`
81 |
82 | const options = {
83 | method: 'POST',
84 | headers: { 'Content-Type': 'application/json' }
85 | }
86 |
87 | // Perform the POST request using the fetch API
88 | fetch(endpoint, options)
89 | .then(response => {
90 | if (response.ok) {
91 | window.stopPipeLogs()
92 | Alpine.store('process').stop()
93 | Alpine.store('process').resetAbort()
94 | return response.json(); // Parse the JSON response if needed
95 | } else {
96 | throw new Error('Network response was not ok');
97 | }
98 | })
99 | .then(data => {
100 | console.log(data)
101 | outputContainerEl.innerHTML += `Aborted process with PID ${data.message}
`
102 | })
103 | .catch(error => {
104 | console.error('Fetch error:', error)
105 | })
106 | }
107 |
108 | // Some other JS that probably should be refactored at some point...
109 | document.addEventListener('DOMContentLoaded', (event) => {
110 | // Hackish way to refresh git status with turbo frames
111 | // setInterval(() => {
112 | // document.getElementById('git-status').reload()
113 | // }, 2500)
114 |
115 | // Resizing functionality
116 | let isResizing = false
117 | let initialY
118 | let initialHeight
119 |
120 | const deployOutputContainer = document.getElementById('deploy-output-container')
121 | const resizeHandle = document.getElementById('resize-handle')
122 |
123 | const startResize = (e) => {
124 | isResizing = true
125 | initialY = e.clientY
126 | initialHeight = deployOutputContainer.clientHeight
127 | }
128 |
129 | const stopResize = () => { isResizing = false }
130 |
131 | const resize = (e) => {
132 | if (isResizing) {
133 | const deltaY = initialY - e.clientY
134 | deployOutputContainer.style.height = initialHeight + deltaY + 'px'
135 | }
136 | }
137 |
138 | resizeHandle.addEventListener('mousedown', startResize)
139 | document.addEventListener('mousemove', resize)
140 | document.addEventListener('mouseup', stopResize)
141 | })
142 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/deployed/deployed.css:
--------------------------------------------------------------------------------
1 | /*
2 | ! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com
3 | */
4 |
5 | /*
6 | 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
7 | 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
8 | */
9 |
10 | *,
11 | ::before,
12 | ::after {
13 | box-sizing: border-box;
14 | /* 1 */
15 | border-width: 0;
16 | /* 2 */
17 | border-style: solid;
18 | /* 2 */
19 | border-color: #e5e7eb;
20 | /* 2 */
21 | }
22 |
23 | ::before,
24 | ::after {
25 | --tw-content: '';
26 | }
27 |
28 | /*
29 | 1. Use a consistent sensible line-height in all browsers.
30 | 2. Prevent adjustments of font size after orientation changes in iOS.
31 | 3. Use a more readable tab size.
32 | 4. Use the user's configured `sans` font-family by default.
33 | 5. Use the user's configured `sans` font-feature-settings by default.
34 | 6. Use the user's configured `sans` font-variation-settings by default.
35 | */
36 |
37 | html {
38 | line-height: 1.5;
39 | /* 1 */
40 | -webkit-text-size-adjust: 100%;
41 | /* 2 */
42 | -moz-tab-size: 4;
43 | /* 3 */
44 | -o-tab-size: 4;
45 | tab-size: 4;
46 | /* 3 */
47 | font-family: Inter var, 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";
48 | /* 4 */
49 | font-feature-settings: normal;
50 | /* 5 */
51 | font-variation-settings: normal;
52 | /* 6 */
53 | }
54 |
55 | /*
56 | 1. Remove the margin in all browsers.
57 | 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
58 | */
59 |
60 | body {
61 | margin: 0;
62 | /* 1 */
63 | line-height: inherit;
64 | /* 2 */
65 | }
66 |
67 | /*
68 | 1. Add the correct height in Firefox.
69 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
70 | 3. Ensure horizontal rules are visible by default.
71 | */
72 |
73 | hr {
74 | height: 0;
75 | /* 1 */
76 | color: inherit;
77 | /* 2 */
78 | border-top-width: 1px;
79 | /* 3 */
80 | }
81 |
82 | /*
83 | Add the correct text decoration in Chrome, Edge, and Safari.
84 | */
85 |
86 | abbr:where([title]) {
87 | -webkit-text-decoration: underline dotted;
88 | text-decoration: underline dotted;
89 | }
90 |
91 | /*
92 | Remove the default font size and weight for headings.
93 | */
94 |
95 | h1,
96 | h2,
97 | h3,
98 | h4,
99 | h5,
100 | h6 {
101 | font-size: inherit;
102 | font-weight: inherit;
103 | }
104 |
105 | /*
106 | Reset links to optimize for opt-in styling instead of opt-out.
107 | */
108 |
109 | a {
110 | color: inherit;
111 | text-decoration: inherit;
112 | }
113 |
114 | /*
115 | Add the correct font weight in Edge and Safari.
116 | */
117 |
118 | b,
119 | strong {
120 | font-weight: bolder;
121 | }
122 |
123 | /*
124 | 1. Use the user's configured `mono` font family by default.
125 | 2. Correct the odd `em` font sizing in all browsers.
126 | */
127 |
128 | code,
129 | kbd,
130 | samp,
131 | pre {
132 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
133 | /* 1 */
134 | font-size: 1em;
135 | /* 2 */
136 | }
137 |
138 | /*
139 | Add the correct font size in all browsers.
140 | */
141 |
142 | small {
143 | font-size: 80%;
144 | }
145 |
146 | /*
147 | Prevent `sub` and `sup` elements from affecting the line height in all browsers.
148 | */
149 |
150 | sub,
151 | sup {
152 | font-size: 75%;
153 | line-height: 0;
154 | position: relative;
155 | vertical-align: baseline;
156 | }
157 |
158 | sub {
159 | bottom: -0.25em;
160 | }
161 |
162 | sup {
163 | top: -0.5em;
164 | }
165 |
166 | /*
167 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
168 | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
169 | 3. Remove gaps between table borders by default.
170 | */
171 |
172 | table {
173 | text-indent: 0;
174 | /* 1 */
175 | border-color: inherit;
176 | /* 2 */
177 | border-collapse: collapse;
178 | /* 3 */
179 | }
180 |
181 | /*
182 | 1. Change the font styles in all browsers.
183 | 2. Remove the margin in Firefox and Safari.
184 | 3. Remove default padding in all browsers.
185 | */
186 |
187 | button,
188 | input,
189 | optgroup,
190 | select,
191 | textarea {
192 | font-family: inherit;
193 | /* 1 */
194 | font-feature-settings: inherit;
195 | /* 1 */
196 | font-variation-settings: inherit;
197 | /* 1 */
198 | font-size: 100%;
199 | /* 1 */
200 | font-weight: inherit;
201 | /* 1 */
202 | line-height: inherit;
203 | /* 1 */
204 | color: inherit;
205 | /* 1 */
206 | margin: 0;
207 | /* 2 */
208 | padding: 0;
209 | /* 3 */
210 | }
211 |
212 | /*
213 | Remove the inheritance of text transform in Edge and Firefox.
214 | */
215 |
216 | button,
217 | select {
218 | text-transform: none;
219 | }
220 |
221 | /*
222 | 1. Correct the inability to style clickable types in iOS and Safari.
223 | 2. Remove default button styles.
224 | */
225 |
226 | button,
227 | [type='button'],
228 | [type='reset'],
229 | [type='submit'] {
230 | -webkit-appearance: button;
231 | /* 1 */
232 | background-color: transparent;
233 | /* 2 */
234 | background-image: none;
235 | /* 2 */
236 | }
237 |
238 | /*
239 | Use the modern Firefox focus style for all focusable elements.
240 | */
241 |
242 | :-moz-focusring {
243 | outline: auto;
244 | }
245 |
246 | /*
247 | Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
248 | */
249 |
250 | :-moz-ui-invalid {
251 | box-shadow: none;
252 | }
253 |
254 | /*
255 | Add the correct vertical alignment in Chrome and Firefox.
256 | */
257 |
258 | progress {
259 | vertical-align: baseline;
260 | }
261 |
262 | /*
263 | Correct the cursor style of increment and decrement buttons in Safari.
264 | */
265 |
266 | ::-webkit-inner-spin-button,
267 | ::-webkit-outer-spin-button {
268 | height: auto;
269 | }
270 |
271 | /*
272 | 1. Correct the odd appearance in Chrome and Safari.
273 | 2. Correct the outline style in Safari.
274 | */
275 |
276 | [type='search'] {
277 | -webkit-appearance: textfield;
278 | /* 1 */
279 | outline-offset: -2px;
280 | /* 2 */
281 | }
282 |
283 | /*
284 | Remove the inner padding in Chrome and Safari on macOS.
285 | */
286 |
287 | ::-webkit-search-decoration {
288 | -webkit-appearance: none;
289 | }
290 |
291 | /*
292 | 1. Correct the inability to style clickable types in iOS and Safari.
293 | 2. Change font properties to `inherit` in Safari.
294 | */
295 |
296 | ::-webkit-file-upload-button {
297 | -webkit-appearance: button;
298 | /* 1 */
299 | font: inherit;
300 | /* 2 */
301 | }
302 |
303 | /*
304 | Add the correct display in Chrome and Safari.
305 | */
306 |
307 | summary {
308 | display: list-item;
309 | }
310 |
311 | /*
312 | Removes the default spacing and border for appropriate elements.
313 | */
314 |
315 | blockquote,
316 | dl,
317 | dd,
318 | h1,
319 | h2,
320 | h3,
321 | h4,
322 | h5,
323 | h6,
324 | hr,
325 | figure,
326 | p,
327 | pre {
328 | margin: 0;
329 | }
330 |
331 | fieldset {
332 | margin: 0;
333 | padding: 0;
334 | }
335 |
336 | legend {
337 | padding: 0;
338 | }
339 |
340 | ol,
341 | ul,
342 | menu {
343 | list-style: none;
344 | margin: 0;
345 | padding: 0;
346 | }
347 |
348 | /*
349 | Reset default styling for dialogs.
350 | */
351 |
352 | dialog {
353 | padding: 0;
354 | }
355 |
356 | /*
357 | Prevent resizing textareas horizontally by default.
358 | */
359 |
360 | textarea {
361 | resize: vertical;
362 | }
363 |
364 | /*
365 | 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
366 | 2. Set the default placeholder color to the user's configured gray 400 color.
367 | */
368 |
369 | input::-moz-placeholder, textarea::-moz-placeholder {
370 | opacity: 1;
371 | /* 1 */
372 | color: #9ca3af;
373 | /* 2 */
374 | }
375 |
376 | input::placeholder,
377 | textarea::placeholder {
378 | opacity: 1;
379 | /* 1 */
380 | color: #9ca3af;
381 | /* 2 */
382 | }
383 |
384 | /*
385 | Set the default cursor for buttons.
386 | */
387 |
388 | button,
389 | [role="button"] {
390 | cursor: pointer;
391 | }
392 |
393 | /*
394 | Make sure disabled buttons don't get the pointer cursor.
395 | */
396 |
397 | :disabled {
398 | cursor: default;
399 | }
400 |
401 | /*
402 | 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
403 | 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
404 | This can trigger a poorly considered lint error in some tools but is included by design.
405 | */
406 |
407 | img,
408 | svg,
409 | video,
410 | canvas,
411 | audio,
412 | iframe,
413 | embed,
414 | object {
415 | display: block;
416 | /* 1 */
417 | vertical-align: middle;
418 | /* 2 */
419 | }
420 |
421 | /*
422 | Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
423 | */
424 |
425 | img,
426 | video {
427 | max-width: 100%;
428 | height: auto;
429 | }
430 |
431 | /* Make elements with the HTML hidden attribute stay hidden by default */
432 |
433 | [hidden] {
434 | display: none;
435 | }
436 |
437 | [type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select {
438 | -webkit-appearance: none;
439 | -moz-appearance: none;
440 | appearance: none;
441 | background-color: #fff;
442 | border-color: #6b7280;
443 | border-width: 1px;
444 | border-radius: 0px;
445 | padding-top: 0.5rem;
446 | padding-right: 0.75rem;
447 | padding-bottom: 0.5rem;
448 | padding-left: 0.75rem;
449 | font-size: 1rem;
450 | line-height: 1.5rem;
451 | --tw-shadow: 0 0 #0000;
452 | }
453 |
454 | [type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus {
455 | outline: 2px solid transparent;
456 | outline-offset: 2px;
457 | --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
458 | --tw-ring-offset-width: 0px;
459 | --tw-ring-offset-color: #fff;
460 | --tw-ring-color: #2563eb;
461 | --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
462 | --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
463 | box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
464 | border-color: #2563eb;
465 | }
466 |
467 | input::-moz-placeholder, textarea::-moz-placeholder {
468 | color: #6b7280;
469 | opacity: 1;
470 | }
471 |
472 | input::placeholder,textarea::placeholder {
473 | color: #6b7280;
474 | opacity: 1;
475 | }
476 |
477 | ::-webkit-datetime-edit-fields-wrapper {
478 | padding: 0;
479 | }
480 |
481 | ::-webkit-date-and-time-value {
482 | min-height: 1.5em;
483 | text-align: inherit;
484 | }
485 |
486 | ::-webkit-datetime-edit {
487 | display: inline-flex;
488 | }
489 |
490 | ::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field {
491 | padding-top: 0;
492 | padding-bottom: 0;
493 | }
494 |
495 | select {
496 | background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
497 | background-position: right 0.5rem center;
498 | background-repeat: no-repeat;
499 | background-size: 1.5em 1.5em;
500 | padding-right: 2.5rem;
501 | -webkit-print-color-adjust: exact;
502 | print-color-adjust: exact;
503 | }
504 |
505 | [multiple],[size]:where(select:not([size="1"])) {
506 | background-image: initial;
507 | background-position: initial;
508 | background-repeat: unset;
509 | background-size: initial;
510 | padding-right: 0.75rem;
511 | -webkit-print-color-adjust: unset;
512 | print-color-adjust: unset;
513 | }
514 |
515 | [type='checkbox'],[type='radio'] {
516 | -webkit-appearance: none;
517 | -moz-appearance: none;
518 | appearance: none;
519 | padding: 0;
520 | -webkit-print-color-adjust: exact;
521 | print-color-adjust: exact;
522 | display: inline-block;
523 | vertical-align: middle;
524 | background-origin: border-box;
525 | -webkit-user-select: none;
526 | -moz-user-select: none;
527 | user-select: none;
528 | flex-shrink: 0;
529 | height: 1rem;
530 | width: 1rem;
531 | color: #2563eb;
532 | background-color: #fff;
533 | border-color: #6b7280;
534 | border-width: 1px;
535 | --tw-shadow: 0 0 #0000;
536 | }
537 |
538 | [type='checkbox'] {
539 | border-radius: 0px;
540 | }
541 |
542 | [type='radio'] {
543 | border-radius: 100%;
544 | }
545 |
546 | [type='checkbox']:focus,[type='radio']:focus {
547 | outline: 2px solid transparent;
548 | outline-offset: 2px;
549 | --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
550 | --tw-ring-offset-width: 2px;
551 | --tw-ring-offset-color: #fff;
552 | --tw-ring-color: #2563eb;
553 | --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
554 | --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
555 | box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
556 | }
557 |
558 | [type='checkbox']:checked,[type='radio']:checked {
559 | border-color: transparent;
560 | background-color: currentColor;
561 | background-size: 100% 100%;
562 | background-position: center;
563 | background-repeat: no-repeat;
564 | }
565 |
566 | [type='checkbox']:checked {
567 | background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
568 | }
569 |
570 | [type='radio']:checked {
571 | background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
572 | }
573 |
574 | [type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus {
575 | border-color: transparent;
576 | background-color: currentColor;
577 | }
578 |
579 | [type='checkbox']:indeterminate {
580 | background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");
581 | border-color: transparent;
582 | background-color: currentColor;
583 | background-size: 100% 100%;
584 | background-position: center;
585 | background-repeat: no-repeat;
586 | }
587 |
588 | [type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus {
589 | border-color: transparent;
590 | background-color: currentColor;
591 | }
592 |
593 | [type='file'] {
594 | background: unset;
595 | border-color: inherit;
596 | border-width: 0;
597 | border-radius: 0;
598 | padding: 0;
599 | font-size: unset;
600 | line-height: inherit;
601 | }
602 |
603 | [type='file']:focus {
604 | outline: 1px solid ButtonText;
605 | outline: 1px auto -webkit-focus-ring-color;
606 | }
607 |
608 | *, ::before, ::after {
609 | --tw-border-spacing-x: 0;
610 | --tw-border-spacing-y: 0;
611 | --tw-translate-x: 0;
612 | --tw-translate-y: 0;
613 | --tw-rotate: 0;
614 | --tw-skew-x: 0;
615 | --tw-skew-y: 0;
616 | --tw-scale-x: 1;
617 | --tw-scale-y: 1;
618 | --tw-pan-x: ;
619 | --tw-pan-y: ;
620 | --tw-pinch-zoom: ;
621 | --tw-scroll-snap-strictness: proximity;
622 | --tw-gradient-from-position: ;
623 | --tw-gradient-via-position: ;
624 | --tw-gradient-to-position: ;
625 | --tw-ordinal: ;
626 | --tw-slashed-zero: ;
627 | --tw-numeric-figure: ;
628 | --tw-numeric-spacing: ;
629 | --tw-numeric-fraction: ;
630 | --tw-ring-inset: ;
631 | --tw-ring-offset-width: 0px;
632 | --tw-ring-offset-color: #fff;
633 | --tw-ring-color: rgb(59 130 246 / 0.5);
634 | --tw-ring-offset-shadow: 0 0 #0000;
635 | --tw-ring-shadow: 0 0 #0000;
636 | --tw-shadow: 0 0 #0000;
637 | --tw-shadow-colored: 0 0 #0000;
638 | --tw-blur: ;
639 | --tw-brightness: ;
640 | --tw-contrast: ;
641 | --tw-grayscale: ;
642 | --tw-hue-rotate: ;
643 | --tw-invert: ;
644 | --tw-saturate: ;
645 | --tw-sepia: ;
646 | --tw-drop-shadow: ;
647 | --tw-backdrop-blur: ;
648 | --tw-backdrop-brightness: ;
649 | --tw-backdrop-contrast: ;
650 | --tw-backdrop-grayscale: ;
651 | --tw-backdrop-hue-rotate: ;
652 | --tw-backdrop-invert: ;
653 | --tw-backdrop-opacity: ;
654 | --tw-backdrop-saturate: ;
655 | --tw-backdrop-sepia: ;
656 | }
657 |
658 | ::backdrop {
659 | --tw-border-spacing-x: 0;
660 | --tw-border-spacing-y: 0;
661 | --tw-translate-x: 0;
662 | --tw-translate-y: 0;
663 | --tw-rotate: 0;
664 | --tw-skew-x: 0;
665 | --tw-skew-y: 0;
666 | --tw-scale-x: 1;
667 | --tw-scale-y: 1;
668 | --tw-pan-x: ;
669 | --tw-pan-y: ;
670 | --tw-pinch-zoom: ;
671 | --tw-scroll-snap-strictness: proximity;
672 | --tw-gradient-from-position: ;
673 | --tw-gradient-via-position: ;
674 | --tw-gradient-to-position: ;
675 | --tw-ordinal: ;
676 | --tw-slashed-zero: ;
677 | --tw-numeric-figure: ;
678 | --tw-numeric-spacing: ;
679 | --tw-numeric-fraction: ;
680 | --tw-ring-inset: ;
681 | --tw-ring-offset-width: 0px;
682 | --tw-ring-offset-color: #fff;
683 | --tw-ring-color: rgb(59 130 246 / 0.5);
684 | --tw-ring-offset-shadow: 0 0 #0000;
685 | --tw-ring-shadow: 0 0 #0000;
686 | --tw-shadow: 0 0 #0000;
687 | --tw-shadow-colored: 0 0 #0000;
688 | --tw-blur: ;
689 | --tw-brightness: ;
690 | --tw-contrast: ;
691 | --tw-grayscale: ;
692 | --tw-hue-rotate: ;
693 | --tw-invert: ;
694 | --tw-saturate: ;
695 | --tw-sepia: ;
696 | --tw-drop-shadow: ;
697 | --tw-backdrop-blur: ;
698 | --tw-backdrop-brightness: ;
699 | --tw-backdrop-contrast: ;
700 | --tw-backdrop-grayscale: ;
701 | --tw-backdrop-hue-rotate: ;
702 | --tw-backdrop-invert: ;
703 | --tw-backdrop-opacity: ;
704 | --tw-backdrop-saturate: ;
705 | --tw-backdrop-sepia: ;
706 | }
707 |
708 | .fixed {
709 | position: fixed;
710 | }
711 |
712 | .absolute {
713 | position: absolute;
714 | }
715 |
716 | .relative {
717 | position: relative;
718 | }
719 |
720 | .inset-0 {
721 | inset: 0px;
722 | }
723 |
724 | .left-0 {
725 | left: 0px;
726 | }
727 |
728 | .right-0 {
729 | right: 0px;
730 | }
731 |
732 | .right-5 {
733 | right: 1.25rem;
734 | }
735 |
736 | .right-\[40px\] {
737 | right: 40px;
738 | }
739 |
740 | .top-0 {
741 | top: 0px;
742 | }
743 |
744 | .top-16 {
745 | top: 4rem;
746 | }
747 |
748 | .top-\[-6px\] {
749 | top: -6px;
750 | }
751 |
752 | .top-\[50px\] {
753 | top: 50px;
754 | }
755 |
756 | .z-10 {
757 | z-index: 10;
758 | }
759 |
760 | .mx-auto {
761 | margin-left: auto;
762 | margin-right: auto;
763 | }
764 |
765 | .my-8 {
766 | margin-top: 2rem;
767 | margin-bottom: 2rem;
768 | }
769 |
770 | .-ml-1 {
771 | margin-left: -0.25rem;
772 | }
773 |
774 | .mb-5 {
775 | margin-bottom: 1.25rem;
776 | }
777 |
778 | .mr-2 {
779 | margin-right: 0.5rem;
780 | }
781 |
782 | .mt-1 {
783 | margin-top: 0.25rem;
784 | }
785 |
786 | .mt-2 {
787 | margin-top: 0.5rem;
788 | }
789 |
790 | .mt-4 {
791 | margin-top: 1rem;
792 | }
793 |
794 | .mt-5 {
795 | margin-top: 1.25rem;
796 | }
797 |
798 | .block {
799 | display: block;
800 | }
801 |
802 | .flex {
803 | display: flex;
804 | }
805 |
806 | .inline-flex {
807 | display: inline-flex;
808 | }
809 |
810 | .grid {
811 | display: grid;
812 | }
813 |
814 | .hidden {
815 | display: none;
816 | }
817 |
818 | .h-5 {
819 | height: 1.25rem;
820 | }
821 |
822 | .h-6 {
823 | height: 1.5rem;
824 | }
825 |
826 | .h-\[12px\] {
827 | height: 12px;
828 | }
829 |
830 | .h-\[200px\] {
831 | height: 200px;
832 | }
833 |
834 | .h-screen {
835 | height: 100vh;
836 | }
837 |
838 | .min-h-full {
839 | min-height: 100%;
840 | }
841 |
842 | .w-5 {
843 | width: 1.25rem;
844 | }
845 |
846 | .w-6 {
847 | width: 1.5rem;
848 | }
849 |
850 | .w-full {
851 | width: 100%;
852 | }
853 |
854 | .w-screen {
855 | width: 100vw;
856 | }
857 |
858 | .max-w-5xl {
859 | max-width: 64rem;
860 | }
861 |
862 | .max-w-lg {
863 | max-width: 32rem;
864 | }
865 |
866 | .flex-1 {
867 | flex: 1 1 0%;
868 | }
869 |
870 | .translate-y-0 {
871 | --tw-translate-y: 0px;
872 | transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
873 | }
874 |
875 | .translate-y-4 {
876 | --tw-translate-y: 1rem;
877 | transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
878 | }
879 |
880 | .transform {
881 | transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
882 | }
883 |
884 | @keyframes pulse {
885 | 50% {
886 | opacity: .5;
887 | }
888 | }
889 |
890 | .animate-pulse {
891 | animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
892 | }
893 |
894 | @keyframes spin {
895 | to {
896 | transform: rotate(360deg);
897 | }
898 | }
899 |
900 | .animate-spin {
901 | animation: spin 1s linear infinite;
902 | }
903 |
904 | .resize {
905 | resize: both;
906 | }
907 |
908 | .grid-cols-1 {
909 | grid-template-columns: repeat(1, minmax(0, 1fr));
910 | }
911 |
912 | .flex-col {
913 | flex-direction: column;
914 | }
915 |
916 | .items-center {
917 | align-items: center;
918 | }
919 |
920 | .justify-start {
921 | justify-content: flex-start;
922 | }
923 |
924 | .justify-center {
925 | justify-content: center;
926 | }
927 |
928 | .gap-x-8 {
929 | -moz-column-gap: 2rem;
930 | column-gap: 2rem;
931 | }
932 |
933 | .gap-y-4 {
934 | row-gap: 1rem;
935 | }
936 |
937 | .space-x-1 > :not([hidden]) ~ :not([hidden]) {
938 | --tw-space-x-reverse: 0;
939 | margin-right: calc(0.25rem * var(--tw-space-x-reverse));
940 | margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));
941 | }
942 |
943 | .space-x-2 > :not([hidden]) ~ :not([hidden]) {
944 | --tw-space-x-reverse: 0;
945 | margin-right: calc(0.5rem * var(--tw-space-x-reverse));
946 | margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
947 | }
948 |
949 | .space-y-10 > :not([hidden]) ~ :not([hidden]) {
950 | --tw-space-y-reverse: 0;
951 | margin-top: calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));
952 | margin-bottom: calc(2.5rem * var(--tw-space-y-reverse));
953 | }
954 |
955 | .space-y-4 > :not([hidden]) ~ :not([hidden]) {
956 | --tw-space-y-reverse: 0;
957 | margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
958 | margin-bottom: calc(1rem * var(--tw-space-y-reverse));
959 | }
960 |
961 | .divide-y > :not([hidden]) ~ :not([hidden]) {
962 | --tw-divide-y-reverse: 0;
963 | border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
964 | border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
965 | }
966 |
967 | .divide-gray-100 > :not([hidden]) ~ :not([hidden]) {
968 | --tw-divide-opacity: 1;
969 | border-color: rgb(243 244 246 / var(--tw-divide-opacity));
970 | }
971 |
972 | .divide-gray-900\/10 > :not([hidden]) ~ :not([hidden]) {
973 | border-color: rgb(17 24 39 / 0.1);
974 | }
975 |
976 | .overflow-hidden {
977 | overflow: hidden;
978 | }
979 |
980 | .overflow-scroll {
981 | overflow: scroll;
982 | }
983 |
984 | .overflow-y-auto {
985 | overflow-y: auto;
986 | }
987 |
988 | .rounded-full {
989 | border-radius: 9999px;
990 | }
991 |
992 | .rounded-lg {
993 | border-radius: 0.5rem;
994 | }
995 |
996 | .rounded-md {
997 | border-radius: 0.375rem;
998 | }
999 |
1000 | .rounded-xl {
1001 | border-radius: 0.75rem;
1002 | }
1003 |
1004 | .border {
1005 | border-width: 1px;
1006 | }
1007 |
1008 | .border-b-4 {
1009 | border-bottom-width: 4px;
1010 | }
1011 |
1012 | .border-t {
1013 | border-top-width: 1px;
1014 | }
1015 |
1016 | .border-slate-200 {
1017 | --tw-border-opacity: 1;
1018 | border-color: rgb(226 232 240 / var(--tw-border-opacity));
1019 | }
1020 |
1021 | .border-slate-300 {
1022 | --tw-border-opacity: 1;
1023 | border-color: rgb(203 213 225 / var(--tw-border-opacity));
1024 | }
1025 |
1026 | .bg-gray-500 {
1027 | --tw-bg-opacity: 1;
1028 | background-color: rgb(107 114 128 / var(--tw-bg-opacity));
1029 | }
1030 |
1031 | .bg-red-400 {
1032 | --tw-bg-opacity: 1;
1033 | background-color: rgb(248 113 113 / var(--tw-bg-opacity));
1034 | }
1035 |
1036 | .bg-red-600 {
1037 | --tw-bg-opacity: 1;
1038 | background-color: rgb(220 38 38 / var(--tw-bg-opacity));
1039 | }
1040 |
1041 | .bg-sky-600 {
1042 | --tw-bg-opacity: 1;
1043 | background-color: rgb(2 132 199 / var(--tw-bg-opacity));
1044 | }
1045 |
1046 | .bg-slate-100 {
1047 | --tw-bg-opacity: 1;
1048 | background-color: rgb(241 245 249 / var(--tw-bg-opacity));
1049 | }
1050 |
1051 | .bg-slate-200 {
1052 | --tw-bg-opacity: 1;
1053 | background-color: rgb(226 232 240 / var(--tw-bg-opacity));
1054 | }
1055 |
1056 | .bg-slate-700 {
1057 | --tw-bg-opacity: 1;
1058 | background-color: rgb(51 65 85 / var(--tw-bg-opacity));
1059 | }
1060 |
1061 | .bg-slate-900 {
1062 | --tw-bg-opacity: 1;
1063 | background-color: rgb(15 23 42 / var(--tw-bg-opacity));
1064 | }
1065 |
1066 | .bg-white {
1067 | --tw-bg-opacity: 1;
1068 | background-color: rgb(255 255 255 / var(--tw-bg-opacity));
1069 | }
1070 |
1071 | .bg-yellow-400 {
1072 | --tw-bg-opacity: 1;
1073 | background-color: rgb(250 204 21 / var(--tw-bg-opacity));
1074 | }
1075 |
1076 | .bg-opacity-75 {
1077 | --tw-bg-opacity: 0.75;
1078 | }
1079 |
1080 | .p-4 {
1081 | padding: 1rem;
1082 | }
1083 |
1084 | .p-6 {
1085 | padding: 1.5rem;
1086 | }
1087 |
1088 | .p-8 {
1089 | padding: 2rem;
1090 | }
1091 |
1092 | .px-0 {
1093 | padding-left: 0px;
1094 | padding-right: 0px;
1095 | }
1096 |
1097 | .px-2 {
1098 | padding-left: 0.5rem;
1099 | padding-right: 0.5rem;
1100 | }
1101 |
1102 | .px-3 {
1103 | padding-left: 0.75rem;
1104 | padding-right: 0.75rem;
1105 | }
1106 |
1107 | .px-3\.5 {
1108 | padding-left: 0.875rem;
1109 | padding-right: 0.875rem;
1110 | }
1111 |
1112 | .px-4 {
1113 | padding-left: 1rem;
1114 | padding-right: 1rem;
1115 | }
1116 |
1117 | .px-6 {
1118 | padding-left: 1.5rem;
1119 | padding-right: 1.5rem;
1120 | }
1121 |
1122 | .px-8 {
1123 | padding-left: 2rem;
1124 | padding-right: 2rem;
1125 | }
1126 |
1127 | .py-0 {
1128 | padding-top: 0px;
1129 | padding-bottom: 0px;
1130 | }
1131 |
1132 | .py-0\.5 {
1133 | padding-top: 0.125rem;
1134 | padding-bottom: 0.125rem;
1135 | }
1136 |
1137 | .py-1 {
1138 | padding-top: 0.25rem;
1139 | padding-bottom: 0.25rem;
1140 | }
1141 |
1142 | .py-1\.5 {
1143 | padding-top: 0.375rem;
1144 | padding-bottom: 0.375rem;
1145 | }
1146 |
1147 | .py-2 {
1148 | padding-top: 0.5rem;
1149 | padding-bottom: 0.5rem;
1150 | }
1151 |
1152 | .py-2\.5 {
1153 | padding-top: 0.625rem;
1154 | padding-bottom: 0.625rem;
1155 | }
1156 |
1157 | .py-3 {
1158 | padding-top: 0.75rem;
1159 | padding-bottom: 0.75rem;
1160 | }
1161 |
1162 | .py-4 {
1163 | padding-top: 1rem;
1164 | padding-bottom: 1rem;
1165 | }
1166 |
1167 | .py-6 {
1168 | padding-top: 1.5rem;
1169 | padding-bottom: 1.5rem;
1170 | }
1171 |
1172 | .py-8 {
1173 | padding-top: 2rem;
1174 | padding-bottom: 2rem;
1175 | }
1176 |
1177 | .\!pb-0 {
1178 | padding-bottom: 0px !important;
1179 | }
1180 |
1181 | .\!pt-0 {
1182 | padding-top: 0px !important;
1183 | }
1184 |
1185 | .pb-4 {
1186 | padding-bottom: 1rem;
1187 | }
1188 |
1189 | .pt-10 {
1190 | padding-top: 2.5rem;
1191 | }
1192 |
1193 | .pt-\[56px\] {
1194 | padding-top: 56px;
1195 | }
1196 |
1197 | .text-left {
1198 | text-align: left;
1199 | }
1200 |
1201 | .text-center {
1202 | text-align: center;
1203 | }
1204 |
1205 | .font-mono {
1206 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
1207 | }
1208 |
1209 | .text-3xl {
1210 | font-size: 1.875rem;
1211 | line-height: 2.25rem;
1212 | }
1213 |
1214 | .text-base {
1215 | font-size: 1rem;
1216 | line-height: 1.5rem;
1217 | }
1218 |
1219 | .text-sm {
1220 | font-size: 0.875rem;
1221 | line-height: 1.25rem;
1222 | }
1223 |
1224 | .text-xl {
1225 | font-size: 1.25rem;
1226 | line-height: 1.75rem;
1227 | }
1228 |
1229 | .font-bold {
1230 | font-weight: 700;
1231 | }
1232 |
1233 | .font-medium {
1234 | font-weight: 500;
1235 | }
1236 |
1237 | .font-semibold {
1238 | font-weight: 600;
1239 | }
1240 |
1241 | .italic {
1242 | font-style: italic;
1243 | }
1244 |
1245 | .leading-6 {
1246 | line-height: 1.5rem;
1247 | }
1248 |
1249 | .leading-7 {
1250 | line-height: 1.75rem;
1251 | }
1252 |
1253 | .text-gray-500 {
1254 | --tw-text-opacity: 1;
1255 | color: rgb(107 114 128 / var(--tw-text-opacity));
1256 | }
1257 |
1258 | .text-gray-700 {
1259 | --tw-text-opacity: 1;
1260 | color: rgb(55 65 81 / var(--tw-text-opacity));
1261 | }
1262 |
1263 | .text-gray-900 {
1264 | --tw-text-opacity: 1;
1265 | color: rgb(17 24 39 / var(--tw-text-opacity));
1266 | }
1267 |
1268 | .text-green-400 {
1269 | --tw-text-opacity: 1;
1270 | color: rgb(74 222 128 / var(--tw-text-opacity));
1271 | }
1272 |
1273 | .text-red-400 {
1274 | --tw-text-opacity: 1;
1275 | color: rgb(248 113 113 / var(--tw-text-opacity));
1276 | }
1277 |
1278 | .text-red-500 {
1279 | --tw-text-opacity: 1;
1280 | color: rgb(239 68 68 / var(--tw-text-opacity));
1281 | }
1282 |
1283 | .text-red-900 {
1284 | --tw-text-opacity: 1;
1285 | color: rgb(127 29 29 / var(--tw-text-opacity));
1286 | }
1287 |
1288 | .text-slate-200 {
1289 | --tw-text-opacity: 1;
1290 | color: rgb(226 232 240 / var(--tw-text-opacity));
1291 | }
1292 |
1293 | .text-slate-300 {
1294 | --tw-text-opacity: 1;
1295 | color: rgb(203 213 225 / var(--tw-text-opacity));
1296 | }
1297 |
1298 | .text-slate-400 {
1299 | --tw-text-opacity: 1;
1300 | color: rgb(148 163 184 / var(--tw-text-opacity));
1301 | }
1302 |
1303 | .text-slate-700 {
1304 | --tw-text-opacity: 1;
1305 | color: rgb(51 65 85 / var(--tw-text-opacity));
1306 | }
1307 |
1308 | .text-white {
1309 | --tw-text-opacity: 1;
1310 | color: rgb(255 255 255 / var(--tw-text-opacity));
1311 | }
1312 |
1313 | .text-yellow-400 {
1314 | --tw-text-opacity: 1;
1315 | color: rgb(250 204 21 / var(--tw-text-opacity));
1316 | }
1317 |
1318 | .text-yellow-900 {
1319 | --tw-text-opacity: 1;
1320 | color: rgb(113 63 18 / var(--tw-text-opacity));
1321 | }
1322 |
1323 | .opacity-0 {
1324 | opacity: 0;
1325 | }
1326 |
1327 | .opacity-100 {
1328 | opacity: 1;
1329 | }
1330 |
1331 | .opacity-25 {
1332 | opacity: 0.25;
1333 | }
1334 |
1335 | .opacity-50 {
1336 | opacity: 0.5;
1337 | }
1338 |
1339 | .opacity-75 {
1340 | opacity: 0.75;
1341 | }
1342 |
1343 | .shadow-md {
1344 | --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
1345 | --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
1346 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1347 | }
1348 |
1349 | .shadow-sm {
1350 | --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
1351 | --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
1352 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1353 | }
1354 |
1355 | .shadow-xl {
1356 | --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
1357 | --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);
1358 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1359 | }
1360 |
1361 | .ring-1 {
1362 | --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
1363 | --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
1364 | box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
1365 | }
1366 |
1367 | .ring-inset {
1368 | --tw-ring-inset: inset;
1369 | }
1370 |
1371 | .ring-gray-300 {
1372 | --tw-ring-opacity: 1;
1373 | --tw-ring-color: rgb(209 213 219 / var(--tw-ring-opacity));
1374 | }
1375 |
1376 | .ring-gray-900\/5 {
1377 | --tw-ring-color: rgb(17 24 39 / 0.05);
1378 | }
1379 |
1380 | .transition-all {
1381 | transition-property: all;
1382 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1383 | transition-duration: 150ms;
1384 | }
1385 |
1386 | .transition-opacity {
1387 | transition-property: opacity;
1388 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1389 | transition-duration: 150ms;
1390 | }
1391 |
1392 | .duration-200 {
1393 | transition-duration: 200ms;
1394 | }
1395 |
1396 | .duration-300 {
1397 | transition-duration: 300ms;
1398 | }
1399 |
1400 | .ease-in {
1401 | transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
1402 | }
1403 |
1404 | .ease-out {
1405 | transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
1406 | }
1407 |
1408 | [x-cloak] {
1409 | display: none !important;
1410 | }
1411 |
1412 | /* Style for scrollable-div to fill the available vertical space */
1413 |
1414 | #scrollable-div {
1415 | flex: 1;
1416 | /* Grow to fill available vertical space */
1417 | }
1418 |
1419 | #resize-handle {
1420 | cursor: ns-resize;
1421 | /* Change cursor to indicate vertical resizing */
1422 | }
1423 |
1424 | /* Style for deploy-output-container */
1425 |
1426 | #deploy-output-container {
1427 | min-height: 150px;
1428 | }
1429 |
1430 | .hover\:bg-gray-50:hover {
1431 | --tw-bg-opacity: 1;
1432 | background-color: rgb(249 250 251 / var(--tw-bg-opacity));
1433 | }
1434 |
1435 | .hover\:bg-red-500:hover {
1436 | --tw-bg-opacity: 1;
1437 | background-color: rgb(239 68 68 / var(--tw-bg-opacity));
1438 | }
1439 |
1440 | .hover\:bg-sky-500:hover {
1441 | --tw-bg-opacity: 1;
1442 | background-color: rgb(14 165 233 / var(--tw-bg-opacity));
1443 | }
1444 |
1445 | .hover\:bg-slate-300:hover {
1446 | --tw-bg-opacity: 1;
1447 | background-color: rgb(203 213 225 / var(--tw-bg-opacity));
1448 | }
1449 |
1450 | .focus-visible\:outline:focus-visible {
1451 | outline-style: solid;
1452 | }
1453 |
1454 | .focus-visible\:outline-2:focus-visible {
1455 | outline-width: 2px;
1456 | }
1457 |
1458 | .focus-visible\:outline-offset-2:focus-visible {
1459 | outline-offset: 2px;
1460 | }
1461 |
1462 | .focus-visible\:outline-red-600:focus-visible {
1463 | outline-color: #dc2626;
1464 | }
1465 |
1466 | .focus-visible\:outline-sky-600:focus-visible {
1467 | outline-color: #0284c7;
1468 | }
1469 |
1470 | @media (min-width: 640px) {
1471 | .sm\:col-span-2 {
1472 | grid-column: span 2 / span 2;
1473 | }
1474 |
1475 | .sm\:col-start-2 {
1476 | grid-column-start: 2;
1477 | }
1478 |
1479 | .sm\:mt-0 {
1480 | margin-top: 0px;
1481 | }
1482 |
1483 | .sm\:translate-y-0 {
1484 | --tw-translate-y: 0px;
1485 | transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1486 | }
1487 |
1488 | .sm\:scale-100 {
1489 | --tw-scale-x: 1;
1490 | --tw-scale-y: 1;
1491 | transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1492 | }
1493 |
1494 | .sm\:scale-95 {
1495 | --tw-scale-x: .95;
1496 | --tw-scale-y: .95;
1497 | transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1498 | }
1499 |
1500 | .sm\:p-8 {
1501 | padding: 2rem;
1502 | }
1503 | }
1504 |
1505 | @media (min-width: 768px) {
1506 | .md\:col-span-2 {
1507 | grid-column: span 2 / span 2;
1508 | }
1509 |
1510 | .md\:grid-cols-3 {
1511 | grid-template-columns: repeat(3, minmax(0, 1fr));
1512 | }
1513 | }
1514 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/deployed/src/input.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | [x-cloak] { display: none !important; }
6 |
7 | /* Style for scrollable-div to fill the available vertical space */
8 | #scrollable-div {
9 | flex: 1; /* Grow to fill available vertical space */
10 | }
11 |
12 | #resize-handle {
13 | cursor: ns-resize; /* Change cursor to indicate vertical resizing */
14 | }
15 |
16 | /* Style for deploy-output-container */
17 | #deploy-output-container {
18 | min-height: 150px;
19 | }
20 |
--------------------------------------------------------------------------------
/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/app/controllers/concerns/.keep
--------------------------------------------------------------------------------
/app/controllers/deployed/application_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Deployed
4 | class ApplicationController < ActionController::Base
5 | layout 'deployed/application'
6 |
7 | helper Deployed::Engine.helpers
8 |
9 | before_action :initialize_deployed
10 |
11 | private
12 |
13 | # A bunch of housekeeping stuff to make things run
14 | def initialize_deployed
15 | Deployed.setup!
16 | end
17 |
18 | def lock_file_path
19 | Rails.root.join(Deployed::DIRECTORY, 'process.lock')
20 | end
21 |
22 | def lock_process
23 | File.open(lock_file_path, 'a') do |file|
24 | file.puts(Deployed::CurrentExecution.child_pid)
25 | end
26 | end
27 |
28 | def release_process
29 | return unless File.exist?(lock_file_path)
30 |
31 | File.delete(lock_file_path)
32 | end
33 |
34 | def stored_pid
35 | return false unless File.exist?(lock_file_path)
36 |
37 | value = File.read(lock_file_path).to_i
38 |
39 | if value.is_a?(Integer)
40 | value
41 | else
42 | false
43 | end
44 | end
45 |
46 | def process_running?
47 | return false unless stored_pid
48 |
49 | begin
50 | # Send signal 0 to the process to check if it exists
51 | Process.kill(0, stored_pid)
52 | true
53 | rescue Errno::ESRCH
54 | false
55 | end
56 | end
57 | helper_method :process_running?
58 |
59 | def current_log_file
60 | Rails.root.join(Deployed::DIRECTORY, 'deployments/current.log')
61 | end
62 | end
63 | end
64 |
--------------------------------------------------------------------------------
/app/controllers/deployed/config_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Deployed
4 | # Provides information on the current ./config/deploy.yml
5 | class ConfigController < ApplicationController
6 | def show
7 | respond_to(&:html)
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/app/controllers/deployed/git_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Deployed
4 | # Provides a git status check to see if we are deploying uncommitted changes
5 | class GitController < ApplicationController
6 | def uncommitted_check
7 | @git_status = `git status --porcelain`
8 | respond_to(&:html)
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/app/controllers/deployed/log_output_controller.rb:
--------------------------------------------------------------------------------
1 | module Deployed
2 | class LogOutputController < ApplicationController
3 | include ActionController::Live
4 |
5 | before_action :set_headers
6 |
7 | def index
8 | thread_exit_flag = false
9 |
10 | thread = Thread.new do
11 | File.open(current_log_file, 'r') do |file|
12 | while true
13 | IO.select([file])
14 |
15 | found_deployed = false
16 |
17 | file.each_line do |line|
18 | # Check the exit flag
19 | if thread_exit_flag
20 | break
21 | end
22 |
23 | css_class = if line.include?('[Deployed]')
24 | 'text-slate-400'
25 | else
26 | 'text-green-400'
27 | end
28 | sse.write("#{line.strip}
", event: 'message')
29 |
30 | if line.include?("[Deployed Rails] End")
31 | found_deployed = true
32 | break
33 | end
34 | end
35 |
36 | if found_deployed || thread_exit_flag
37 | break
38 | end
39 | end
40 | end
41 | end
42 |
43 | begin
44 | thread.join
45 | rescue ActionController::Live::ClientDisconnected
46 | logger.info 'Client Disconnected'
47 | ensure
48 | # Set the exit flag to true to signal the thread to exit
49 | thread_exit_flag = true
50 | sse.close
51 | response.stream.close
52 | end
53 | end
54 |
55 |
56 | private
57 |
58 | def set_headers
59 | response.headers['Content-Type'] = 'text/event-stream'
60 | response.headers['Last-Modified'] = Time.now.httpdate
61 | end
62 |
63 | def sse
64 | @sse ||= SSE.new(response.stream, event: 'Stream Started')
65 | end
66 | end
67 | end
68 |
--------------------------------------------------------------------------------
/app/controllers/deployed/run_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Deployed
4 | # Provides a centralized way to run all `kamal [command]` executions and streams to the browser
5 | class RunController < ApplicationController
6 | class ConcurrentProcessRunning < StandardError; end
7 | skip_forgery_protection
8 |
9 | # Endpoint to execute the kamal command
10 | def execute
11 | raise(ConcurrentProcessRunning) if process_running?
12 | release_process if stored_pid
13 | File.write(current_log_file, '')
14 |
15 | # Fork a child process
16 | Deployed::CurrentExecution.child_pid = fork do
17 | exec("bundle exec rake deployed:execute_and_log['#{command}']")
18 | end
19 |
20 | lock_process
21 | render json: { message: 'OK' }
22 | rescue ConcurrentProcessRunning
23 | render json: { message: 'EXISTING PROCESS' }
24 | end
25 |
26 | # Endpoint to cancel currently running process
27 | def cancel
28 | pid = stored_pid
29 | if process_running?
30 | # If a process is running, get the PID and attempt to kill it
31 | begin
32 | Process.kill('TERM', stored_pid)
33 | rescue Errno::ESRCH
34 | ensure
35 | release_process
36 | end
37 | end
38 | render json: { message: pid }
39 | end
40 |
41 | private
42 |
43 | def command
44 | params[:command]
45 | end
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/app/controllers/deployed/setup_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Deployed
4 | # Provides a way to setup ./config/deploy.yml
5 | class SetupController < ApplicationController
6 | def new
7 | respond_to do |format|
8 | format.html
9 | end
10 | end
11 |
12 | def create
13 | `kamal init`
14 |
15 | respond_to do |format|
16 | format.html { redirect_to root_path }
17 | end
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/app/controllers/deployed/welcome_controller.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Deployed
4 | # Provides the main entry point for the app
5 | class WelcomeController < ApplicationController
6 | def index
7 | respond_to(&:html)
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/app/helpers/deployed/application_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Deployed
4 | module ApplicationHelper
5 | def rocket_icon
6 | output = <<~ICON
7 |
10 | ICON
11 |
12 | output.html_safe
13 | end
14 |
15 | def config_icon
16 | output = <<~ICON
17 |
20 | ICON
21 |
22 | output.html_safe
23 | end
24 |
25 | def tools_icon
26 | output = <<~ICON
27 |
31 | ICON
32 |
33 | output.html_safe
34 | end
35 |
36 | def right_arrow
37 | output = <<~ICON
38 |
41 | ICON
42 |
43 | output.html_safe
44 | end
45 |
46 | def kamal_exec_button(label:, command:)
47 | button_tag(
48 | label,
49 | type: 'button',
50 | onclick: "execDeployed('#{command}')",
51 | class: 'rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50',
52 | 'x-bind:disabled' => '$store.process.running',
53 | 'x-bind:class' => "{'opacity-50': $store.process.running}",
54 | 'x-data' => ''
55 | )
56 | end
57 |
58 | def kamal_abort_button
59 | button_tag(
60 | 'Abort',
61 | type: 'button',
62 | onclick: "abortDeployed()",
63 | class: 'rounded-md bg-red-600 px-3 py-1.5 text-sm text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600',
64 | 'x-bind:disabled' => '$store.process.abortInProgress',
65 | 'x-bind:class' => "{'opacity-50': $store.process.abortInProgress}",
66 | 'x-text' => "$store.process.abortInProgress ? 'Aborting' : 'Abort'",
67 | 'x-data' => ''
68 | )
69 | end
70 | end
71 | end
72 |
--------------------------------------------------------------------------------
/app/helpers/deployed/log_output_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Deployed
4 | module LogOutputHelper
5 | def deploy_output_intro
6 | output = <<~HTML
7 | Ready... Set... Deploy!
8 | HTML
9 |
10 | output.html_safe
11 | end
12 |
13 | def deploy_output_kamal_version
14 | output = <<~HTML
15 |
16 | Using kamal #{::Kamal::VERSION}
17 |
18 | HTML
19 |
20 | output.html_safe
21 | end
22 |
23 | def deploy_output_missing_config
24 | return unless Deployed::Config.requires_init
25 |
26 | output = <<~HTML
27 | WARNING: ./config/deploy.yml file not detected
28 | HTML
29 |
30 | output.html_safe
31 | end
32 |
33 | def deploy_output_spinner
34 | output = <<~HTML
35 |
41 | HTML
42 |
43 | output.html_safe
44 | end
45 |
46 | def deploy_output_resize_handler
47 | output = <<~ICON
48 |
51 | ICON
52 |
53 | output.html_safe
54 | end
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/app/models/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/app/models/concerns/.keep
--------------------------------------------------------------------------------
/app/models/deployed/config.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'yaml'
4 |
5 | module Deployed
6 | # Provides a model to track the current values in ./config/deploy.yml
7 | class Config < ActiveSupport::CurrentAttributes
8 | attribute :service, :image, :servers, :ssh, :volumes, :registry, :env, :traefik, :requires_init, :env_values
9 |
10 | def self.init!(yaml_file = './config/deploy.yml', dot_env_file = '.env')
11 | self.requires_init = File.exist?(yaml_file) ? false : true
12 |
13 | unless requires_init
14 | yaml_data = YAML.load_file(yaml_file)
15 | self.service = yaml_data['service']
16 | self.image = yaml_data['image']
17 | self.servers = yaml_data['servers']
18 | self.ssh = yaml_data['ssh']
19 | self.volumes = yaml_data['volumes']
20 | self.registry = yaml_data['registry']
21 | self.env = yaml_data['env'] || {}
22 | self.traefik = yaml_data['traefik']
23 | end
24 |
25 | if File.exist?(dot_env_file)
26 | self.env_values = {}
27 |
28 | File.open(dot_env_file, 'r') do |file|
29 | file.each_line do |line|
30 | key, value = line.strip.split('=')
31 | self.env_values[key] = value
32 | end
33 | end
34 | end
35 |
36 | requires_init
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/app/models/deployed/current_execution.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Deployed
4 | # Provides a way to track the current child_pid
5 | class CurrentExecution < ActiveSupport::CurrentAttributes
6 | attribute :child_pid
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/views/deployed/git/uncommitted_check.html.erb:
--------------------------------------------------------------------------------
1 | <%= turbo_frame_tag 'git-status' do %>
2 | <% unless @git_status.empty? %>
3 | You have uncommitted files!
4 | <% end %>
5 | <% end %>
6 |
--------------------------------------------------------------------------------
/app/views/deployed/setup/new.html.erb:
--------------------------------------------------------------------------------
1 | <%= turbo_frame_tag 'deployed-init', target: '_top' do %>
2 |
3 |
12 |
13 |
14 |
15 |
24 |
25 |
26 |
27 |
28 |
31 | Kamal Initialization Required
32 |
33 |
34 |
35 |
./config/deploy.yml not detected.
36 |
We will run kamal init
for you.
37 |
38 |
39 |
40 |
41 | <%= button_to 'Setup Kamal', setup_path, method: :post, class: 'inline-flex w-full justify-center rounded-full bg-sky-600 py-3 font-semibold text-white shadow-sm hover:bg-sky-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-600 sm:col-start-2' %>
42 |
43 |
44 |
45 |
46 |
47 | <% end %>
48 |
--------------------------------------------------------------------------------
/app/views/deployed/welcome/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <%= rocket_icon %>
6 | Deployment
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | <%= kamal_exec_button(label: 'Deploy', command: 'deploy') %>
15 |
16 | <%= turbo_frame_tag 'git-status', src: git_uncommitted_check_url %>
17 |
18 |
19 | <%= kamal_exec_button(label: 'App Details', command: 'app details') %>
20 | <%= kamal_exec_button(label: 'App Containers', command: 'app containers') %>
21 |
22 |
23 | <%= kamal_exec_button(label: 'App Boot', command: 'app boot') %>
24 | <%= kamal_exec_button(label: 'App Start', command: 'app start') %>
25 | <%= kamal_exec_button(label: 'App Stop', command: 'app stop') %>
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | <%= config_icon %>
36 | Configuration
37 |
38 |
39 |
40 |
41 |
42 | <% if Deployed::Config.requires_init %>
43 |
Your ./config/deploy.yml file does not exist. You will need to create it.
44 | <% else %>
45 |
46 |
47 |
- App
48 | -
49 | <%= Deployed::Config.service %>
50 |
51 |
52 |
53 |
- Image
54 | -
55 | <%= Deployed::Config.image %>
56 |
57 |
58 |
59 |
- Environment variables
60 |
-
61 | <% if !Deployed::Config.env.dig('secret').present? && !Deployed::Config.env.dig('clear').present? %>
62 |
You have not specified any environment variables in your configuration file. This is likely an error. Please check your ./config/deploy.yml file.
63 | <% end %>
64 |
65 | <% if Deployed::Config.env.dig('secret').present? %>
66 | Secret
67 |
68 | <% Deployed::Config.env.dig('secret').each do |secret_env| %>
69 | -
70 | <%= secret_env %>
71 | <%= right_arrow %>
72 | <% if Deployed::Config.env_values[secret_env].present? %>
73 |
74 | <%= redacted_string = '*' * (Deployed::Config.env_values[secret_env].length - 6) + Deployed::Config.env_values[secret_env][-6..-1] %>
75 |
76 | <% else %>
77 | Not found
78 | <% end %>
79 |
80 | <% end %>
81 |
82 | <% end %>
83 |
84 | <% if Deployed::Config.env['clear'].present? %>
85 | Secret
86 |
87 | <% Deployed::Config.env['clear'].each do |secret_env| %>
88 | -
89 | <%= secret_env %>
90 | <%= right_arrow %>
91 | <% if Deployed::Config.env_values[secret_env].present? %>
92 |
93 | <%= Deployed::Config.env_values[secret_env] %>
94 |
95 | <% else %>
96 | Not found
97 | <% end %>
98 |
99 | <% end %>
100 |
101 | <% end %>
102 |
103 |
104 |
105 | <% end %>
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | <%= tools_icon %>
114 | Utilities
115 |
116 |
117 |
118 |
119 |
120 |
<%= kamal_exec_button(label: 'Perform Healthcheck', command: 'healthcheck --verbose') %>
121 |
122 | <%= kamal_exec_button(label: 'Check Lock Status', command: 'lock status') %>
123 | <%= kamal_exec_button(label: 'Release Lock', command: 'lock release') %>
124 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/app/views/layouts/deployed/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Deployed: The Deployment Rails Engine
5 | <%= csrf_meta_tags %>
6 | <%= csp_meta_tag %>
7 |
8 | <%= stylesheet_link_tag "deployed/deployed", 'data-turbo-track': 'reload' %>
9 | <%= javascript_include_tag "deployed/application", type: "module" %>
10 |
32 |
33 |
34 |
35 | Process Running
36 |
37 |
38 | Configuration Required
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | DEPLOYED
48 |
49 |
50 |
51 | v<%= Deployed::VERSION %>
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | <%= yield %>
62 |
63 |
64 |
65 |
66 |
67 |
68 | <%= deploy_output_resize_handler %>
69 |
70 |
71 |
83 |
84 |
85 |
86 | <%= turbo_frame_tag('deployed-init', src: setup_path, target: '_top') if Deployed::Config.requires_init %>
87 |
88 |
89 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails gems
3 | # installed from the root of your application.
4 |
5 | ENGINE_ROOT = File.expand_path("..", __dir__)
6 | ENGINE_PATH = File.expand_path("../lib/deployed/engine", __dir__)
7 | APP_PATH = File.expand_path("../test/dummy/config/application", __dir__)
8 |
9 | # Set up gems listed in the Gemfile.
10 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
11 | require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
12 |
13 | require "rails/all"
14 | require "rails/engine/commands"
15 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | npm install -D tailwindcss
4 | npm install -D @tailwindcss/aspect-ratio
5 | npm install -D @tailwindcss/typography
6 | npm install -D @tailwindcss/container-queries
7 |
8 | bundle
9 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | Deployed::Engine.routes.draw do
2 | get 'setup', to: 'setup#new'
3 | post 'setup', to: 'setup#create'
4 | get 'config', to: 'config#show'
5 | get 'git/uncommitted_check', to: 'git#uncommitted_check'
6 | post 'execute', to: 'run#execute'
7 | post 'cancel', to: 'run#cancel'
8 | get 'log_output', to: 'log_output#index'
9 | root to: 'welcome#index'
10 | end
11 |
--------------------------------------------------------------------------------
/deployed.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative 'lib/deployed/version'
4 |
5 | Gem::Specification.new do |spec|
6 | spec.name = 'deployed'
7 | spec.version = Deployed::VERSION
8 | spec.authors = ['Simon Chiu']
9 | spec.email = ['simon@furvur.com']
10 | spec.homepage = 'https://github.com/geetfun/deployed'
11 | spec.summary = 'Mountable Rails engine to manage Kamal commands'
12 | spec.description = 'Mountable Rails engine to manage Kamal commands'
13 | spec.license = 'MIT'
14 |
15 | # Prevent pushing this gem to RubyGems.org. To allow pushes either set the "allowed_push_host"
16 | # to allow pushing to a single host or delete this section to allow pushing to any host.
17 | spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18 |
19 | spec.metadata['homepage_uri'] = spec.homepage
20 | spec.metadata['source_code_uri'] = 'https://github.com/geetfun/deployed'
21 | spec.metadata['changelog_uri'] = 'https://github.com/geetfun/deployed/blob/main/CHANGELOG.md'
22 |
23 | spec.files = Dir.chdir(File.expand_path(__dir__)) do
24 | Dir['{app,config,db,lib}/**/*', 'MIT-LICENSE', 'Rakefile', 'README.md']
25 | end
26 |
27 | spec.add_dependency 'kamal', '~> 1.0'
28 | spec.add_dependency 'turbo-rails', '~> 1.5'
29 | spec.add_dependency 'rails', '>= 7.1.1'
30 | end
31 |
--------------------------------------------------------------------------------
/lib/deployed.rb:
--------------------------------------------------------------------------------
1 | require 'deployed/version'
2 | require 'deployed/engine'
3 |
4 | module Deployed
5 | DIRECTORY = '.deployed'
6 |
7 | def self.setup!
8 | # Ensure directory is set up
9 | directory_path = Rails.root.join(DIRECTORY)
10 |
11 | unless File.directory?(directory_path)
12 | Dir.mkdir(directory_path)
13 | end
14 |
15 | # Ensure we read the config
16 | Deployed::Config.init!
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/deployed/engine.rb:
--------------------------------------------------------------------------------
1 | module Deployed
2 | class Engine < ::Rails::Engine
3 | isolate_namespace Deployed
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/lib/deployed/version.rb:
--------------------------------------------------------------------------------
1 | module Deployed
2 | VERSION = "0.1.3"
3 | end
4 |
--------------------------------------------------------------------------------
/lib/tasks/deployed_tasks.rake:
--------------------------------------------------------------------------------
1 | # lib/tasks/deployed.rake
2 |
3 | namespace :deployed do
4 | desc "Execute a Kamal command and log its output"
5 | task :execute_and_log, [:command] => :environment do |task, args|
6 | command = args[:command]
7 |
8 | unless command
9 | puts "Please provide a Kamal command. Usage: rake deployed:execute_and_log[command]"
10 | next
11 | end
12 |
13 | log_file = Rails.root.join(Deployed::DIRECTORY, 'deployments/current.log')
14 |
15 | File.open(log_file, 'a') do |file|
16 | IO.popen("kamal #{command}") do |io|
17 | start_time = Time.now
18 |
19 | file.puts("[Deployed] > kamal #{command}")
20 | file.fsync
21 |
22 | io.each_line do |line|
23 | file.puts line
24 | file.fsync # Force data to be written to disk immediately
25 | end
26 | end_time = Time.now
27 | file.puts("[Deployed] Finished in #{end_time - start_time} seconds")
28 | file.puts("[Deployed] End")
29 | file.fsync
30 |
31 | # Delete lockfile
32 | File.delete(Rails.root.join(Deployed::DIRECTORY, 'process.lock'))
33 | end
34 | end
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "deployed",
3 | "lockfileVersion": 3,
4 | "requires": true,
5 | "packages": {
6 | "": {
7 | "devDependencies": {
8 | "@tailwindcss/aspect-ratio": "^0.4.2",
9 | "@tailwindcss/container-queries": "^0.1.1",
10 | "@tailwindcss/forms": "^0.5.6",
11 | "@tailwindcss/typography": "^0.5.10",
12 | "tailwindcss": "^3.3.3"
13 | }
14 | },
15 | "node_modules/@alloc/quick-lru": {
16 | "version": "5.2.0",
17 | "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
18 | "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
19 | "dev": true,
20 | "engines": {
21 | "node": ">=10"
22 | },
23 | "funding": {
24 | "url": "https://github.com/sponsors/sindresorhus"
25 | }
26 | },
27 | "node_modules/@jridgewell/gen-mapping": {
28 | "version": "0.3.3",
29 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
30 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
31 | "dev": true,
32 | "dependencies": {
33 | "@jridgewell/set-array": "^1.0.1",
34 | "@jridgewell/sourcemap-codec": "^1.4.10",
35 | "@jridgewell/trace-mapping": "^0.3.9"
36 | },
37 | "engines": {
38 | "node": ">=6.0.0"
39 | }
40 | },
41 | "node_modules/@jridgewell/resolve-uri": {
42 | "version": "3.1.1",
43 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
44 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
45 | "dev": true,
46 | "engines": {
47 | "node": ">=6.0.0"
48 | }
49 | },
50 | "node_modules/@jridgewell/set-array": {
51 | "version": "1.1.2",
52 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
53 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
54 | "dev": true,
55 | "engines": {
56 | "node": ">=6.0.0"
57 | }
58 | },
59 | "node_modules/@jridgewell/sourcemap-codec": {
60 | "version": "1.4.15",
61 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
62 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
63 | "dev": true
64 | },
65 | "node_modules/@jridgewell/trace-mapping": {
66 | "version": "0.3.20",
67 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
68 | "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
69 | "dev": true,
70 | "dependencies": {
71 | "@jridgewell/resolve-uri": "^3.1.0",
72 | "@jridgewell/sourcemap-codec": "^1.4.14"
73 | }
74 | },
75 | "node_modules/@nodelib/fs.scandir": {
76 | "version": "2.1.5",
77 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
78 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
79 | "dev": true,
80 | "dependencies": {
81 | "@nodelib/fs.stat": "2.0.5",
82 | "run-parallel": "^1.1.9"
83 | },
84 | "engines": {
85 | "node": ">= 8"
86 | }
87 | },
88 | "node_modules/@nodelib/fs.stat": {
89 | "version": "2.0.5",
90 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
91 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
92 | "dev": true,
93 | "engines": {
94 | "node": ">= 8"
95 | }
96 | },
97 | "node_modules/@nodelib/fs.walk": {
98 | "version": "1.2.8",
99 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
100 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
101 | "dev": true,
102 | "dependencies": {
103 | "@nodelib/fs.scandir": "2.1.5",
104 | "fastq": "^1.6.0"
105 | },
106 | "engines": {
107 | "node": ">= 8"
108 | }
109 | },
110 | "node_modules/@tailwindcss/aspect-ratio": {
111 | "version": "0.4.2",
112 | "resolved": "https://registry.npmjs.org/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz",
113 | "integrity": "sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==",
114 | "dev": true,
115 | "peerDependencies": {
116 | "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1"
117 | }
118 | },
119 | "node_modules/@tailwindcss/container-queries": {
120 | "version": "0.1.1",
121 | "resolved": "https://registry.npmjs.org/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz",
122 | "integrity": "sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==",
123 | "dev": true,
124 | "peerDependencies": {
125 | "tailwindcss": ">=3.2.0"
126 | }
127 | },
128 | "node_modules/@tailwindcss/forms": {
129 | "version": "0.5.6",
130 | "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.6.tgz",
131 | "integrity": "sha512-Fw+2BJ0tmAwK/w01tEFL5TiaJBX1NLT1/YbWgvm7ws3Qcn11kiXxzNTEQDMs5V3mQemhB56l3u0i9dwdzSQldA==",
132 | "dev": true,
133 | "dependencies": {
134 | "mini-svg-data-uri": "^1.2.3"
135 | },
136 | "peerDependencies": {
137 | "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1"
138 | }
139 | },
140 | "node_modules/@tailwindcss/typography": {
141 | "version": "0.5.10",
142 | "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz",
143 | "integrity": "sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==",
144 | "dev": true,
145 | "dependencies": {
146 | "lodash.castarray": "^4.4.0",
147 | "lodash.isplainobject": "^4.0.6",
148 | "lodash.merge": "^4.6.2",
149 | "postcss-selector-parser": "6.0.10"
150 | },
151 | "peerDependencies": {
152 | "tailwindcss": ">=3.0.0 || insiders"
153 | }
154 | },
155 | "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": {
156 | "version": "6.0.10",
157 | "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
158 | "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
159 | "dev": true,
160 | "dependencies": {
161 | "cssesc": "^3.0.0",
162 | "util-deprecate": "^1.0.2"
163 | },
164 | "engines": {
165 | "node": ">=4"
166 | }
167 | },
168 | "node_modules/any-promise": {
169 | "version": "1.3.0",
170 | "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
171 | "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
172 | "dev": true
173 | },
174 | "node_modules/anymatch": {
175 | "version": "3.1.3",
176 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
177 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
178 | "dev": true,
179 | "dependencies": {
180 | "normalize-path": "^3.0.0",
181 | "picomatch": "^2.0.4"
182 | },
183 | "engines": {
184 | "node": ">= 8"
185 | }
186 | },
187 | "node_modules/arg": {
188 | "version": "5.0.2",
189 | "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
190 | "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
191 | "dev": true
192 | },
193 | "node_modules/balanced-match": {
194 | "version": "1.0.2",
195 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
196 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
197 | "dev": true
198 | },
199 | "node_modules/binary-extensions": {
200 | "version": "2.2.0",
201 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
202 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
203 | "dev": true,
204 | "engines": {
205 | "node": ">=8"
206 | }
207 | },
208 | "node_modules/brace-expansion": {
209 | "version": "1.1.11",
210 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
211 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
212 | "dev": true,
213 | "dependencies": {
214 | "balanced-match": "^1.0.0",
215 | "concat-map": "0.0.1"
216 | }
217 | },
218 | "node_modules/braces": {
219 | "version": "3.0.2",
220 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
221 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
222 | "dev": true,
223 | "dependencies": {
224 | "fill-range": "^7.0.1"
225 | },
226 | "engines": {
227 | "node": ">=8"
228 | }
229 | },
230 | "node_modules/camelcase-css": {
231 | "version": "2.0.1",
232 | "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
233 | "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
234 | "dev": true,
235 | "engines": {
236 | "node": ">= 6"
237 | }
238 | },
239 | "node_modules/chokidar": {
240 | "version": "3.5.3",
241 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
242 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
243 | "dev": true,
244 | "funding": [
245 | {
246 | "type": "individual",
247 | "url": "https://paulmillr.com/funding/"
248 | }
249 | ],
250 | "dependencies": {
251 | "anymatch": "~3.1.2",
252 | "braces": "~3.0.2",
253 | "glob-parent": "~5.1.2",
254 | "is-binary-path": "~2.1.0",
255 | "is-glob": "~4.0.1",
256 | "normalize-path": "~3.0.0",
257 | "readdirp": "~3.6.0"
258 | },
259 | "engines": {
260 | "node": ">= 8.10.0"
261 | },
262 | "optionalDependencies": {
263 | "fsevents": "~2.3.2"
264 | }
265 | },
266 | "node_modules/chokidar/node_modules/glob-parent": {
267 | "version": "5.1.2",
268 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
269 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
270 | "dev": true,
271 | "dependencies": {
272 | "is-glob": "^4.0.1"
273 | },
274 | "engines": {
275 | "node": ">= 6"
276 | }
277 | },
278 | "node_modules/commander": {
279 | "version": "4.1.1",
280 | "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
281 | "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
282 | "dev": true,
283 | "engines": {
284 | "node": ">= 6"
285 | }
286 | },
287 | "node_modules/concat-map": {
288 | "version": "0.0.1",
289 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
290 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
291 | "dev": true
292 | },
293 | "node_modules/cssesc": {
294 | "version": "3.0.0",
295 | "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
296 | "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
297 | "dev": true,
298 | "bin": {
299 | "cssesc": "bin/cssesc"
300 | },
301 | "engines": {
302 | "node": ">=4"
303 | }
304 | },
305 | "node_modules/didyoumean": {
306 | "version": "1.2.2",
307 | "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
308 | "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
309 | "dev": true
310 | },
311 | "node_modules/dlv": {
312 | "version": "1.1.3",
313 | "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
314 | "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
315 | "dev": true
316 | },
317 | "node_modules/fast-glob": {
318 | "version": "3.3.1",
319 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
320 | "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
321 | "dev": true,
322 | "dependencies": {
323 | "@nodelib/fs.stat": "^2.0.2",
324 | "@nodelib/fs.walk": "^1.2.3",
325 | "glob-parent": "^5.1.2",
326 | "merge2": "^1.3.0",
327 | "micromatch": "^4.0.4"
328 | },
329 | "engines": {
330 | "node": ">=8.6.0"
331 | }
332 | },
333 | "node_modules/fast-glob/node_modules/glob-parent": {
334 | "version": "5.1.2",
335 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
336 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
337 | "dev": true,
338 | "dependencies": {
339 | "is-glob": "^4.0.1"
340 | },
341 | "engines": {
342 | "node": ">= 6"
343 | }
344 | },
345 | "node_modules/fastq": {
346 | "version": "1.15.0",
347 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
348 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
349 | "dev": true,
350 | "dependencies": {
351 | "reusify": "^1.0.4"
352 | }
353 | },
354 | "node_modules/fill-range": {
355 | "version": "7.0.1",
356 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
357 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
358 | "dev": true,
359 | "dependencies": {
360 | "to-regex-range": "^5.0.1"
361 | },
362 | "engines": {
363 | "node": ">=8"
364 | }
365 | },
366 | "node_modules/fs.realpath": {
367 | "version": "1.0.0",
368 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
369 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
370 | "dev": true
371 | },
372 | "node_modules/fsevents": {
373 | "version": "2.3.3",
374 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
375 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
376 | "dev": true,
377 | "hasInstallScript": true,
378 | "optional": true,
379 | "os": [
380 | "darwin"
381 | ],
382 | "engines": {
383 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
384 | }
385 | },
386 | "node_modules/glob": {
387 | "version": "7.1.6",
388 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
389 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
390 | "dev": true,
391 | "dependencies": {
392 | "fs.realpath": "^1.0.0",
393 | "inflight": "^1.0.4",
394 | "inherits": "2",
395 | "minimatch": "^3.0.4",
396 | "once": "^1.3.0",
397 | "path-is-absolute": "^1.0.0"
398 | },
399 | "engines": {
400 | "node": "*"
401 | },
402 | "funding": {
403 | "url": "https://github.com/sponsors/isaacs"
404 | }
405 | },
406 | "node_modules/glob-parent": {
407 | "version": "6.0.2",
408 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
409 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
410 | "dev": true,
411 | "dependencies": {
412 | "is-glob": "^4.0.3"
413 | },
414 | "engines": {
415 | "node": ">=10.13.0"
416 | }
417 | },
418 | "node_modules/has": {
419 | "version": "1.0.4",
420 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
421 | "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
422 | "dev": true,
423 | "engines": {
424 | "node": ">= 0.4.0"
425 | }
426 | },
427 | "node_modules/inflight": {
428 | "version": "1.0.6",
429 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
430 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
431 | "dev": true,
432 | "dependencies": {
433 | "once": "^1.3.0",
434 | "wrappy": "1"
435 | }
436 | },
437 | "node_modules/inherits": {
438 | "version": "2.0.4",
439 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
440 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
441 | "dev": true
442 | },
443 | "node_modules/is-binary-path": {
444 | "version": "2.1.0",
445 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
446 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
447 | "dev": true,
448 | "dependencies": {
449 | "binary-extensions": "^2.0.0"
450 | },
451 | "engines": {
452 | "node": ">=8"
453 | }
454 | },
455 | "node_modules/is-core-module": {
456 | "version": "2.13.0",
457 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
458 | "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
459 | "dev": true,
460 | "dependencies": {
461 | "has": "^1.0.3"
462 | },
463 | "funding": {
464 | "url": "https://github.com/sponsors/ljharb"
465 | }
466 | },
467 | "node_modules/is-extglob": {
468 | "version": "2.1.1",
469 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
470 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
471 | "dev": true,
472 | "engines": {
473 | "node": ">=0.10.0"
474 | }
475 | },
476 | "node_modules/is-glob": {
477 | "version": "4.0.3",
478 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
479 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
480 | "dev": true,
481 | "dependencies": {
482 | "is-extglob": "^2.1.1"
483 | },
484 | "engines": {
485 | "node": ">=0.10.0"
486 | }
487 | },
488 | "node_modules/is-number": {
489 | "version": "7.0.0",
490 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
491 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
492 | "dev": true,
493 | "engines": {
494 | "node": ">=0.12.0"
495 | }
496 | },
497 | "node_modules/jiti": {
498 | "version": "1.20.0",
499 | "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz",
500 | "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==",
501 | "dev": true,
502 | "bin": {
503 | "jiti": "bin/jiti.js"
504 | }
505 | },
506 | "node_modules/lilconfig": {
507 | "version": "2.1.0",
508 | "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
509 | "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
510 | "dev": true,
511 | "engines": {
512 | "node": ">=10"
513 | }
514 | },
515 | "node_modules/lines-and-columns": {
516 | "version": "1.2.4",
517 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
518 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
519 | "dev": true
520 | },
521 | "node_modules/lodash.castarray": {
522 | "version": "4.4.0",
523 | "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
524 | "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
525 | "dev": true
526 | },
527 | "node_modules/lodash.isplainobject": {
528 | "version": "4.0.6",
529 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
530 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
531 | "dev": true
532 | },
533 | "node_modules/lodash.merge": {
534 | "version": "4.6.2",
535 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
536 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
537 | "dev": true
538 | },
539 | "node_modules/merge2": {
540 | "version": "1.4.1",
541 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
542 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
543 | "dev": true,
544 | "engines": {
545 | "node": ">= 8"
546 | }
547 | },
548 | "node_modules/micromatch": {
549 | "version": "4.0.5",
550 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
551 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
552 | "dev": true,
553 | "dependencies": {
554 | "braces": "^3.0.2",
555 | "picomatch": "^2.3.1"
556 | },
557 | "engines": {
558 | "node": ">=8.6"
559 | }
560 | },
561 | "node_modules/mini-svg-data-uri": {
562 | "version": "1.4.4",
563 | "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
564 | "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
565 | "dev": true,
566 | "bin": {
567 | "mini-svg-data-uri": "cli.js"
568 | }
569 | },
570 | "node_modules/minimatch": {
571 | "version": "3.1.2",
572 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
573 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
574 | "dev": true,
575 | "dependencies": {
576 | "brace-expansion": "^1.1.7"
577 | },
578 | "engines": {
579 | "node": "*"
580 | }
581 | },
582 | "node_modules/mz": {
583 | "version": "2.7.0",
584 | "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
585 | "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
586 | "dev": true,
587 | "dependencies": {
588 | "any-promise": "^1.0.0",
589 | "object-assign": "^4.0.1",
590 | "thenify-all": "^1.0.0"
591 | }
592 | },
593 | "node_modules/nanoid": {
594 | "version": "3.3.6",
595 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
596 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
597 | "dev": true,
598 | "funding": [
599 | {
600 | "type": "github",
601 | "url": "https://github.com/sponsors/ai"
602 | }
603 | ],
604 | "bin": {
605 | "nanoid": "bin/nanoid.cjs"
606 | },
607 | "engines": {
608 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
609 | }
610 | },
611 | "node_modules/normalize-path": {
612 | "version": "3.0.0",
613 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
614 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
615 | "dev": true,
616 | "engines": {
617 | "node": ">=0.10.0"
618 | }
619 | },
620 | "node_modules/object-assign": {
621 | "version": "4.1.1",
622 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
623 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
624 | "dev": true,
625 | "engines": {
626 | "node": ">=0.10.0"
627 | }
628 | },
629 | "node_modules/object-hash": {
630 | "version": "3.0.0",
631 | "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
632 | "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
633 | "dev": true,
634 | "engines": {
635 | "node": ">= 6"
636 | }
637 | },
638 | "node_modules/once": {
639 | "version": "1.4.0",
640 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
641 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
642 | "dev": true,
643 | "dependencies": {
644 | "wrappy": "1"
645 | }
646 | },
647 | "node_modules/path-is-absolute": {
648 | "version": "1.0.1",
649 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
650 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
651 | "dev": true,
652 | "engines": {
653 | "node": ">=0.10.0"
654 | }
655 | },
656 | "node_modules/path-parse": {
657 | "version": "1.0.7",
658 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
659 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
660 | "dev": true
661 | },
662 | "node_modules/picocolors": {
663 | "version": "1.0.0",
664 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
665 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
666 | "dev": true
667 | },
668 | "node_modules/picomatch": {
669 | "version": "2.3.1",
670 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
671 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
672 | "dev": true,
673 | "engines": {
674 | "node": ">=8.6"
675 | },
676 | "funding": {
677 | "url": "https://github.com/sponsors/jonschlinkert"
678 | }
679 | },
680 | "node_modules/pify": {
681 | "version": "2.3.0",
682 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
683 | "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
684 | "dev": true,
685 | "engines": {
686 | "node": ">=0.10.0"
687 | }
688 | },
689 | "node_modules/pirates": {
690 | "version": "4.0.6",
691 | "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
692 | "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
693 | "dev": true,
694 | "engines": {
695 | "node": ">= 6"
696 | }
697 | },
698 | "node_modules/postcss": {
699 | "version": "8.4.31",
700 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
701 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
702 | "dev": true,
703 | "funding": [
704 | {
705 | "type": "opencollective",
706 | "url": "https://opencollective.com/postcss/"
707 | },
708 | {
709 | "type": "tidelift",
710 | "url": "https://tidelift.com/funding/github/npm/postcss"
711 | },
712 | {
713 | "type": "github",
714 | "url": "https://github.com/sponsors/ai"
715 | }
716 | ],
717 | "dependencies": {
718 | "nanoid": "^3.3.6",
719 | "picocolors": "^1.0.0",
720 | "source-map-js": "^1.0.2"
721 | },
722 | "engines": {
723 | "node": "^10 || ^12 || >=14"
724 | }
725 | },
726 | "node_modules/postcss-import": {
727 | "version": "15.1.0",
728 | "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
729 | "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
730 | "dev": true,
731 | "dependencies": {
732 | "postcss-value-parser": "^4.0.0",
733 | "read-cache": "^1.0.0",
734 | "resolve": "^1.1.7"
735 | },
736 | "engines": {
737 | "node": ">=14.0.0"
738 | },
739 | "peerDependencies": {
740 | "postcss": "^8.0.0"
741 | }
742 | },
743 | "node_modules/postcss-js": {
744 | "version": "4.0.1",
745 | "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
746 | "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
747 | "dev": true,
748 | "dependencies": {
749 | "camelcase-css": "^2.0.1"
750 | },
751 | "engines": {
752 | "node": "^12 || ^14 || >= 16"
753 | },
754 | "funding": {
755 | "type": "opencollective",
756 | "url": "https://opencollective.com/postcss/"
757 | },
758 | "peerDependencies": {
759 | "postcss": "^8.4.21"
760 | }
761 | },
762 | "node_modules/postcss-load-config": {
763 | "version": "4.0.1",
764 | "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz",
765 | "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==",
766 | "dev": true,
767 | "dependencies": {
768 | "lilconfig": "^2.0.5",
769 | "yaml": "^2.1.1"
770 | },
771 | "engines": {
772 | "node": ">= 14"
773 | },
774 | "funding": {
775 | "type": "opencollective",
776 | "url": "https://opencollective.com/postcss/"
777 | },
778 | "peerDependencies": {
779 | "postcss": ">=8.0.9",
780 | "ts-node": ">=9.0.0"
781 | },
782 | "peerDependenciesMeta": {
783 | "postcss": {
784 | "optional": true
785 | },
786 | "ts-node": {
787 | "optional": true
788 | }
789 | }
790 | },
791 | "node_modules/postcss-nested": {
792 | "version": "6.0.1",
793 | "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
794 | "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
795 | "dev": true,
796 | "dependencies": {
797 | "postcss-selector-parser": "^6.0.11"
798 | },
799 | "engines": {
800 | "node": ">=12.0"
801 | },
802 | "funding": {
803 | "type": "opencollective",
804 | "url": "https://opencollective.com/postcss/"
805 | },
806 | "peerDependencies": {
807 | "postcss": "^8.2.14"
808 | }
809 | },
810 | "node_modules/postcss-selector-parser": {
811 | "version": "6.0.13",
812 | "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
813 | "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
814 | "dev": true,
815 | "dependencies": {
816 | "cssesc": "^3.0.0",
817 | "util-deprecate": "^1.0.2"
818 | },
819 | "engines": {
820 | "node": ">=4"
821 | }
822 | },
823 | "node_modules/postcss-value-parser": {
824 | "version": "4.2.0",
825 | "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
826 | "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
827 | "dev": true
828 | },
829 | "node_modules/queue-microtask": {
830 | "version": "1.2.3",
831 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
832 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
833 | "dev": true,
834 | "funding": [
835 | {
836 | "type": "github",
837 | "url": "https://github.com/sponsors/feross"
838 | },
839 | {
840 | "type": "patreon",
841 | "url": "https://www.patreon.com/feross"
842 | },
843 | {
844 | "type": "consulting",
845 | "url": "https://feross.org/support"
846 | }
847 | ]
848 | },
849 | "node_modules/read-cache": {
850 | "version": "1.0.0",
851 | "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
852 | "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
853 | "dev": true,
854 | "dependencies": {
855 | "pify": "^2.3.0"
856 | }
857 | },
858 | "node_modules/readdirp": {
859 | "version": "3.6.0",
860 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
861 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
862 | "dev": true,
863 | "dependencies": {
864 | "picomatch": "^2.2.1"
865 | },
866 | "engines": {
867 | "node": ">=8.10.0"
868 | }
869 | },
870 | "node_modules/resolve": {
871 | "version": "1.22.8",
872 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
873 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
874 | "dev": true,
875 | "dependencies": {
876 | "is-core-module": "^2.13.0",
877 | "path-parse": "^1.0.7",
878 | "supports-preserve-symlinks-flag": "^1.0.0"
879 | },
880 | "bin": {
881 | "resolve": "bin/resolve"
882 | },
883 | "funding": {
884 | "url": "https://github.com/sponsors/ljharb"
885 | }
886 | },
887 | "node_modules/reusify": {
888 | "version": "1.0.4",
889 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
890 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
891 | "dev": true,
892 | "engines": {
893 | "iojs": ">=1.0.0",
894 | "node": ">=0.10.0"
895 | }
896 | },
897 | "node_modules/run-parallel": {
898 | "version": "1.2.0",
899 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
900 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
901 | "dev": true,
902 | "funding": [
903 | {
904 | "type": "github",
905 | "url": "https://github.com/sponsors/feross"
906 | },
907 | {
908 | "type": "patreon",
909 | "url": "https://www.patreon.com/feross"
910 | },
911 | {
912 | "type": "consulting",
913 | "url": "https://feross.org/support"
914 | }
915 | ],
916 | "dependencies": {
917 | "queue-microtask": "^1.2.2"
918 | }
919 | },
920 | "node_modules/source-map-js": {
921 | "version": "1.0.2",
922 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
923 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
924 | "dev": true,
925 | "engines": {
926 | "node": ">=0.10.0"
927 | }
928 | },
929 | "node_modules/sucrase": {
930 | "version": "3.34.0",
931 | "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
932 | "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==",
933 | "dev": true,
934 | "dependencies": {
935 | "@jridgewell/gen-mapping": "^0.3.2",
936 | "commander": "^4.0.0",
937 | "glob": "7.1.6",
938 | "lines-and-columns": "^1.1.6",
939 | "mz": "^2.7.0",
940 | "pirates": "^4.0.1",
941 | "ts-interface-checker": "^0.1.9"
942 | },
943 | "bin": {
944 | "sucrase": "bin/sucrase",
945 | "sucrase-node": "bin/sucrase-node"
946 | },
947 | "engines": {
948 | "node": ">=8"
949 | }
950 | },
951 | "node_modules/supports-preserve-symlinks-flag": {
952 | "version": "1.0.0",
953 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
954 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
955 | "dev": true,
956 | "engines": {
957 | "node": ">= 0.4"
958 | },
959 | "funding": {
960 | "url": "https://github.com/sponsors/ljharb"
961 | }
962 | },
963 | "node_modules/tailwindcss": {
964 | "version": "3.3.3",
965 | "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz",
966 | "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==",
967 | "dev": true,
968 | "dependencies": {
969 | "@alloc/quick-lru": "^5.2.0",
970 | "arg": "^5.0.2",
971 | "chokidar": "^3.5.3",
972 | "didyoumean": "^1.2.2",
973 | "dlv": "^1.1.3",
974 | "fast-glob": "^3.2.12",
975 | "glob-parent": "^6.0.2",
976 | "is-glob": "^4.0.3",
977 | "jiti": "^1.18.2",
978 | "lilconfig": "^2.1.0",
979 | "micromatch": "^4.0.5",
980 | "normalize-path": "^3.0.0",
981 | "object-hash": "^3.0.0",
982 | "picocolors": "^1.0.0",
983 | "postcss": "^8.4.23",
984 | "postcss-import": "^15.1.0",
985 | "postcss-js": "^4.0.1",
986 | "postcss-load-config": "^4.0.1",
987 | "postcss-nested": "^6.0.1",
988 | "postcss-selector-parser": "^6.0.11",
989 | "resolve": "^1.22.2",
990 | "sucrase": "^3.32.0"
991 | },
992 | "bin": {
993 | "tailwind": "lib/cli.js",
994 | "tailwindcss": "lib/cli.js"
995 | },
996 | "engines": {
997 | "node": ">=14.0.0"
998 | }
999 | },
1000 | "node_modules/thenify": {
1001 | "version": "3.3.1",
1002 | "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
1003 | "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
1004 | "dev": true,
1005 | "dependencies": {
1006 | "any-promise": "^1.0.0"
1007 | }
1008 | },
1009 | "node_modules/thenify-all": {
1010 | "version": "1.6.0",
1011 | "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
1012 | "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
1013 | "dev": true,
1014 | "dependencies": {
1015 | "thenify": ">= 3.1.0 < 4"
1016 | },
1017 | "engines": {
1018 | "node": ">=0.8"
1019 | }
1020 | },
1021 | "node_modules/to-regex-range": {
1022 | "version": "5.0.1",
1023 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1024 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1025 | "dev": true,
1026 | "dependencies": {
1027 | "is-number": "^7.0.0"
1028 | },
1029 | "engines": {
1030 | "node": ">=8.0"
1031 | }
1032 | },
1033 | "node_modules/ts-interface-checker": {
1034 | "version": "0.1.13",
1035 | "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
1036 | "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
1037 | "dev": true
1038 | },
1039 | "node_modules/util-deprecate": {
1040 | "version": "1.0.2",
1041 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1042 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
1043 | "dev": true
1044 | },
1045 | "node_modules/wrappy": {
1046 | "version": "1.0.2",
1047 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1048 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
1049 | "dev": true
1050 | },
1051 | "node_modules/yaml": {
1052 | "version": "2.3.3",
1053 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz",
1054 | "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==",
1055 | "dev": true,
1056 | "engines": {
1057 | "node": ">= 14"
1058 | }
1059 | }
1060 | }
1061 | }
1062 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "@tailwindcss/aspect-ratio": "^0.4.2",
4 | "@tailwindcss/container-queries": "^0.1.1",
5 | "@tailwindcss/forms": "^0.5.6",
6 | "@tailwindcss/typography": "^0.5.10",
7 | "tailwindcss": "^3.3.3"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | const defaultTheme = require('tailwindcss/defaultTheme')
3 |
4 | module.exports = {
5 | content: [
6 | './app/**/*.{erb,html,rb,js}'
7 | ],
8 | theme: {
9 | extend: {
10 | fontFamily: {
11 | sans: ['Inter var', ...defaultTheme.fontFamily.sans],
12 | },
13 | },
14 | },
15 | plugins: [
16 | require('@tailwindcss/forms'),
17 | require('@tailwindcss/aspect-ratio'),
18 | require('@tailwindcss/typography'),
19 | require('@tailwindcss/container-queries'),
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/test/controllers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/controllers/.keep
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/config/manifest.js:
--------------------------------------------------------------------------------
1 | //= link_tree ../images
2 | //= link_directory ../stylesheets .css
3 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/images/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/dummy/app/assets/images/.keep
--------------------------------------------------------------------------------
/test/dummy/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, vendor/assets/stylesheets,
6 | * or any plugin's 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_tree .
14 | *= require_self
15 | */
16 |
--------------------------------------------------------------------------------
/test/dummy/app/channels/application_cable/channel.rb:
--------------------------------------------------------------------------------
1 | module ApplicationCable
2 | class Channel < ActionCable::Channel::Base
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/test/dummy/app/channels/application_cable/connection.rb:
--------------------------------------------------------------------------------
1 | module ApplicationCable
2 | class Connection < ActionCable::Connection::Base
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | end
3 |
--------------------------------------------------------------------------------
/test/dummy/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/dummy/app/controllers/concerns/.keep
--------------------------------------------------------------------------------
/test/dummy/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | end
3 |
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/app/mailers/application_mailer.rb:
--------------------------------------------------------------------------------
1 | class ApplicationMailer < ActionMailer::Base
2 | default from: "from@example.com"
3 | layout "mailer"
4 | end
5 |
--------------------------------------------------------------------------------
/test/dummy/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | class ApplicationRecord < ActiveRecord::Base
2 | primary_abstract_class
3 | end
4 |
--------------------------------------------------------------------------------
/test/dummy/app/models/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/dummy/app/models/concerns/.keep
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Dummy
5 |
6 | <%= csrf_meta_tags %>
7 | <%= csp_meta_tag %>
8 |
9 | <%= stylesheet_link_tag "application" %>
10 |
11 |
12 |
13 | <%= yield %>
14 |
15 |
16 |
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/mailer.text.erb:
--------------------------------------------------------------------------------
1 | <%= yield %>
2 |
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative "../config/boot"
3 | require "rake"
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/test/dummy/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, exception: true)
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 |
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/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 Dummy
10 | class Application < Rails::Application
11 | config.load_defaults Rails::VERSION::STRING.to_f
12 |
13 | # For compatibility with applications that use this config
14 | config.action_controller.include_all_helpers = false
15 |
16 | # Please, add to the `ignore` list any other `lib` subdirectories that do
17 | # not contain `.rb` files, or that should not be reloaded or eager loaded.
18 | # Common ones are `templates`, `generators`, or `middleware`, for example.
19 | config.autoload_lib(ignore: %w(assets tasks))
20 |
21 | # Configuration for the application, engines, and railties goes here.
22 | #
23 | # These settings can be overridden in specific environments using the files
24 | # in config/environments, which are processed later.
25 | #
26 | # config.time_zone = "Central Time (US & Canada)"
27 | # config.eager_load_paths << Rails.root.join("extras")
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/test/dummy/config/boot.rb:
--------------------------------------------------------------------------------
1 | # Set up gems listed in the Gemfile.
2 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", __dir__)
3 |
4 | require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
5 | $LOAD_PATH.unshift File.expand_path("../../../lib", __dir__)
6 |
--------------------------------------------------------------------------------
/test/dummy/config/cable.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: async
3 |
4 | test:
5 | adapter: test
6 |
7 | production:
8 | adapter: redis
9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
10 | channel_prefix: dummy_production
11 |
--------------------------------------------------------------------------------
/test/dummy/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite. Versions 3.8.0 and up are supported.
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem "sqlite3"
6 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10 | timeout: 5000
11 |
12 | development:
13 | <<: *default
14 | database: storage/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | <<: *default
21 | database: storage/test.sqlite3
22 |
23 | production:
24 | <<: *default
25 | database: storage/production.sqlite3
26 |
--------------------------------------------------------------------------------
/test/dummy/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative "application"
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/test/dummy/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.enable_reloading = true
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 | # Highlight code that enqueued background job in logs.
60 | config.active_job.verbose_enqueue_logs = true
61 |
62 | # Suppress logger output for asset requests.
63 | config.assets.quiet = true
64 | config.assets.check_precompiled_asset = false
65 |
66 | # Raises error for missing translations.
67 | # config.i18n.raise_on_missing_translations = true
68 |
69 | # Annotate rendered view with file names.
70 | # config.action_view.annotate_rendered_view_with_filenames = true
71 |
72 | # Uncomment if you wish to allow Action Cable access from any origin.
73 | # config.action_cable.disable_request_forgery_protection = true
74 |
75 | # Raise error when a before_action's only/except options reference missing actions
76 | config.action_controller.raise_on_missing_callback_actions = true
77 | end
78 |
--------------------------------------------------------------------------------
/test/dummy/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.enable_reloading = false
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 ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
20 | # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
21 | # config.require_master_key = true
22 |
23 | # Enable static file serving from the `/public` folder (turn off if using NGINX/Apache for it).
24 | config.public_file_server.enabled = true
25 |
26 | # Compress CSS using a preprocessor.
27 | # config.assets.css_compressor = :sass
28 |
29 | # Do not fallback to assets pipeline if a precompiled asset is missed.
30 | config.assets.compile = false
31 |
32 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
33 | # config.asset_host = "http://assets.example.com"
34 |
35 | # Specifies the header that your server uses for sending files.
36 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
37 | # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
38 |
39 | # Store uploaded files on the local file system (see config/storage.yml for options).
40 | config.active_storage.service = :local
41 |
42 | # Mount Action Cable outside main process or domain.
43 | # config.action_cable.mount_path = nil
44 | # config.action_cable.url = "wss://example.com/cable"
45 | # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]
46 |
47 | # Assume all access to the app is happening through a SSL-terminating reverse proxy.
48 | # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
49 | # config.assume_ssl = true
50 |
51 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
52 | config.force_ssl = true
53 |
54 | # Log to STDOUT by default
55 | config.logger = ActiveSupport::Logger.new(STDOUT)
56 | .tap { |logger| logger.formatter = ::Logger::Formatter.new }
57 | .then { |logger| ActiveSupport::TaggedLogging.new(logger) }
58 |
59 | # Prepend all log lines with the following tags.
60 | config.log_tags = [ :request_id ]
61 |
62 | # Info include generic and useful information about system operation, but avoids logging too much
63 | # information to avoid inadvertent exposure of personally identifiable information (PII). If you
64 | # want to log everything, set the level to "debug".
65 | config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
66 |
67 | # Use a different cache store in production.
68 | # config.cache_store = :mem_cache_store
69 |
70 | # Use a real queuing backend for Active Job (and separate queues per environment).
71 | # config.active_job.queue_adapter = :resque
72 | # config.active_job.queue_name_prefix = "dummy_production"
73 |
74 | config.action_mailer.perform_caching = false
75 |
76 | # Ignore bad email addresses and do not raise email delivery errors.
77 | # Set this to true and configure the email server for immediate delivery to raise delivery errors.
78 | # config.action_mailer.raise_delivery_errors = false
79 |
80 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
81 | # the I18n.default_locale when a translation cannot be found).
82 | config.i18n.fallbacks = true
83 |
84 | # Don't log any deprecations.
85 | config.active_support.report_deprecations = false
86 |
87 | # Do not dump schema after migrations.
88 | config.active_record.dump_schema_after_migration = false
89 |
90 | # Enable DNS rebinding protection and other `Host` header attacks.
91 | # config.hosts = [
92 | # "example.com", # Allow requests from example.com
93 | # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
94 | # ]
95 | # Skip DNS rebinding protection for the default health check endpoint.
96 | # config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
97 | end
98 |
--------------------------------------------------------------------------------
/test/dummy/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 | # While tests run files are not watched, reloading is not necessary.
12 | config.enable_reloading = false
13 |
14 | # Eager loading loads your entire application. When running a single test locally,
15 | # this is usually not necessary, and can slow down your test suite. However, it's
16 | # recommended that you enable it in continuous integration systems to ensure eager
17 | # loading is working properly before deploying your code.
18 | config.eager_load = ENV["CI"].present?
19 |
20 | # Configure public file server for tests with Cache-Control for performance.
21 | config.public_file_server.enabled = true
22 | config.public_file_server.headers = {
23 | "Cache-Control" => "public, max-age=#{1.hour.to_i}"
24 | }
25 |
26 | # Show full error reports and disable caching.
27 | config.consider_all_requests_local = true
28 | config.action_controller.perform_caching = false
29 | config.cache_store = :null_store
30 |
31 | # Raise exceptions instead of rendering exception templates.
32 | config.action_dispatch.show_exceptions = :rescuable
33 |
34 | # Disable request forgery protection in test environment.
35 | config.action_controller.allow_forgery_protection = false
36 |
37 | # Store uploaded files on the local file system in a temporary directory.
38 | config.active_storage.service = :test
39 |
40 | config.action_mailer.perform_caching = false
41 |
42 | # Tell Action Mailer not to deliver emails to the real world.
43 | # The :test delivery method accumulates sent emails in the
44 | # ActionMailer::Base.deliveries array.
45 | config.action_mailer.delivery_method = :test
46 |
47 | # Print deprecation notices to the stderr.
48 | config.active_support.deprecation = :stderr
49 |
50 | # Raise exceptions for disallowed deprecations.
51 | config.active_support.disallowed_deprecation = :raise
52 |
53 | # Tell Active Support which deprecation messages to disallow.
54 | config.active_support.disallowed_deprecation_warnings = []
55 |
56 | # Raises error for missing translations.
57 | # config.i18n.raise_on_missing_translations = true
58 |
59 | # Annotate rendered view with file names.
60 | # config.action_view.annotate_rendered_view_with_filenames = true
61 |
62 | # Raise error when a before_action's only/except options reference missing actions
63 | config.action_controller.raise_on_missing_callback_actions = true
64 | end
65 |
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/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, inline scripts, and inline styles.
20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
21 | # config.content_security_policy_nonce_directives = %w(script-src style-src)
22 | #
23 | # # Report violations without enforcing the policy.
24 | # # config.content_security_policy_report_only = true
25 | # end
26 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
4 | # Use this to limit dissemination of sensitive information.
5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
6 | Rails.application.config.filter_parameters += [
7 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
8 | ]
9 |
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/permissions_policy.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Define an application-wide HTTP permissions policy. For further
4 | # information see: https://developers.google.com/web/updates/2018/06/feature-policy
5 |
6 | # Rails.application.config.permissions_policy do |policy|
7 | # policy.camera :none
8 | # policy.gyroscope :none
9 | # policy.microphone :none
10 | # policy.usb :none
11 | # policy.fullscreen :self
12 | # policy.payment :self, "https://secure.example.com"
13 | # end
14 |
--------------------------------------------------------------------------------
/test/dummy/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization and
2 | # are automatically loaded by Rails. If you want to use locales other than
3 | # 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 | # To learn more about the API, please read the Rails Internationalization guide
20 | # at https://guides.rubyonrails.org/i18n.html.
21 | #
22 | # Be aware that YAML interprets the following case-insensitive strings as
23 | # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings
24 | # must be quoted to be interpreted as strings. For example:
25 | #
26 | # en:
27 | # "yes": yup
28 | # enabled: "ON"
29 |
30 | en:
31 | hello: "Hello world"
32 |
--------------------------------------------------------------------------------
/test/dummy/config/puma.rb:
--------------------------------------------------------------------------------
1 | # This configuration file will be evaluated by Puma. The top-level methods that
2 | # are invoked here are part of Puma's configuration DSL. For more information
3 | # about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.
4 |
5 | # Puma can serve each request in a thread from an internal thread pool.
6 | # The `threads` method setting takes two numbers: a minimum and maximum.
7 | # Any libraries that use thread pools should be configured to match
8 | # the maximum value specified for Puma. Default is set to 5 threads for minimum
9 | # and maximum; this matches the default thread size of Active Record.
10 | max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
11 | min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
12 | threads min_threads_count, max_threads_count
13 |
14 | # Specifies that the worker count should equal the number of processors in production.
15 | if ENV["RAILS_ENV"] == "production"
16 | require "concurrent-ruby"
17 | worker_count = Integer(ENV.fetch("WEB_CONCURRENCY") { Concurrent.physical_processor_count })
18 | workers worker_count if worker_count > 1
19 | end
20 |
21 | # Specifies the `worker_timeout` threshold that Puma will use to wait before
22 | # terminating a worker in development environments.
23 | worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
24 |
25 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
26 | port ENV.fetch("PORT") { 3000 }
27 |
28 | # Specifies the `environment` that Puma will run in.
29 | environment ENV.fetch("RAILS_ENV") { "development" }
30 |
31 | # Specifies the `pidfile` that Puma will use.
32 | pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
33 |
34 | # Allow puma to be restarted by `bin/rails restart` command.
35 | plugin :tmp_restart
36 |
--------------------------------------------------------------------------------
/test/dummy/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | mount Deployed::Engine => "/deployed"
3 | end
4 |
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/config/tailwind.config.js:
--------------------------------------------------------------------------------
1 | const defaultTheme = require('tailwindcss/defaultTheme')
2 |
3 | module.exports = {
4 | content: [
5 | '../public/*.html',
6 | '../app/helpers/**/*.rb',
7 | '../app/javascript/**/*.js',
8 | '../app/views/**/*.{erb,haml,html,slim}'
9 | ],
10 | theme: {
11 | extend: {
12 | fontFamily: {
13 | sans: ['Inter var', ...defaultTheme.fontFamily.sans],
14 | },
15 | },
16 | },
17 | plugins: [
18 | require('@tailwindcss/forms'),
19 | require('@tailwindcss/aspect-ratio'),
20 | require('@tailwindcss/typography'),
21 | require('@tailwindcss/container-queries'),
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/test/dummy/lib/assets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/dummy/lib/assets/.keep
--------------------------------------------------------------------------------
/test/dummy/log/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/dummy/log/.keep
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/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 |
--------------------------------------------------------------------------------
/test/dummy/public/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/dummy/public/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/test/dummy/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/dummy/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/test/dummy/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/dummy/public/favicon.ico
--------------------------------------------------------------------------------
/test/fixtures/files/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/fixtures/files/.keep
--------------------------------------------------------------------------------
/test/helpers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/helpers/.keep
--------------------------------------------------------------------------------
/test/integration/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/integration/.keep
--------------------------------------------------------------------------------
/test/integration/navigation_test.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class NavigationTest < ActionDispatch::IntegrationTest
4 | # test "the truth" do
5 | # assert true
6 | # end
7 | end
8 |
--------------------------------------------------------------------------------
/test/kamal_rails_test.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class DeployedTest < ActiveSupport::TestCase
4 | test "it has a version number" do
5 | assert Deployed::VERSION
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/mailers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/mailers/.keep
--------------------------------------------------------------------------------
/test/models/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geetfun/deployed/e88439b8822b70d54f4035e8d0feba805d4e4a8c/test/models/.keep
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # Configure Rails Environment
2 | ENV["RAILS_ENV"] = "test"
3 |
4 | require_relative "../test/dummy/config/environment"
5 | ActiveRecord::Migrator.migrations_paths = [File.expand_path("../test/dummy/db/migrate", __dir__)]
6 | ActiveRecord::Migrator.migrations_paths << File.expand_path("../db/migrate", __dir__)
7 | require "rails/test_help"
8 |
9 | # Load fixtures from the engine
10 | if ActiveSupport::TestCase.respond_to?(:fixture_paths=)
11 | ActiveSupport::TestCase.fixture_paths = [File.expand_path("fixtures", __dir__)]
12 | ActionDispatch::IntegrationTest.fixture_paths = ActiveSupport::TestCase.fixture_paths
13 | ActiveSupport::TestCase.file_fixture_path = File.expand_path("fixtures", __dir__) + "/files"
14 | ActiveSupport::TestCase.fixtures :all
15 | end
16 |
--------------------------------------------------------------------------------