good_job 4.13.0 → 4.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/app/controllers/good_job/batches_controller.rb +1 -1
  4. data/app/controllers/good_job/cron_entries_controller.rb +3 -3
  5. data/app/controllers/good_job/frontends_controller.rb +15 -10
  6. data/app/controllers/good_job/jobs_controller.rb +7 -7
  7. data/app/controllers/good_job/pauses_controller.rb +2 -2
  8. data/app/frontend/good_job/application.js +23 -9
  9. data/app/frontend/good_job/modules/form_controller.js +11 -0
  10. data/app/frontend/good_job/vendor/turbo.js +34 -0
  11. data/app/models/good_job/batch.rb +2 -0
  12. data/app/models/good_job/batch_record.rb +2 -0
  13. data/app/models/good_job/job.rb +2 -2
  14. data/app/models/good_job/process.rb +2 -0
  15. data/app/models/good_job/setting.rb +2 -0
  16. data/app/views/good_job/batches/_jobs.erb +4 -4
  17. data/app/views/good_job/batches/_table.erb +2 -2
  18. data/app/views/good_job/batches/show.html.erb +1 -1
  19. data/app/views/good_job/cron_entries/index.html.erb +2 -2
  20. data/app/views/good_job/jobs/_table.erb +12 -9
  21. data/app/views/good_job/jobs/show.html.erb +4 -4
  22. data/app/views/good_job/pauses/_group.html.erb +1 -1
  23. data/app/views/good_job/pauses/_pause.html.erb +1 -1
  24. data/app/views/good_job/shared/_filter.erb +4 -14
  25. data/app/views/good_job/shared/_navbar.erb +6 -6
  26. data/app/views/layouts/good_job/application.html.erb +10 -8
  27. data/config/brakeman.ignore +25 -25
  28. data/lib/generators/good_job/templates/install/migrations/create_good_jobs.rb.erb +1 -1
  29. data/lib/generators/good_job/templates/update/migrations/05_add_index_good_jobs_finished_at_for_cleanup.rb.erb +17 -0
  30. data/lib/generators/good_job/templates/update/migrations/06_remove_extraneous_finished_at_index.rb.erb +17 -0
  31. data/lib/good_job/version.rb +1 -1
  32. data/lib/good_job.rb +1 -1
  33. metadata +5 -3
  34. data/app/frontend/good_job/modules/document_ready.js +0 -7
  35. data/app/frontend/good_job/vendor/rails_ujs.js +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58105c96940dfa3fd32635f82347a87571d94828417977937f181795a87cbc9f
4
- data.tar.gz: 8ef6a8cf16b8365674debd40cb29c16a02fc7e9863ce34b0dfada3eba8215724
3
+ metadata.gz: 3407384b57488071d4631ea643e46bd06c1d7a01d2edb9655a1e65be8d59a62d
4
+ data.tar.gz: 322a40ebccd3081455d7ebefa16811b0a5a745dc3c49090fff422b1fa91593c0
5
5
  SHA512:
6
- metadata.gz: ff39513833a272a1078c0fbdbfac38a7b303a78adc761007dedd0c365cc77b95d1a395e04ba1d57676dff090d4ebdaf0f4564cb80efce6c98554a5b780ce5cd9
7
- data.tar.gz: 072d4b2d4d27f4f262e2e13c1171cd64a88937662b8e64daf4db1e592f5f5e30472345e25d58976c66ce617a08ddc500ecab976269c1622c51bd8604194a781a
6
+ metadata.gz: a77366c7a3fa599505a8d25b1bf56c43633bcec29c68ce58d7bd787dee71813ffa51ff784d6f1ad46e9d8bb5d79029e4ca321e238e8e1b468b29aabbb89f3392
7
+ data.tar.gz: af3dd4540b43b8fb47c8eb7c686e9d67e0942d17a6299dac06887c3b65072844654cdaeaae30d873c1b1c6ecde39a52b25d31a9eb1898c92fee51521e08d064c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [v4.13.1](https://github.com/bensheldon/good_job/tree/v4.13.1) (2025-12-16)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v4.13.0...v4.13.1)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - Adjust indexes on `good_jobs.finished_at` to better support job cleanup [\#1677](https://github.com/bensheldon/good_job/pull/1677) ([mkrfowler](https://github.com/mkrfowler))
10
+
11
+ **Closed issues:**
12
+
13
+ - ui question: meaning of icons in cron job section [\#1651](https://github.com/bensheldon/good_job/issues/1651)
14
+
15
+ **Merged pull requests:**
16
+
17
+ - Add Active Support load hooks for all Active Record classes [\#1699](https://github.com/bensheldon/good_job/pull/1699) ([bensheldon](https://github.com/bensheldon))
18
+ - Replace Rails UJS with Turbo; make navbar badges data-turbo-permanent to not pop-in on every navigation [\#1658](https://github.com/bensheldon/good_job/pull/1658) ([bensheldon](https://github.com/bensheldon))
19
+
3
20
  ## [v4.13.0](https://github.com/bensheldon/good_job/tree/v4.13.0) (2025-12-02)
4
21
 
5
22
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v4.12.1...v4.13.0)
@@ -13,7 +13,7 @@ module GoodJob
13
13
  def retry
14
14
  @batch = GoodJob::Batch.find(params[:id])
15
15
  @batch.retry
16
- redirect_back(fallback_location: batches_path, notice: t(".notice"))
16
+ redirect_back(fallback_location: batches_path, notice: t(".notice"), status: :see_other)
17
17
  end
18
18
  end
19
19
  end
@@ -14,19 +14,19 @@ module GoodJob
14
14
  def enqueue
15
15
  @cron_entry = CronEntry.find(params[:cron_key])
16
16
  use_original_locale { @cron_entry.enqueue(Time.current) }
17
- redirect_back(fallback_location: cron_entries_path, notice: t(".notice"))
17
+ redirect_back(fallback_location: cron_entries_path, notice: t(".notice"), status: :see_other)
18
18
  end
19
19
 
20
20
  def enable
21
21
  @cron_entry = CronEntry.find(params[:cron_key])
22
22
  @cron_entry.enable
23
- redirect_back(fallback_location: cron_entries_path, notice: t(".notice"))
23
+ redirect_back(fallback_location: cron_entries_path, notice: t(".notice"), status: :see_other)
24
24
  end
25
25
 
26
26
  def disable
27
27
  @cron_entry = CronEntry.find(params[:cron_key])
28
28
  @cron_entry.disable
29
- redirect_back(fallback_location: cron_entries_path, notice: t(".notice"))
29
+ redirect_back(fallback_location: cron_entries_path, notice: t(".notice"), status: :see_other)
30
30
  end
31
31
  end
32
32
  end
@@ -5,29 +5,34 @@ module GoodJob
5
5
  protect_from_forgery with: :exception
6
6
  skip_after_action :verify_same_origin_request, raise: false
7
7
 
8
+ def self.asset_path(*path)
9
+ Engine.root.join("app/frontend/good_job", *path)
10
+ end
11
+
8
12
  STATIC_ASSETS = {
9
13
  css: {
10
- bootstrap: GoodJob::Engine.root.join("app", "frontend", "good_job", "vendor", "bootstrap", "bootstrap.min.css"),
11
- style: GoodJob::Engine.root.join("app", "frontend", "good_job", "style.css"),
14
+ bootstrap: asset_path("vendor", "bootstrap", "bootstrap.min.css"),
15
+ style: asset_path("style.css"),
12
16
  },
13
17
  js: {
14
- bootstrap: GoodJob::Engine.root.join("app", "frontend", "good_job", "vendor", "bootstrap", "bootstrap.bundle.min.js"),
15
- chartjs: GoodJob::Engine.root.join("app", "frontend", "good_job", "vendor", "chartjs", "chart.min.js"),
16
- es_module_shims: GoodJob::Engine.root.join("app", "frontend", "good_job", "vendor", "es_module_shims.js"),
17
- rails_ujs: GoodJob::Engine.root.join("app", "frontend", "good_job", "vendor", "rails_ujs.js"),
18
+ bootstrap: asset_path("vendor", "bootstrap", "bootstrap.bundle.min.js"),
19
+ chartjs: asset_path("vendor", "chartjs", "chart.min.js"),
20
+ es_module_shims: asset_path("vendor", "es_module_shims.js"),
21
+ turbo: asset_path("vendor", "turbo.js"),
18
22
  },
19
23
  svg: {
20
- icons: GoodJob::Engine.root.join("app", "frontend", "good_job", "icons.svg"),
24
+ icons: asset_path("icons.svg"),
21
25
  },
22
26
  }.freeze
23
27
 
24
28
  MODULE_OVERRIDES = {
25
- application: GoodJob::Engine.root.join("app", "frontend", "good_job", "application.js"),
26
- stimulus: GoodJob::Engine.root.join("app", "frontend", "good_job", "vendor", "stimulus.js"),
29
+ application: asset_path("application.js"),
30
+ stimulus: asset_path("vendor", "stimulus.js"),
31
+ turbo: asset_path("vendor", "turbo.js"),
27
32
  }.freeze
28
33
 
29
34
  def self.js_modules
30
- @_js_modules ||= GoodJob::Engine.root.join("app", "frontend", "good_job", "modules").children.select(&:file?).each_with_object({}) do |file, modules|
35
+ @_js_modules ||= asset_path("modules").children.select(&:file?).each_with_object({}) do |file, modules|
31
36
  key = File.basename(file.basename.to_s, ".js").to_sym
32
37
  modules[key] = file
33
38
  end.merge(MODULE_OVERRIDES)
@@ -57,7 +57,7 @@ module GoodJob
57
57
  "No jobs were #{ACTIONS[mass_action]}"
58
58
  end
59
59
 
60
- redirect_back(fallback_location: jobs_path, notice: notice)
60
+ redirect_back(fallback_location: jobs_path, notice: notice, status: :see_other)
61
61
  end
62
62
 
63
63
  def show
@@ -67,31 +67,31 @@ module GoodJob
67
67
  def discard
68
68
  @job = Job.find(params[:id])
69
69
  @job.discard_job(DISCARD_MESSAGE)
70
- redirect_back(fallback_location: jobs_path, notice: t(".notice"))
70
+ redirect_back(fallback_location: jobs_path, notice: t(".notice"), status: :see_other)
71
71
  end
72
72
 
73
73
  def force_discard
74
74
  @job = Job.find(params[:id])
75
75
  @job.force_discard_job(FORCE_DISCARD_MESSAGE)
76
- redirect_back(fallback_location: jobs_path, notice: t(".notice"))
76
+ redirect_back(fallback_location: jobs_path, notice: t(".notice"), status: :see_other)
77
77
  end
78
78
 
79
79
  def reschedule
80
80
  @job = Job.find(params[:id])
81
81
  @job.reschedule_job
82
- redirect_back(fallback_location: jobs_path, notice: t(".notice"))
82
+ redirect_back(fallback_location: jobs_path, notice: t(".notice"), status: :see_other)
83
83
  end
84
84
 
85
85
  def retry
86
86
  @job = Job.find(params[:id])
87
87
  use_original_locale { @job.retry_job }
88
- redirect_back(fallback_location: jobs_path, notice: t(".notice"))
88
+ redirect_back(fallback_location: jobs_path, notice: t(".notice"), status: :see_other)
89
89
  end
90
90
 
91
91
  def destroy
92
92
  @job = Job.find(params[:id])
93
93
  @job.destroy_job
94
- redirect_to jobs_path, notice: t(".notice")
94
+ redirect_to jobs_path, notice: t(".notice"), status: :see_other
95
95
  end
96
96
 
97
97
  def redirect_to_index
@@ -115,7 +115,7 @@ module GoodJob
115
115
  else
116
116
  exception.to_s
117
117
  end
118
- redirect_back(fallback_location: jobs_path, alert: alert)
118
+ redirect_back(fallback_location: jobs_path, alert: alert, status: :see_other)
119
119
  end
120
120
  end
121
121
  end
@@ -12,7 +12,7 @@ module GoodJob
12
12
  pause_value = params[:value].to_s
13
13
 
14
14
  GoodJob::Setting.pause(pause_type => pause_value)
15
- redirect_to({ action: :index }, notice: "Successfully paused #{params[:type]} '#{params[:value]}'")
15
+ redirect_to({ action: :index }, notice: "Successfully paused #{params[:type]} '#{params[:value]}'", status: :see_other)
16
16
  end
17
17
 
18
18
  def destroy
@@ -20,7 +20,7 @@ module GoodJob
20
20
  pause_value = params[:value].to_s
21
21
 
22
22
  GoodJob::Setting.unpause(pause_type => pause_value)
23
- redirect_to({ action: :index }, notice: "Successfully unpaused #{params[:type]} '#{params[:value]}'")
23
+ redirect_to({ action: :index }, notice: "Successfully unpaused #{params[:type]} '#{params[:value]}'", status: :see_other)
24
24
  end
25
25
 
26
26
  private
@@ -1,20 +1,23 @@
1
1
  /*jshint esversion: 6, strict: false */
2
2
 
3
+ import "turbo";
4
+ import { Application } from "stimulus";
5
+ window.Stimulus = Application.start();
6
+
7
+ import FormController from "form_controller";
8
+ Stimulus.register("form", FormController);
9
+ import ThemeController from "theme_controller";
10
+ Stimulus.register("theme", ThemeController);
11
+ import AsyncValuesController from "async_values_controller";
12
+ Stimulus.register("async-values", AsyncValuesController);
13
+
3
14
  import renderCharts from "charts";
4
15
  import checkboxToggle from "checkbox_toggle";
5
- import documentReady from "document_ready";
6
16
  import showToasts from "toasts";
7
17
  import setupPopovers from "popovers";
8
18
  import LivePoll from "live_poll";
9
19
 
10
- import { Application } from "stimulus";
11
- import ThemeController from "theme_controller";
12
- import AsyncValuesController from "async_values_controller";
13
- window.Stimulus = Application.start();
14
- Stimulus.register("theme", ThemeController)
15
- Stimulus.register("async-values", AsyncValuesController)
16
-
17
- documentReady(function() {
20
+ window.document.addEventListener("turbo:load", function() {
18
21
  renderCharts();
19
22
  showToasts();
20
23
  setupPopovers();
@@ -24,3 +27,14 @@ documentReady(function() {
24
27
  livePoll.start();
25
28
  });
26
29
 
30
+ document.addEventListener("turbo:load", function() {
31
+ document.documentElement.removeAttribute("data-turbo-unloaded")
32
+ })
33
+
34
+ document.addEventListener("turbo:submit-start", function() {
35
+ document.documentElement.setAttribute("data-turbo-loading", "1")
36
+ })
37
+ document.addEventListener("turbo:submit-end", function() {
38
+ document.documentElement.removeAttribute("data-turbo-loading")
39
+ })
40
+
@@ -0,0 +1,11 @@
1
+ import {Controller} from "stimulus"
2
+
3
+ export default class extends Controller {
4
+ submit() {
5
+ this.element.requestSubmit();
6
+ }
7
+
8
+ reset() {
9
+ this.element.reset();
10
+ }
11
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Minified by jsDelivr using Terser v5.39.0.
3
+ * Original file: /npm/@hotwired/turbo-rails@8.0.20/app/assets/javascripts/turbo.js
4
+ *
5
+ * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6
+ */
7
+ /*!
8
+ Turbo 8.0.19
9
+ Copyright © 2025 37signals LLC
10
+ */
11
+ !function(e){function t(e,t,s){throw new e("Failed to execute 'requestSubmit' on 'HTMLFormElement': "+t+".",s)}"function"!=typeof e.requestSubmit&&(e.requestSubmit=function(e){e?(!function(e,s){e instanceof HTMLElement||t(TypeError,"parameter 1 is not of type 'HTMLElement'"),"submit"==e.type||t(TypeError,"The specified element is not a submit button"),e.form==s||t(DOMException,"The specified element is not owned by this form element","NotFoundError")}(e,this),e.click()):((e=document.createElement("input")).type="submit",e.hidden=!0,this.appendChild(e),e.click(),this.removeChild(e))})}(HTMLFormElement.prototype);const submittersByForm=new WeakMap;function findSubmitterFromClickTarget(e){const t=e instanceof Element?e:e instanceof Node?e.parentElement:null,s=t?t.closest("input, button"):null;return"submit"==s?.type?s:null}function clickCaptured(e){const t=findSubmitterFromClickTarget(e.target);t&&t.form&&submittersByForm.set(t.form,t)}!function(){if("submitter"in Event.prototype)return;let e=window.Event.prototype;if("SubmitEvent"in window){const t=window.SubmitEvent.prototype;if(!/Apple Computer/.test(navigator.vendor)||"submitter"in t)return;e=t}addEventListener("click",clickCaptured,!0),Object.defineProperty(e,"submitter",{get(){if("submit"==this.type&&this.target instanceof HTMLFormElement)return submittersByForm.get(this.target)}})}();const FrameLoadingStyle={eager:"eager",lazy:"lazy"};class FrameElement extends HTMLElement{static delegateConstructor=void 0;loaded=Promise.resolve();static get observedAttributes(){return["disabled","loading","src"]}constructor(){super(),this.delegate=new FrameElement.delegateConstructor(this)}connectedCallback(){this.delegate.connect()}disconnectedCallback(){this.delegate.disconnect()}reload(){return this.delegate.sourceURLReloaded()}attributeChangedCallback(e){"loading"==e?this.delegate.loadingStyleChanged():"src"==e?this.delegate.sourceURLChanged():"disabled"==e&&this.delegate.disabledChanged()}get src(){return this.getAttribute("src")}set src(e){e?this.setAttribute("src",e):this.removeAttribute("src")}get refresh(){return this.getAttribute("refresh")}set refresh(e){e?this.setAttribute("refresh",e):this.removeAttribute("refresh")}get shouldReloadWithMorph(){return this.src&&"morph"===this.refresh}get loading(){return frameLoadingStyleFromString(this.getAttribute("loading")||"")}set loading(e){e?this.setAttribute("loading",e):this.removeAttribute("loading")}get disabled(){return this.hasAttribute("disabled")}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}get autoscroll(){return this.hasAttribute("autoscroll")}set autoscroll(e){e?this.setAttribute("autoscroll",""):this.removeAttribute("autoscroll")}get complete(){return!this.delegate.isLoading}get isActive(){return this.ownerDocument===document&&!this.isPreview}get isPreview(){return this.ownerDocument?.documentElement?.hasAttribute("data-turbo-preview")}}function frameLoadingStyleFromString(e){return"lazy"===e.toLowerCase()?FrameLoadingStyle.lazy:FrameLoadingStyle.eager}const drive={enabled:!0,progressBarDelay:500,unvisitableExtensions:new Set([".7z",".aac",".apk",".avi",".bmp",".bz2",".css",".csv",".deb",".dmg",".doc",".docx",".exe",".gif",".gz",".heic",".heif",".ico",".iso",".jpeg",".jpg",".js",".json",".m4a",".mkv",".mov",".mp3",".mp4",".mpeg",".mpg",".msi",".ogg",".ogv",".pdf",".pkg",".png",".ppt",".pptx",".rar",".rtf",".svg",".tar",".tif",".tiff",".txt",".wav",".webm",".webp",".wma",".wmv",".xls",".xlsx",".xml",".zip"])};function activateScriptElement(e){if("false"==e.getAttribute("data-turbo-eval"))return e;{const t=document.createElement("script"),s=getCspNonce();return s&&(t.nonce=s),t.textContent=e.textContent,t.async=!1,copyElementAttributes(t,e),t}}function copyElementAttributes(e,t){for(const{name:s,value:r}of t.attributes)e.setAttribute(s,r)}function createDocumentFragment(e){const t=document.createElement("template");return t.innerHTML=e,t.content}function dispatch(e,{target:t,cancelable:s,detail:r}={}){const i=new CustomEvent(e,{cancelable:s,bubbles:!0,composed:!0,detail:r});return t&&t.isConnected?t.dispatchEvent(i):document.documentElement.dispatchEvent(i),i}function cancelEvent(e){e.preventDefault(),e.stopImmediatePropagation()}function nextRepaint(){return"hidden"===document.visibilityState?nextEventLoopTick():nextAnimationFrame()}function nextAnimationFrame(){return new Promise((e=>requestAnimationFrame((()=>e()))))}function nextEventLoopTick(){return new Promise((e=>setTimeout((()=>e()),0)))}function nextMicrotask(){return Promise.resolve()}function parseHTMLDocument(e=""){return(new DOMParser).parseFromString(e,"text/html")}function unindent(e,...t){const s=interpolate(e,t).replace(/^\n/,"").split("\n"),r=s[0].match(/^\s+/),i=r?r[0].length:0;return s.map((e=>e.slice(i))).join("\n")}function interpolate(e,t){return e.reduce(((e,s,r)=>e+s+(null==t[r]?"":t[r])),"")}function uuid(){return Array.from({length:36}).map(((e,t)=>8==t||13==t||18==t||23==t?"-":14==t?"4":19==t?(Math.floor(4*Math.random())+8).toString(16):Math.floor(15*Math.random()).toString(16))).join("")}function getAttribute(e,...t){for(const s of t.map((t=>t?.getAttribute(e))))if("string"==typeof s)return s;return null}function hasAttribute(e,...t){return t.some((t=>t&&t.hasAttribute(e)))}function markAsBusy(...e){for(const t of e)"turbo-frame"==t.localName&&t.setAttribute("busy",""),t.setAttribute("aria-busy","true")}function clearBusyState(...e){for(const t of e)"turbo-frame"==t.localName&&t.removeAttribute("busy"),t.removeAttribute("aria-busy")}function waitForLoad(e,t=2e3){return new Promise((s=>{const r=()=>{e.removeEventListener("error",r),e.removeEventListener("load",r),s()};e.addEventListener("load",r,{once:!0}),e.addEventListener("error",r,{once:!0}),setTimeout(s,t)}))}function getHistoryMethodForAction(e){switch(e){case"replace":return history.replaceState;case"advance":case"restore":return history.pushState}}function isAction(e){return"advance"==e||"replace"==e||"restore"==e}function getVisitAction(...e){const t=getAttribute("data-turbo-action",...e);return isAction(t)?t:null}function getMetaElement(e){return document.querySelector(`meta[name="${e}"]`)}function getMetaContent(e){const t=getMetaElement(e);return t&&t.content}function getCspNonce(){const e=getMetaElement("csp-nonce");if(e){const{nonce:t,content:s}=e;return""==t?s:t}}function setMetaContent(e,t){let s=getMetaElement(e);return s||(s=document.createElement("meta"),s.setAttribute("name",e),document.head.appendChild(s)),s.setAttribute("content",t),s}function findClosestRecursively(e,t){if(e instanceof Element)return e.closest(t)||findClosestRecursively(e.assignedSlot||e.getRootNode()?.host,t)}function elementIsFocusable(e){return!!e&&null==e.closest("[inert], :disabled, [hidden], details:not([open]), dialog:not([open])")&&"function"==typeof e.focus}function queryAutofocusableElement(e){return Array.from(e.querySelectorAll("[autofocus]")).find(elementIsFocusable)}async function around(e,t){const s=t();e(),await nextAnimationFrame();return[s,t()]}function doesNotTargetIFrame(e){if("_blank"===e)return!1;if(e){for(const t of document.getElementsByName(e))if(t instanceof HTMLIFrameElement)return!1;return!0}return!0}function findLinkFromClickTarget(e){const t=findClosestRecursively(e,"a[href], a[xlink\\:href]");return t?t.hasAttribute("download")||t.hasAttribute("target")&&"_self"!==t.target?null:t:null}function getLocationForLink(e){return expandURL(e.getAttribute("href")||"")}function debounce(e,t){let s=null;return(...r)=>{clearTimeout(s),s=setTimeout((()=>e.apply(this,r)),t)}}const submitter={"aria-disabled":{beforeSubmit:e=>{e.setAttribute("aria-disabled","true"),e.addEventListener("click",cancelEvent)},afterSubmit:e=>{e.removeAttribute("aria-disabled"),e.removeEventListener("click",cancelEvent)}},disabled:{beforeSubmit:e=>e.disabled=!0,afterSubmit:e=>e.disabled=!1}};class Config{#e=null;constructor(e){Object.assign(this,e)}get submitter(){return this.#e}set submitter(e){this.#e=submitter[e]||e}}const forms=new Config({mode:"on",submitter:"disabled"}),config={drive:drive,forms:forms};function expandURL(e){return new URL(e.toString(),document.baseURI)}function getAnchor(e){let t;return e.hash?e.hash.slice(1):(t=e.href.match(/#(.*)$/))?t[1]:void 0}function getAction$1(e,t){return expandURL(t?.getAttribute("formaction")||e.getAttribute("action")||e.action)}function getExtension(e){return(getLastPathComponent(e).match(/\.[^.]*$/)||[])[0]||""}function isPrefixedBy(e,t){const s=addTrailingSlash(t.origin+t.pathname);return addTrailingSlash(e.href)===s||e.href.startsWith(s)}function locationIsVisitable(e,t){return isPrefixedBy(e,t)&&!config.drive.unvisitableExtensions.has(getExtension(e))}function getRequestURL(e){const t=getAnchor(e);return null!=t?e.href.slice(0,-(t.length+1)):e.href}function toCacheKey(e){return getRequestURL(e)}function urlsAreEqual(e,t){return expandURL(e).href==expandURL(t).href}function getPathComponents(e){return e.pathname.split("/").slice(1)}function getLastPathComponent(e){return getPathComponents(e).slice(-1)[0]}function addTrailingSlash(e){return e.endsWith("/")?e:e+"/"}class FetchResponse{constructor(e){this.response=e}get succeeded(){return this.response.ok}get failed(){return!this.succeeded}get clientError(){return this.statusCode>=400&&this.statusCode<=499}get serverError(){return this.statusCode>=500&&this.statusCode<=599}get redirected(){return this.response.redirected}get location(){return expandURL(this.response.url)}get isHTML(){return this.contentType&&this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/)}get statusCode(){return this.response.status}get contentType(){return this.header("Content-Type")}get responseText(){return this.response.clone().text()}get responseHTML(){return this.isHTML?this.response.clone().text():Promise.resolve(void 0)}header(e){return this.response.headers.get(e)}}class LimitedSet extends Set{constructor(e){super(),this.maxSize=e}add(e){if(this.size>=this.maxSize){const e=this.values().next().value;this.delete(e)}super.add(e)}}const recentRequests=new LimitedSet(20);function fetchWithTurboHeaders(e,t={}){const s=new Headers(t.headers||{}),r=uuid();return recentRequests.add(r),s.append("X-Turbo-Request-Id",r),window.fetch(e,{...t,headers:s})}function fetchMethodFromString(e){switch(e.toLowerCase()){case"get":return FetchMethod.get;case"post":return FetchMethod.post;case"put":return FetchMethod.put;case"patch":return FetchMethod.patch;case"delete":return FetchMethod.delete}}const FetchMethod={get:"get",post:"post",put:"put",patch:"patch",delete:"delete"};function fetchEnctypeFromString(e){switch(e.toLowerCase()){case FetchEnctype.multipart:return FetchEnctype.multipart;case FetchEnctype.plain:return FetchEnctype.plain;default:return FetchEnctype.urlEncoded}}const FetchEnctype={urlEncoded:"application/x-www-form-urlencoded",multipart:"multipart/form-data",plain:"text/plain"};class FetchRequest{abortController=new AbortController;#t=e=>{};constructor(e,t,s,r=new URLSearchParams,i=null,n=FetchEnctype.urlEncoded){const[o,a]=buildResourceAndBody(expandURL(s),t,r,n);this.delegate=e,this.url=o,this.target=i,this.fetchOptions={credentials:"same-origin",redirect:"follow",method:t.toUpperCase(),headers:{...this.defaultHeaders},body:a,signal:this.abortSignal,referrer:this.delegate.referrer?.href},this.enctype=n}get method(){return this.fetchOptions.method}set method(e){const t=this.isSafe?this.url.searchParams:this.fetchOptions.body||new FormData,s=fetchMethodFromString(e)||FetchMethod.get;this.url.search="";const[r,i]=buildResourceAndBody(this.url,s,t,this.enctype);this.url=r,this.fetchOptions.body=i,this.fetchOptions.method=s.toUpperCase()}get headers(){return this.fetchOptions.headers}set headers(e){this.fetchOptions.headers=e}get body(){return this.isSafe?this.url.searchParams:this.fetchOptions.body}set body(e){this.fetchOptions.body=e}get location(){return this.url}get params(){return this.url.searchParams}get entries(){return this.body?Array.from(this.body.entries()):[]}cancel(){this.abortController.abort()}async perform(){const{fetchOptions:e}=this;this.delegate.prepareRequest(this);const t=await this.#s(e);try{this.delegate.requestStarted(this),t.detail.fetchRequest?this.response=t.detail.fetchRequest.response:this.response=fetchWithTurboHeaders(this.url.href,e);const s=await this.response;return await this.receive(s)}catch(e){if("AbortError"!==e.name)throw this.#r(e)&&this.delegate.requestErrored(this,e),e}finally{this.delegate.requestFinished(this)}}async receive(e){const t=new FetchResponse(e);return dispatch("turbo:before-fetch-response",{cancelable:!0,detail:{fetchResponse:t},target:this.target}).defaultPrevented?this.delegate.requestPreventedHandlingResponse(this,t):t.succeeded?this.delegate.requestSucceededWithResponse(this,t):this.delegate.requestFailedWithResponse(this,t),t}get defaultHeaders(){return{Accept:"text/html, application/xhtml+xml"}}get isSafe(){return isSafe(this.method)}get abortSignal(){return this.abortController.signal}acceptResponseType(e){this.headers.Accept=[e,this.headers.Accept].join(", ")}async#s(e){const t=new Promise((e=>this.#t=e)),s=dispatch("turbo:before-fetch-request",{cancelable:!0,detail:{fetchOptions:e,url:this.url,resume:this.#t},target:this.target});return this.url=s.detail.url,s.defaultPrevented&&await t,s}#r(e){return!dispatch("turbo:fetch-request-error",{target:this.target,cancelable:!0,detail:{request:this,error:e}}).defaultPrevented}}function isSafe(e){return fetchMethodFromString(e)==FetchMethod.get}function buildResourceAndBody(e,t,s,r){const i=Array.from(s).length>0?new URLSearchParams(entriesExcludingFiles(s)):e.searchParams;return isSafe(t)?[mergeIntoURLSearchParams(e,i),null]:r==FetchEnctype.urlEncoded?[e,i]:[e,s]}function entriesExcludingFiles(e){const t=[];for(const[s,r]of e)r instanceof File||t.push([s,r]);return t}function mergeIntoURLSearchParams(e,t){const s=new URLSearchParams(entriesExcludingFiles(t));return e.search=s.toString(),e}class AppearanceObserver{started=!1;constructor(e,t){this.delegate=e,this.element=t,this.intersectionObserver=new IntersectionObserver(this.intersect)}start(){this.started||(this.started=!0,this.intersectionObserver.observe(this.element))}stop(){this.started&&(this.started=!1,this.intersectionObserver.unobserve(this.element))}intersect=e=>{const t=e.slice(-1)[0];t?.isIntersecting&&this.delegate.elementAppearedInViewport(this.element)}}class StreamMessage{static contentType="text/vnd.turbo-stream.html";static wrap(e){return"string"==typeof e?new this(createDocumentFragment(e)):e}constructor(e){this.fragment=importStreamElements(e)}}function importStreamElements(e){for(const t of e.querySelectorAll("turbo-stream")){const e=document.importNode(t,!0);for(const t of e.templateElement.content.querySelectorAll("script"))t.replaceWith(activateScriptElement(t));t.replaceWith(e)}return e}const PREFETCH_DELAY=100;class PrefetchCache{#i=null;#n=null;get(e){if(this.#n&&this.#n.url===e&&this.#n.expire>Date.now())return this.#n.request}setLater(e,t,s){this.clear(),this.#i=setTimeout((()=>{t.perform(),this.set(e,t,s),this.#i=null}),100)}set(e,t,s){this.#n={url:e,request:t,expire:new Date((new Date).getTime()+s)}}clear(){this.#i&&clearTimeout(this.#i),this.#n=null}}const cacheTtl=1e4,prefetchCache=new PrefetchCache,FormSubmissionState={initialized:"initialized",requesting:"requesting",waiting:"waiting",receiving:"receiving",stopping:"stopping",stopped:"stopped"};class FormSubmission{state=FormSubmissionState.initialized;static confirmMethod(e){return Promise.resolve(confirm(e))}constructor(e,t,s,r=!1){const i=getMethod(t,s),n=getAction(getFormAction(t,s),i),o=buildFormData(t,s),a=getEnctype(t,s);this.delegate=e,this.formElement=t,this.submitter=s,this.fetchRequest=new FetchRequest(this,i,n,o,t,a),this.mustRedirect=r}get method(){return this.fetchRequest.method}set method(e){this.fetchRequest.method=e}get action(){return this.fetchRequest.url.toString()}set action(e){this.fetchRequest.url=expandURL(e)}get body(){return this.fetchRequest.body}get enctype(){return this.fetchRequest.enctype}get isSafe(){return this.fetchRequest.isSafe}get location(){return this.fetchRequest.url}async start(){const{initialized:e,requesting:t}=FormSubmissionState,s=getAttribute("data-turbo-confirm",this.submitter,this.formElement);if("string"==typeof s){const e="function"==typeof config.forms.confirm?config.forms.confirm:FormSubmission.confirmMethod;if(!await e(s,this.formElement,this.submitter))return}if(this.state==e)return this.state=t,this.fetchRequest.perform()}stop(){const{stopping:e,stopped:t}=FormSubmissionState;if(this.state!=e&&this.state!=t)return this.state=e,this.fetchRequest.cancel(),!0}prepareRequest(e){if(!e.isSafe){const t=getCookieValue(getMetaContent("csrf-param"))||getMetaContent("csrf-token");t&&(e.headers["X-CSRF-Token"]=t)}this.requestAcceptsTurboStreamResponse(e)&&e.acceptResponseType(StreamMessage.contentType)}requestStarted(e){this.state=FormSubmissionState.waiting,this.submitter&&config.forms.submitter.beforeSubmit(this.submitter),this.setSubmitsWith(),markAsBusy(this.formElement),dispatch("turbo:submit-start",{target:this.formElement,detail:{formSubmission:this}}),this.delegate.formSubmissionStarted(this)}requestPreventedHandlingResponse(e,t){prefetchCache.clear(),this.result={success:t.succeeded,fetchResponse:t}}requestSucceededWithResponse(e,t){if(t.clientError||t.serverError)this.delegate.formSubmissionFailedWithResponse(this,t);else if(prefetchCache.clear(),this.requestMustRedirect(e)&&responseSucceededWithoutRedirect(t)){const e=new Error("Form responses must redirect to another location");this.delegate.formSubmissionErrored(this,e)}else this.state=FormSubmissionState.receiving,this.result={success:!0,fetchResponse:t},this.delegate.formSubmissionSucceededWithResponse(this,t)}requestFailedWithResponse(e,t){this.result={success:!1,fetchResponse:t},this.delegate.formSubmissionFailedWithResponse(this,t)}requestErrored(e,t){this.result={success:!1,error:t},this.delegate.formSubmissionErrored(this,t)}requestFinished(e){this.state=FormSubmissionState.stopped,this.submitter&&config.forms.submitter.afterSubmit(this.submitter),this.resetSubmitterText(),clearBusyState(this.formElement),dispatch("turbo:submit-end",{target:this.formElement,detail:{formSubmission:this,...this.result}}),this.delegate.formSubmissionFinished(this)}setSubmitsWith(){if(this.submitter&&this.submitsWith)if(this.submitter.matches("button"))this.originalSubmitText=this.submitter.innerHTML,this.submitter.innerHTML=this.submitsWith;else if(this.submitter.matches("input")){const e=this.submitter;this.originalSubmitText=e.value,e.value=this.submitsWith}}resetSubmitterText(){if(this.submitter&&this.originalSubmitText)if(this.submitter.matches("button"))this.submitter.innerHTML=this.originalSubmitText;else if(this.submitter.matches("input")){this.submitter.value=this.originalSubmitText}}requestMustRedirect(e){return!e.isSafe&&this.mustRedirect}requestAcceptsTurboStreamResponse(e){return!e.isSafe||hasAttribute("data-turbo-stream",this.submitter,this.formElement)}get submitsWith(){return this.submitter?.getAttribute("data-turbo-submits-with")}}function buildFormData(e,t){const s=new FormData(e),r=t?.getAttribute("name"),i=t?.getAttribute("value");return r&&s.append(r,i||""),s}function getCookieValue(e){if(null!=e){const t=(document.cookie?document.cookie.split("; "):[]).find((t=>t.startsWith(e)));if(t){const e=t.split("=").slice(1).join("=");return e?decodeURIComponent(e):void 0}}}function responseSucceededWithoutRedirect(e){return 200==e.statusCode&&!e.redirected}function getFormAction(e,t){const s="string"==typeof e.action?e.action:null;return t?.hasAttribute("formaction")?t.getAttribute("formaction")||"":e.getAttribute("action")||s||""}function getAction(e,t){const s=expandURL(e);return isSafe(t)&&(s.search=""),s}function getMethod(e,t){return fetchMethodFromString((t?.getAttribute("formmethod")||e.getAttribute("method")||"").toLowerCase())||FetchMethod.get}function getEnctype(e,t){return fetchEnctypeFromString(t?.getAttribute("formenctype")||e.enctype)}class Snapshot{constructor(e){this.element=e}get activeElement(){return this.element.ownerDocument.activeElement}get children(){return[...this.element.children]}hasAnchor(e){return null!=this.getElementForAnchor(e)}getElementForAnchor(e){return e?this.element.querySelector(`[id='${e}'], a[name='${e}']`):null}get isConnected(){return this.element.isConnected}get firstAutofocusableElement(){return queryAutofocusableElement(this.element)}get permanentElements(){return queryPermanentElementsAll(this.element)}getPermanentElementById(e){return getPermanentElementById(this.element,e)}getPermanentElementMapForSnapshot(e){const t={};for(const s of this.permanentElements){const{id:r}=s,i=e.getPermanentElementById(r);i&&(t[r]=[s,i])}return t}}function getPermanentElementById(e,t){return e.querySelector(`#${t}[data-turbo-permanent]`)}function queryPermanentElementsAll(e){return e.querySelectorAll("[id][data-turbo-permanent]")}class FormSubmitObserver{started=!1;constructor(e,t){this.delegate=e,this.eventTarget=t}start(){this.started||(this.eventTarget.addEventListener("submit",this.submitCaptured,!0),this.started=!0)}stop(){this.started&&(this.eventTarget.removeEventListener("submit",this.submitCaptured,!0),this.started=!1)}submitCaptured=()=>{this.eventTarget.removeEventListener("submit",this.submitBubbled,!1),this.eventTarget.addEventListener("submit",this.submitBubbled,!1)};submitBubbled=e=>{if(!e.defaultPrevented){const t=e.target instanceof HTMLFormElement?e.target:void 0,s=e.submitter||void 0;t&&submissionDoesNotDismissDialog(t,s)&&submissionDoesNotTargetIFrame(t,s)&&this.delegate.willSubmitForm(t,s)&&(e.preventDefault(),e.stopImmediatePropagation(),this.delegate.formSubmitted(t,s))}}}function submissionDoesNotDismissDialog(e,t){return"dialog"!=(t?.getAttribute("formmethod")||e.getAttribute("method"))}function submissionDoesNotTargetIFrame(e,t){return doesNotTargetIFrame(t?.getAttribute("formtarget")||e.getAttribute("target"))}class View{#o=e=>{};#a=e=>{};constructor(e,t){this.delegate=e,this.element=t}scrollToAnchor(e){const t=this.snapshot.getElementForAnchor(e);t?(this.focusElement(t),this.scrollToElement(t)):this.scrollToPosition({x:0,y:0})}scrollToAnchorFromLocation(e){this.scrollToAnchor(getAnchor(e))}scrollToElement(e){e.scrollIntoView()}focusElement(e){e instanceof HTMLElement&&(e.hasAttribute("tabindex")?e.focus():(e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")))}scrollToPosition({x:e,y:t}){this.scrollRoot.scrollTo(e,t)}scrollToTop(){this.scrollToPosition({x:0,y:0})}get scrollRoot(){return window}async render(e){const{isPreview:t,shouldRender:s,willRender:r,newSnapshot:i}=e,n=r;if(s)try{this.renderPromise=new Promise((e=>this.#o=e)),this.renderer=e,await this.prepareToRenderSnapshot(e);const s=new Promise((e=>this.#a=e)),r={resume:this.#a,render:this.renderer.renderElement,renderMethod:this.renderer.renderMethod};this.delegate.allowsImmediateRender(i,r)||await s,await this.renderSnapshot(e),this.delegate.viewRenderedSnapshot(i,t,this.renderer.renderMethod),this.delegate.preloadOnLoadLinksForView(this.element),this.finishRenderingSnapshot(e)}finally{delete this.renderer,this.#o(void 0),delete this.renderPromise}else n&&this.invalidate(e.reloadReason)}invalidate(e){this.delegate.viewInvalidated(e)}async prepareToRenderSnapshot(e){this.markAsPreview(e.isPreview),await e.prepareToRender()}markAsPreview(e){e?this.element.setAttribute("data-turbo-preview",""):this.element.removeAttribute("data-turbo-preview")}markVisitDirection(e){this.element.setAttribute("data-turbo-visit-direction",e)}unmarkVisitDirection(){this.element.removeAttribute("data-turbo-visit-direction")}async renderSnapshot(e){await e.render()}finishRenderingSnapshot(e){e.finishRendering()}}class FrameView extends View{missing(){this.element.innerHTML='<strong class="turbo-frame-error">Content missing</strong>'}get snapshot(){return new Snapshot(this.element)}}class LinkInterceptor{constructor(e,t){this.delegate=e,this.element=t}start(){this.element.addEventListener("click",this.clickBubbled),document.addEventListener("turbo:click",this.linkClicked),document.addEventListener("turbo:before-visit",this.willVisit)}stop(){this.element.removeEventListener("click",this.clickBubbled),document.removeEventListener("turbo:click",this.linkClicked),document.removeEventListener("turbo:before-visit",this.willVisit)}clickBubbled=e=>{this.clickEventIsSignificant(e)?this.clickEvent=e:delete this.clickEvent};linkClicked=e=>{this.clickEvent&&this.clickEventIsSignificant(e)&&this.delegate.shouldInterceptLinkClick(e.target,e.detail.url,e.detail.originalEvent)&&(this.clickEvent.preventDefault(),e.preventDefault(),this.delegate.linkClickIntercepted(e.target,e.detail.url,e.detail.originalEvent)),delete this.clickEvent};willVisit=e=>{delete this.clickEvent};clickEventIsSignificant(e){const t=e.composed?e.target?.parentElement:e.target,s=findLinkFromClickTarget(t)||t;return s instanceof Element&&s.closest("turbo-frame, html")==this.element}}class LinkClickObserver{started=!1;constructor(e,t){this.delegate=e,this.eventTarget=t}start(){this.started||(this.eventTarget.addEventListener("click",this.clickCaptured,!0),this.started=!0)}stop(){this.started&&(this.eventTarget.removeEventListener("click",this.clickCaptured,!0),this.started=!1)}clickCaptured=()=>{this.eventTarget.removeEventListener("click",this.clickBubbled,!1),this.eventTarget.addEventListener("click",this.clickBubbled,!1)};clickBubbled=e=>{if(e instanceof MouseEvent&&this.clickEventIsSignificant(e)){const t=findLinkFromClickTarget(e.composedPath&&e.composedPath()[0]||e.target);if(t&&doesNotTargetIFrame(t.target)){const s=getLocationForLink(t);this.delegate.willFollowLinkToLocation(t,s,e)&&(e.preventDefault(),this.delegate.followedLinkToLocation(t,s))}}};clickEventIsSignificant(e){return!(e.target&&e.target.isContentEditable||e.defaultPrevented||e.which>1||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)}}class FormLinkClickObserver{constructor(e,t){this.delegate=e,this.linkInterceptor=new LinkClickObserver(this,t)}start(){this.linkInterceptor.start()}stop(){this.linkInterceptor.stop()}canPrefetchRequestToLocation(e,t){return!1}prefetchAndCacheRequestToLocation(e,t){}willFollowLinkToLocation(e,t,s){return this.delegate.willSubmitFormLinkToLocation(e,t,s)&&(e.hasAttribute("data-turbo-method")||e.hasAttribute("data-turbo-stream"))}followedLinkToLocation(e,t){const s=document.createElement("form");for(const[e,r]of t.searchParams)s.append(Object.assign(document.createElement("input"),{type:"hidden",name:e,value:r}));const r=Object.assign(t,{search:""});s.setAttribute("data-turbo","true"),s.setAttribute("action",r.href),s.setAttribute("hidden","");const i=e.getAttribute("data-turbo-method");i&&s.setAttribute("method",i);const n=e.getAttribute("data-turbo-frame");n&&s.setAttribute("data-turbo-frame",n);const o=getVisitAction(e);o&&s.setAttribute("data-turbo-action",o);const a=e.getAttribute("data-turbo-confirm");a&&s.setAttribute("data-turbo-confirm",a);e.hasAttribute("data-turbo-stream")&&s.setAttribute("data-turbo-stream",""),this.delegate.submittedFormLinkToLocation(e,t,s),document.body.appendChild(s),s.addEventListener("turbo:submit-end",(()=>s.remove()),{once:!0}),requestAnimationFrame((()=>s.requestSubmit()))}}class Bardo{static async preservingPermanentElements(e,t,s){const r=new this(e,t);r.enter(),await s(),r.leave()}constructor(e,t){this.delegate=e,this.permanentElementMap=t}enter(){for(const e in this.permanentElementMap){const[t,s]=this.permanentElementMap[e];this.delegate.enteringBardo(t,s),this.replaceNewPermanentElementWithPlaceholder(s)}}leave(){for(const e in this.permanentElementMap){const[t]=this.permanentElementMap[e];this.replaceCurrentPermanentElementWithClone(t),this.replacePlaceholderWithPermanentElement(t),this.delegate.leavingBardo(t)}}replaceNewPermanentElementWithPlaceholder(e){const t=createPlaceholderForPermanentElement(e);e.replaceWith(t)}replaceCurrentPermanentElementWithClone(e){const t=e.cloneNode(!0);e.replaceWith(t)}replacePlaceholderWithPermanentElement(e){const t=this.getPlaceholderById(e.id);t?.replaceWith(e)}getPlaceholderById(e){return this.placeholders.find((t=>t.content==e))}get placeholders(){return[...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")]}}function createPlaceholderForPermanentElement(e){const t=document.createElement("meta");return t.setAttribute("name","turbo-permanent-placeholder"),t.setAttribute("content",e.id),t}class Renderer{#c=null;static renderElement(e,t){}constructor(e,t,s,r=!0){this.currentSnapshot=e,this.newSnapshot=t,this.isPreview=s,this.willRender=r,this.renderElement=this.constructor.renderElement,this.promise=new Promise(((e,t)=>this.resolvingFunctions={resolve:e,reject:t}))}get shouldRender(){return!0}get shouldAutofocus(){return!0}get reloadReason(){}prepareToRender(){}render(){}finishRendering(){this.resolvingFunctions&&(this.resolvingFunctions.resolve(),delete this.resolvingFunctions)}async preservingPermanentElements(e){await Bardo.preservingPermanentElements(this,this.permanentElementMap,e)}focusFirstAutofocusableElement(){if(this.shouldAutofocus){const e=this.connectedSnapshot.firstAutofocusableElement;e&&e.focus()}}enteringBardo(e){this.#c||e.contains(this.currentSnapshot.activeElement)&&(this.#c=this.currentSnapshot.activeElement)}leavingBardo(e){e.contains(this.#c)&&this.#c instanceof HTMLElement&&(this.#c.focus(),this.#c=null)}get connectedSnapshot(){return this.newSnapshot.isConnected?this.newSnapshot:this.currentSnapshot}get currentElement(){return this.currentSnapshot.element}get newElement(){return this.newSnapshot.element}get permanentElementMap(){return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot)}get renderMethod(){return"replace"}}class FrameRenderer extends Renderer{static renderElement(e,t){const s=document.createRange();s.selectNodeContents(e),s.deleteContents();const r=t,i=r.ownerDocument?.createRange();i&&(i.selectNodeContents(r),e.appendChild(i.extractContents()))}constructor(e,t,s,r,i,n=!0){super(t,s,r,i,n),this.delegate=e}get shouldRender(){return!0}async render(){await nextRepaint(),this.preservingPermanentElements((()=>{this.loadFrameElement()})),this.scrollFrameIntoView(),await nextRepaint(),this.focusFirstAutofocusableElement(),await nextRepaint(),this.activateScriptElements()}loadFrameElement(){this.delegate.willRenderFrame(this.currentElement,this.newElement),this.renderElement(this.currentElement,this.newElement)}scrollFrameIntoView(){if(this.currentElement.autoscroll||this.newElement.autoscroll){const e=this.currentElement.firstElementChild,t=readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"),"end"),s=readScrollBehavior(this.currentElement.getAttribute("data-autoscroll-behavior"),"auto");if(e)return e.scrollIntoView({block:t,behavior:s}),!0}return!1}activateScriptElements(){for(const e of this.newScriptElements){const t=activateScriptElement(e);e.replaceWith(t)}}get newScriptElements(){return this.currentElement.querySelectorAll("script")}}function readScrollLogicalPosition(e,t){return"end"==e||"start"==e||"center"==e||"nearest"==e?e:t}function readScrollBehavior(e,t){return"auto"==e||"smooth"==e?e:t}var Idiomorph=function(){const e=()=>{},t={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:e,afterNodeAdded:e,beforeNodeMorphed:e,afterNodeMorphed:e,beforeNodeRemoved:e,afterNodeRemoved:e,beforeAttributeUpdated:e},head:{style:"merge",shouldPreserve:e=>"true"===e.getAttribute("im-preserve"),shouldReAppend:e=>"true"===e.getAttribute("im-re-append"),shouldRemove:e,afterHeadMorphed:e},restoreFocus:!0};const s=function(){function e(e,t,s,i){if(!1===i.callbacks.beforeNodeAdded(t))return null;if(i.idMap.has(t)){const n=document.createElement(t.tagName);return e.insertBefore(n,s),r(n,t,i),i.callbacks.afterNodeAdded(n),n}{const r=document.importNode(t,!0);return e.insertBefore(r,s),i.callbacks.afterNodeAdded(r),r}}const t=function(){function e(e,t,s){let r=e.idMap.get(t),i=e.idMap.get(s);if(!i||!r)return!1;for(const e of r)if(i.has(e))return!0;return!1}function t(e,t){const s=e,r=t;return s.nodeType===r.nodeType&&s.tagName===r.tagName&&(!s.getAttribute?.("id")||s.getAttribute?.("id")===r.getAttribute?.("id"))}return function(s,r,i,n){let o=null,a=r.nextSibling,c=0,l=i;for(;l&&l!=n;){if(t(l,r)){if(e(s,l,r))return l;null===o&&(s.idMap.has(l)||(o=l))}if(null===o&&a&&t(l,a)&&(c++,a=a.nextSibling,c>=2&&(o=void 0)),s.activeElementAndParents.includes(l))break;l=l.nextSibling}return o||null}}();function s(e,t){if(e.idMap.has(t))o(e.pantry,t,null);else{if(!1===e.callbacks.beforeNodeRemoved(t))return;t.parentNode?.removeChild(t),e.callbacks.afterNodeRemoved(t)}}function i(e,t,r){let i=t;for(;i&&i!==r;){let t=i;i=i.nextSibling,s(e,t)}return i}function n(e,t,s,r){const i=r.target.getAttribute?.("id")===t&&r.target||r.target.querySelector(`[id="${t}"]`)||r.pantry.querySelector(`[id="${t}"]`);return function(e,t){const s=e.getAttribute("id");for(;e=e.parentNode;){let r=t.idMap.get(e);r&&(r.delete(s),r.size||t.idMap.delete(e))}}(i,r),o(e,i,s),i}function o(e,t,s){if(e.moveBefore)try{e.moveBefore(t,s)}catch(r){e.insertBefore(t,s)}else e.insertBefore(t,s)}return function(o,a,c,l=null,h=null){a instanceof HTMLTemplateElement&&c instanceof HTMLTemplateElement&&(a=a.content,c=c.content),l||=a.firstChild;for(const s of c.childNodes){if(l&&l!=h){const e=t(o,s,l,h);if(e){e!==l&&i(o,l,e),r(e,s,o),l=e.nextSibling;continue}}if(s instanceof Element){const e=s.getAttribute("id");if(o.persistentIds.has(e)){const t=n(a,e,l,o);r(t,s,o),l=t.nextSibling;continue}}const c=e(a,s,l,o);c&&(l=c.nextSibling)}for(;l&&l!=h;){const e=l;l=l.nextSibling,s(o,e)}}}(),r=function(){function e(e,s,r,i){const n=s[r];if(n!==e[r]){const o=t(r,e,"update",i);o||(e[r]=s[r]),n?o||e.setAttribute(r,""):t(r,e,"remove",i)||e.removeAttribute(r)}}function t(e,t,s,r){return!("value"!==e||!r.ignoreActiveValue||t!==document.activeElement)||!1===r.callbacks.beforeAttributeUpdated(e,t,s)}function r(e,t){return!!t.ignoreActiveValue&&e===document.activeElement&&e!==document.body}return function(n,o,a){return a.ignoreActive&&n===document.activeElement?null:(!1===a.callbacks.beforeNodeMorphed(n,o)||(n instanceof HTMLHeadElement&&a.head.ignore||(n instanceof HTMLHeadElement&&"morph"!==a.head.style?i(n,o,a):(!function(s,i,n){let o=i.nodeType;if(1===o){const o=s,a=i,c=o.attributes,l=a.attributes;for(const e of l)t(e.name,o,"update",n)||o.getAttribute(e.name)!==e.value&&o.setAttribute(e.name,e.value);for(let e=c.length-1;0<=e;e--){const s=c[e];if(s&&!a.hasAttribute(s.name)){if(t(s.name,o,"remove",n))continue;o.removeAttribute(s.name)}}r(o,n)||function(s,r,i){if(s instanceof HTMLInputElement&&r instanceof HTMLInputElement&&"file"!==r.type){let n=r.value,o=s.value;e(s,r,"checked",i),e(s,r,"disabled",i),r.hasAttribute("value")?o!==n&&(t("value",s,"update",i)||(s.setAttribute("value",n),s.value=n)):t("value",s,"remove",i)||(s.value="",s.removeAttribute("value"))}else if(s instanceof HTMLOptionElement&&r instanceof HTMLOptionElement)e(s,r,"selected",i);else if(s instanceof HTMLTextAreaElement&&r instanceof HTMLTextAreaElement){let e=r.value,n=s.value;if(t("value",s,"update",i))return;e!==n&&(s.value=e),s.firstChild&&s.firstChild.nodeValue!==e&&(s.firstChild.nodeValue=e)}}(o,a,n)}8!==o&&3!==o||s.nodeValue!==i.nodeValue&&(s.nodeValue=i.nodeValue)}(n,o,a),r(n,a)||s(a,n,o))),a.callbacks.afterNodeMorphed(n,o)),n)}}();function i(e,t,s){let r=[],i=[],n=[],o=[],a=new Map;for(const e of t.children)a.set(e.outerHTML,e);for(const t of e.children){let e=a.has(t.outerHTML),r=s.head.shouldReAppend(t),c=s.head.shouldPreserve(t);e||c?r?i.push(t):(a.delete(t.outerHTML),n.push(t)):"append"===s.head.style?r&&(i.push(t),o.push(t)):!1!==s.head.shouldRemove(t)&&i.push(t)}o.push(...a.values());let c=[];for(const t of o){let i=document.createRange().createContextualFragment(t.outerHTML).firstChild;if(!1!==s.callbacks.beforeNodeAdded(i)){if("href"in i&&i.href||"src"in i&&i.src){let e,t=new Promise((function(t){e=t}));i.addEventListener("load",(function(){e()})),c.push(t)}e.appendChild(i),s.callbacks.afterNodeAdded(i),r.push(i)}}for(const t of i)!1!==s.callbacks.beforeNodeRemoved(t)&&(e.removeChild(t),s.callbacks.afterNodeRemoved(t));return s.head.afterHeadMorphed(e,{added:r,kept:n,removed:i}),c}const n=function(){function e(){const e=document.createElement("div");return e.hidden=!0,document.body.insertAdjacentElement("afterend",e),e}function s(e){let t=[],s=document.activeElement;if("BODY"!==s?.tagName&&e.contains(s))for(;s&&(t.push(s),s!==e);)s=s.parentElement;return t}function r(e){let t=Array.from(e.querySelectorAll("[id]"));return e.getAttribute?.("id")&&t.push(e),t}function i(e,t,s,r){for(const i of r){const r=i.getAttribute("id");if(t.has(r)){let t=i;for(;t;){let i=e.get(t);if(null==i&&(i=new Set,e.set(t,i)),i.add(r),t===s)break;t=t.parentElement}}}}return function(n,o,a){const{persistentIds:c,idMap:l}=function(e,t){const s=r(e),n=r(t),o=function(e,t){let s=new Set,r=new Map;for(const{id:t,tagName:i}of e)r.has(t)?s.add(t):r.set(t,i);let i=new Set;for(const{id:e,tagName:n}of t)i.has(e)?s.add(e):r.get(e)===n&&i.add(e);for(const e of s)i.delete(e);return i}(s,n);let a=new Map;i(a,o,e,s);const c=t.__idiomorphRoot||t;return i(a,o,c,n),{persistentIds:o,idMap:a}}(n,o),h=function(e){let s=Object.assign({},t);return Object.assign(s,e),s.callbacks=Object.assign({},t.callbacks,e.callbacks),s.head=Object.assign({},t.head,e.head),s}(a),d=h.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(d))throw`Do not understand how to morph style ${d}`;return{target:n,newContent:o,config:h,morphStyle:d,ignoreActive:h.ignoreActive,ignoreActiveValue:h.ignoreActiveValue,restoreFocus:h.restoreFocus,idMap:l,persistentIds:c,pantry:e(),activeElementAndParents:s(n),callbacks:h.callbacks,head:h.head}}}(),{normalizeElement:o,normalizeParent:a}=function(){const e=new WeakSet;class t{constructor(e){this.originalNode=e,this.realParentNode=e.parentNode,this.previousSibling=e.previousSibling,this.nextSibling=e.nextSibling}get childNodes(){const e=[];let t=this.previousSibling?this.previousSibling.nextSibling:this.realParentNode.firstChild;for(;t&&t!=this.nextSibling;)e.push(t),t=t.nextSibling;return e}querySelectorAll(e){return this.childNodes.reduce(((t,s)=>{if(s instanceof Element){s.matches(e)&&t.push(s);const r=s.querySelectorAll(e);for(let e=0;e<r.length;e++)t.push(r[e])}return t}),[])}insertBefore(e,t){return this.realParentNode.insertBefore(e,t)}moveBefore(e,t){return this.realParentNode.moveBefore(e,t)}get __idiomorphRoot(){return this.originalNode}}return{normalizeElement:function(e){return e instanceof Document?e.documentElement:e},normalizeParent:function s(r){if(null==r)return document.createElement("div");if("string"==typeof r)return s(function(t){let s=new DOMParser,r=t.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(r.match(/<\/html>/)||r.match(/<\/head>/)||r.match(/<\/body>/)){let i=s.parseFromString(t,"text/html");if(r.match(/<\/html>/))return e.add(i),i;{let t=i.firstChild;return t&&e.add(t),t}}{let r=s.parseFromString("<body><template>"+t+"</template></body>","text/html").body.querySelector("template").content;return e.add(r),r}}(r));if(e.has(r))return r;if(r instanceof Node){if(r.parentNode)return new t(r);{const e=document.createElement("div");return e.append(r),e}}{const e=document.createElement("div");for(const t of[...r])e.append(t);return e}}}}();return{morph:function(e,t,r={}){e=o(e);const c=a(t),l=n(e,c,r),h=function(e,t){if(!e.config.restoreFocus)return t();let s=document.activeElement;if(!(s instanceof HTMLInputElement||s instanceof HTMLTextAreaElement))return t();const{id:r,selectionStart:i,selectionEnd:n}=s,o=t();r&&r!==document.activeElement?.getAttribute("id")&&(s=e.target.querySelector(`[id="${r}"]`),s?.focus());s&&!s.selectionEnd&&n&&s.setSelectionRange(i,n);return o}(l,(()=>function(e,t,s,r){if(e.head.block){const n=t.querySelector("head"),o=s.querySelector("head");if(n&&o){const t=i(n,o,e);return Promise.all(t).then((()=>{const t=Object.assign(e,{head:{block:!1,ignore:!0}});return r(t)}))}}return r(e)}(l,e,c,(t=>"innerHTML"===t.morphStyle?(s(t,e,c),Array.from(e.childNodes)):function(e,t,r){const i=a(t);return s(e,i,r,t,t.nextSibling),Array.from(i.childNodes)}(t,e,c)))));return l.pantry.remove(),h},defaults:t}}();function morphElements(e,t,{callbacks:s,...r}={}){Idiomorph.morph(e,t,{...r,callbacks:new DefaultIdiomorphCallbacks(s)})}function morphChildren(e,t,s={}){morphElements(e,t.childNodes,{...s,morphStyle:"innerHTML"})}function shouldRefreshFrameWithMorphing(e,t){return e instanceof FrameElement&&e.shouldReloadWithMorph&&(!t||areFramesCompatibleForRefreshing(e,t))&&!e.closest("[data-turbo-permanent]")}function areFramesCompatibleForRefreshing(e,t){return t instanceof Element&&"TURBO-FRAME"===t.nodeName&&e.id===t.id&&(!t.getAttribute("src")||urlsAreEqual(e.src,t.getAttribute("src")))}function closestFrameReloadableWithMorphing(e){return e.parentElement.closest("turbo-frame[src][refresh=morph]")}class DefaultIdiomorphCallbacks{#l;constructor({beforeNodeMorphed:e}={}){this.#l=e||(()=>!0)}beforeNodeAdded=e=>!(e.id&&e.hasAttribute("data-turbo-permanent")&&document.getElementById(e.id));beforeNodeMorphed=(e,t)=>{if(e instanceof Element){if(!e.hasAttribute("data-turbo-permanent")&&this.#l(e,t)){return!dispatch("turbo:before-morph-element",{cancelable:!0,target:e,detail:{currentElement:e,newElement:t}}).defaultPrevented}return!1}};beforeAttributeUpdated=(e,t,s)=>!dispatch("turbo:before-morph-attribute",{cancelable:!0,target:t,detail:{attributeName:e,mutationType:s}}).defaultPrevented;beforeNodeRemoved=e=>this.beforeNodeMorphed(e);afterNodeMorphed=(e,t)=>{e instanceof Element&&dispatch("turbo:morph-element",{target:e,detail:{currentElement:e,newElement:t}})}}class MorphingFrameRenderer extends FrameRenderer{static renderElement(e,t){dispatch("turbo:before-frame-morph",{target:e,detail:{currentElement:e,newElement:t}}),morphChildren(e,t,{callbacks:{beforeNodeMorphed:(t,s)=>!shouldRefreshFrameWithMorphing(t,s)||closestFrameReloadableWithMorphing(t)!==e||(t.reload(),!1)}})}async preservingPermanentElements(e){return await e()}}class ProgressBar{static animationDuration=300;static get defaultCSS(){return unindent`
12
+ .turbo-progress-bar {
13
+ position: fixed;
14
+ display: block;
15
+ top: 0;
16
+ left: 0;
17
+ height: 3px;
18
+ background: #0076ff;
19
+ z-index: 2147483647;
20
+ transition:
21
+ width ${ProgressBar.animationDuration}ms ease-out,
22
+ opacity ${ProgressBar.animationDuration/2}ms ${ProgressBar.animationDuration/2}ms ease-in;
23
+ transform: translate3d(0, 0, 0);
24
+ }
25
+ `}hiding=!1;value=0;visible=!1;constructor(){this.stylesheetElement=this.createStylesheetElement(),this.progressElement=this.createProgressElement(),this.installStylesheetElement(),this.setValue(0)}show(){this.visible||(this.visible=!0,this.installProgressElement(),this.startTrickling())}hide(){this.visible&&!this.hiding&&(this.hiding=!0,this.fadeProgressElement((()=>{this.uninstallProgressElement(),this.stopTrickling(),this.visible=!1,this.hiding=!1})))}setValue(e){this.value=e,this.refresh()}installStylesheetElement(){document.head.insertBefore(this.stylesheetElement,document.head.firstChild)}installProgressElement(){this.progressElement.style.width="0",this.progressElement.style.opacity="1",document.documentElement.insertBefore(this.progressElement,document.body),this.refresh()}fadeProgressElement(e){this.progressElement.style.opacity="0",setTimeout(e,1.5*ProgressBar.animationDuration)}uninstallProgressElement(){this.progressElement.parentNode&&document.documentElement.removeChild(this.progressElement)}startTrickling(){this.trickleInterval||(this.trickleInterval=window.setInterval(this.trickle,ProgressBar.animationDuration))}stopTrickling(){window.clearInterval(this.trickleInterval),delete this.trickleInterval}trickle=()=>{this.setValue(this.value+Math.random()/100)};refresh(){requestAnimationFrame((()=>{this.progressElement.style.width=10+90*this.value+"%"}))}createStylesheetElement(){const e=document.createElement("style");e.type="text/css",e.textContent=ProgressBar.defaultCSS;const t=getCspNonce();return t&&(e.nonce=t),e}createProgressElement(){const e=document.createElement("div");return e.className="turbo-progress-bar",e}}class HeadSnapshot extends Snapshot{detailsByOuterHTML=this.children.filter((e=>!elementIsNoscript(e))).map((e=>elementWithoutNonce(e))).reduce(((e,t)=>{const{outerHTML:s}=t,r=s in e?e[s]:{type:elementType(t),tracked:elementIsTracked(t),elements:[]};return{...e,[s]:{...r,elements:[...r.elements,t]}}}),{});get trackedElementSignature(){return Object.keys(this.detailsByOuterHTML).filter((e=>this.detailsByOuterHTML[e].tracked)).join("")}getScriptElementsNotInSnapshot(e){return this.getElementsMatchingTypeNotInSnapshot("script",e)}getStylesheetElementsNotInSnapshot(e){return this.getElementsMatchingTypeNotInSnapshot("stylesheet",e)}getElementsMatchingTypeNotInSnapshot(e,t){return Object.keys(this.detailsByOuterHTML).filter((e=>!(e in t.detailsByOuterHTML))).map((e=>this.detailsByOuterHTML[e])).filter((({type:t})=>t==e)).map((({elements:[e]})=>e))}get provisionalElements(){return Object.keys(this.detailsByOuterHTML).reduce(((e,t)=>{const{type:s,tracked:r,elements:i}=this.detailsByOuterHTML[t];return null!=s||r?i.length>1?[...e,...i.slice(1)]:e:[...e,...i]}),[])}getMetaValue(e){const t=this.findMetaElementByName(e);return t?t.getAttribute("content"):null}findMetaElementByName(e){return Object.keys(this.detailsByOuterHTML).reduce(((t,s)=>{const{elements:[r]}=this.detailsByOuterHTML[s];return elementIsMetaElementWithName(r,e)?r:t}),0)}}function elementType(e){return elementIsScript(e)?"script":elementIsStylesheet(e)?"stylesheet":void 0}function elementIsTracked(e){return"reload"==e.getAttribute("data-turbo-track")}function elementIsScript(e){return"script"==e.localName}function elementIsNoscript(e){return"noscript"==e.localName}function elementIsStylesheet(e){const t=e.localName;return"style"==t||"link"==t&&"stylesheet"==e.getAttribute("rel")}function elementIsMetaElementWithName(e,t){return"meta"==e.localName&&e.getAttribute("name")==t}function elementWithoutNonce(e){return e.hasAttribute("nonce")&&e.setAttribute("nonce",""),e}class PageSnapshot extends Snapshot{static fromHTMLString(e=""){return this.fromDocument(parseHTMLDocument(e))}static fromElement(e){return this.fromDocument(e.ownerDocument)}static fromDocument({documentElement:e,body:t,head:s}){return new this(e,t,new HeadSnapshot(s))}constructor(e,t,s){super(t),this.documentElement=e,this.headSnapshot=s}clone(){const e=this.element.cloneNode(!0),t=this.element.querySelectorAll("select"),s=e.querySelectorAll("select");for(const[e,r]of t.entries()){const t=s[e];for(const e of t.selectedOptions)e.selected=!1;for(const e of r.selectedOptions)t.options[e.index].selected=!0}for(const t of e.querySelectorAll('input[type="password"]'))t.value="";return new PageSnapshot(this.documentElement,e,this.headSnapshot)}get lang(){return this.documentElement.getAttribute("lang")}get headElement(){return this.headSnapshot.element}get rootLocation(){return expandURL(this.getSetting("root")??"/")}get cacheControlValue(){return this.getSetting("cache-control")}get isPreviewable(){return"no-preview"!=this.cacheControlValue}get isCacheable(){return"no-cache"!=this.cacheControlValue}get isVisitable(){return"reload"!=this.getSetting("visit-control")}get prefersViewTransitions(){return("true"===this.getSetting("view-transition")||"same-origin"===this.headSnapshot.getMetaValue("view-transition"))&&!window.matchMedia("(prefers-reduced-motion: reduce)").matches}get shouldMorphPage(){return"morph"===this.getSetting("refresh-method")}get shouldPreserveScrollPosition(){return"preserve"===this.getSetting("refresh-scroll")}getSetting(e){return this.headSnapshot.getMetaValue(`turbo-${e}`)}}class ViewTransitioner{#h=!1;#d=Promise.resolve();renderChange(e,t){return e&&this.viewTransitionsAvailable&&!this.#h?(this.#h=!0,this.#d=this.#d.then((async()=>{await document.startViewTransition(t).finished}))):this.#d=this.#d.then(t),this.#d}get viewTransitionsAvailable(){return document.startViewTransition}}const defaultOptions={action:"advance",historyChanged:!1,visitCachedSnapshot:()=>{},willRender:!0,updateHistory:!0,shouldCacheSnapshot:!0,acceptsStreamResponse:!1},TimingMetric={visitStart:"visitStart",requestStart:"requestStart",requestEnd:"requestEnd",visitEnd:"visitEnd"},VisitState={initialized:"initialized",started:"started",canceled:"canceled",failed:"failed",completed:"completed"},SystemStatusCode={networkFailure:0,timeoutFailure:-1,contentTypeMismatch:-2},Direction={advance:"forward",restore:"back",replace:"none"};class Visit{identifier=uuid();timingMetrics={};followedRedirect=!1;historyChanged=!1;scrolled=!1;shouldCacheSnapshot=!0;acceptsStreamResponse=!1;snapshotCached=!1;state=VisitState.initialized;viewTransitioner=new ViewTransitioner;constructor(e,t,s,r={}){this.delegate=e,this.location=t,this.restorationIdentifier=s||uuid();const{action:i,historyChanged:n,referrer:o,snapshot:a,snapshotHTML:c,response:l,visitCachedSnapshot:h,willRender:d,updateHistory:u,shouldCacheSnapshot:m,acceptsStreamResponse:p,direction:g}={...defaultOptions,...r};this.action=i,this.historyChanged=n,this.referrer=o,this.snapshot=a,this.snapshotHTML=c,this.response=l,this.isSamePage=this.delegate.locationWithActionIsSamePage(this.location,this.action),this.isPageRefresh=this.view.isPageRefresh(this),this.visitCachedSnapshot=h,this.willRender=d,this.updateHistory=u,this.scrolled=!d,this.shouldCacheSnapshot=m,this.acceptsStreamResponse=p,this.direction=g||Direction[i]}get adapter(){return this.delegate.adapter}get view(){return this.delegate.view}get history(){return this.delegate.history}get restorationData(){return this.history.getRestorationDataForIdentifier(this.restorationIdentifier)}get silent(){return this.isSamePage}start(){this.state==VisitState.initialized&&(this.recordTimingMetric(TimingMetric.visitStart),this.state=VisitState.started,this.adapter.visitStarted(this),this.delegate.visitStarted(this))}cancel(){this.state==VisitState.started&&(this.request&&this.request.cancel(),this.cancelRender(),this.state=VisitState.canceled)}complete(){this.state==VisitState.started&&(this.recordTimingMetric(TimingMetric.visitEnd),this.adapter.visitCompleted(this),this.state=VisitState.completed,this.followRedirect(),this.followedRedirect||this.delegate.visitCompleted(this))}fail(){this.state==VisitState.started&&(this.state=VisitState.failed,this.adapter.visitFailed(this),this.delegate.visitCompleted(this))}changeHistory(){if(!this.historyChanged&&this.updateHistory){const e=getHistoryMethodForAction(this.location.href===this.referrer?.href?"replace":this.action);this.history.update(e,this.location,this.restorationIdentifier),this.historyChanged=!0}}issueRequest(){this.hasPreloadedResponse()?this.simulateRequest():this.shouldIssueRequest()&&!this.request&&(this.request=new FetchRequest(this,FetchMethod.get,this.location),this.request.perform())}simulateRequest(){this.response&&(this.startRequest(),this.recordResponse(),this.finishRequest())}startRequest(){this.recordTimingMetric(TimingMetric.requestStart),this.adapter.visitRequestStarted(this)}recordResponse(e=this.response){if(this.response=e,e){const{statusCode:t}=e;isSuccessful(t)?this.adapter.visitRequestCompleted(this):this.adapter.visitRequestFailedWithStatusCode(this,t)}}finishRequest(){this.recordTimingMetric(TimingMetric.requestEnd),this.adapter.visitRequestFinished(this)}loadResponse(){if(this.response){const{statusCode:e,responseHTML:t}=this.response;this.render((async()=>{if(this.shouldCacheSnapshot&&this.cacheSnapshot(),this.view.renderPromise&&await this.view.renderPromise,isSuccessful(e)&&null!=t){const e=PageSnapshot.fromHTMLString(t);await this.renderPageSnapshot(e,!1),this.adapter.visitRendered(this),this.complete()}else await this.view.renderError(PageSnapshot.fromHTMLString(t),this),this.adapter.visitRendered(this),this.fail()}))}}getCachedSnapshot(){const e=this.view.getCachedSnapshotForLocation(this.location)||this.getPreloadedSnapshot();if(e&&(!getAnchor(this.location)||e.hasAnchor(getAnchor(this.location)))&&("restore"==this.action||e.isPreviewable))return e}getPreloadedSnapshot(){if(this.snapshotHTML)return PageSnapshot.fromHTMLString(this.snapshotHTML)}hasCachedSnapshot(){return null!=this.getCachedSnapshot()}loadCachedSnapshot(){const e=this.getCachedSnapshot();if(e){const t=this.shouldIssueRequest();this.render((async()=>{this.cacheSnapshot(),this.isSamePage||this.isPageRefresh?this.adapter.visitRendered(this):(this.view.renderPromise&&await this.view.renderPromise,await this.renderPageSnapshot(e,t),this.adapter.visitRendered(this),t||this.complete())}))}}followRedirect(){this.redirectedToLocation&&!this.followedRedirect&&this.response?.redirected&&(this.adapter.visitProposedToLocation(this.redirectedToLocation,{action:"replace",response:this.response,shouldCacheSnapshot:!1,willRender:!1}),this.followedRedirect=!0)}goToSamePageAnchor(){this.isSamePage&&this.render((async()=>{this.cacheSnapshot(),this.performScroll(),this.changeHistory(),this.adapter.visitRendered(this)}))}prepareRequest(e){this.acceptsStreamResponse&&e.acceptResponseType(StreamMessage.contentType)}requestStarted(){this.startRequest()}requestPreventedHandlingResponse(e,t){}async requestSucceededWithResponse(e,t){const s=await t.responseHTML,{redirected:r,statusCode:i}=t;null==s?this.recordResponse({statusCode:SystemStatusCode.contentTypeMismatch,redirected:r}):(this.redirectedToLocation=t.redirected?t.location:void 0,this.recordResponse({statusCode:i,responseHTML:s,redirected:r}))}async requestFailedWithResponse(e,t){const s=await t.responseHTML,{redirected:r,statusCode:i}=t;null==s?this.recordResponse({statusCode:SystemStatusCode.contentTypeMismatch,redirected:r}):this.recordResponse({statusCode:i,responseHTML:s,redirected:r})}requestErrored(e,t){this.recordResponse({statusCode:SystemStatusCode.networkFailure,redirected:!1})}requestFinished(){this.finishRequest()}performScroll(){this.scrolled||this.view.forceReloaded||this.view.shouldPreserveScrollPosition(this)||("restore"==this.action?this.scrollToRestoredPosition()||this.scrollToAnchor()||this.view.scrollToTop():this.scrollToAnchor()||this.view.scrollToTop(),this.isSamePage&&this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation,this.location),this.scrolled=!0)}scrollToRestoredPosition(){const{scrollPosition:e}=this.restorationData;if(e)return this.view.scrollToPosition(e),!0}scrollToAnchor(){const e=getAnchor(this.location);if(null!=e)return this.view.scrollToAnchor(e),!0}recordTimingMetric(e){this.timingMetrics[e]=(new Date).getTime()}getTimingMetrics(){return{...this.timingMetrics}}hasPreloadedResponse(){return"object"==typeof this.response}shouldIssueRequest(){return!this.isSamePage&&("restore"==this.action?!this.hasCachedSnapshot():this.willRender)}cacheSnapshot(){this.snapshotCached||(this.view.cacheSnapshot(this.snapshot).then((e=>e&&this.visitCachedSnapshot(e))),this.snapshotCached=!0)}async render(e){this.cancelRender(),await new Promise((e=>{this.frame="hidden"===document.visibilityState?setTimeout((()=>e()),0):requestAnimationFrame((()=>e()))})),await e(),delete this.frame}async renderPageSnapshot(e,t){await this.viewTransitioner.renderChange(this.view.shouldTransitionTo(e),(async()=>{await this.view.renderPage(e,t,this.willRender,this),this.performScroll()}))}cancelRender(){this.frame&&(cancelAnimationFrame(this.frame),delete this.frame)}}function isSuccessful(e){return e>=200&&e<300}class BrowserAdapter{progressBar=new ProgressBar;constructor(e){this.session=e}visitProposedToLocation(e,t){locationIsVisitable(e,this.navigator.rootLocation)?this.navigator.startVisit(e,t?.restorationIdentifier||uuid(),t):window.location.href=e.toString()}visitStarted(e){this.location=e.location,this.redirectedToLocation=null,e.loadCachedSnapshot(),e.issueRequest(),e.goToSamePageAnchor()}visitRequestStarted(e){this.progressBar.setValue(0),e.hasCachedSnapshot()||"restore"!=e.action?this.showVisitProgressBarAfterDelay():this.showProgressBar()}visitRequestCompleted(e){e.loadResponse(),e.response.redirected&&(this.redirectedToLocation=e.redirectedToLocation)}visitRequestFailedWithStatusCode(e,t){switch(t){case SystemStatusCode.networkFailure:case SystemStatusCode.timeoutFailure:case SystemStatusCode.contentTypeMismatch:return this.reload({reason:"request_failed",context:{statusCode:t}});default:return e.loadResponse()}}visitRequestFinished(e){}visitCompleted(e){this.progressBar.setValue(1),this.hideVisitProgressBar()}pageInvalidated(e){this.reload(e)}visitFailed(e){this.progressBar.setValue(1),this.hideVisitProgressBar()}visitRendered(e){}linkPrefetchingIsEnabledForLocation(e){return!0}formSubmissionStarted(e){this.progressBar.setValue(0),this.showFormProgressBarAfterDelay()}formSubmissionFinished(e){this.progressBar.setValue(1),this.hideFormProgressBar()}showVisitProgressBarAfterDelay(){this.visitProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay)}hideVisitProgressBar(){this.progressBar.hide(),null!=this.visitProgressBarTimeout&&(window.clearTimeout(this.visitProgressBarTimeout),delete this.visitProgressBarTimeout)}showFormProgressBarAfterDelay(){null==this.formProgressBarTimeout&&(this.formProgressBarTimeout=window.setTimeout(this.showProgressBar,this.session.progressBarDelay))}hideFormProgressBar(){this.progressBar.hide(),null!=this.formProgressBarTimeout&&(window.clearTimeout(this.formProgressBarTimeout),delete this.formProgressBarTimeout)}showProgressBar=()=>{this.progressBar.show()};reload(e){dispatch("turbo:reload",{detail:e}),window.location.href=(this.redirectedToLocation||this.location)?.toString()||window.location.href}get navigator(){return this.session.navigator}}class CacheObserver{selector="[data-turbo-temporary]";deprecatedSelector="[data-turbo-cache=false]";started=!1;start(){this.started||(this.started=!0,addEventListener("turbo:before-cache",this.removeTemporaryElements,!1))}stop(){this.started&&(this.started=!1,removeEventListener("turbo:before-cache",this.removeTemporaryElements,!1))}removeTemporaryElements=e=>{for(const e of this.temporaryElements)e.remove()};get temporaryElements(){return[...document.querySelectorAll(this.selector),...this.temporaryElementsWithDeprecation]}get temporaryElementsWithDeprecation(){const e=document.querySelectorAll(this.deprecatedSelector);return e.length&&console.warn(`The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.`),[...e]}}class FrameRedirector{constructor(e,t){this.session=e,this.element=t,this.linkInterceptor=new LinkInterceptor(this,t),this.formSubmitObserver=new FormSubmitObserver(this,t)}start(){this.linkInterceptor.start(),this.formSubmitObserver.start()}stop(){this.linkInterceptor.stop(),this.formSubmitObserver.stop()}shouldInterceptLinkClick(e,t,s){return this.#u(e)}linkClickIntercepted(e,t,s){const r=this.#m(e);r&&r.delegate.linkClickIntercepted(e,t,s)}willSubmitForm(e,t){return null==e.closest("turbo-frame")&&this.#p(e,t)&&this.#u(e,t)}formSubmitted(e,t){const s=this.#m(e,t);s&&s.delegate.formSubmitted(e,t)}#p(e,t){const s=getAction$1(e,t),r=this.element.ownerDocument.querySelector('meta[name="turbo-root"]'),i=expandURL(r?.content??"/");return this.#u(e,t)&&locationIsVisitable(s,i)}#u(e,t){if(e instanceof HTMLFormElement?this.session.submissionIsNavigatable(e,t):this.session.elementIsNavigatable(e)){const s=this.#m(e,t);return!!s&&s!=e.closest("turbo-frame")}return!1}#m(e,t){const s=t?.getAttribute("data-turbo-frame")||e.getAttribute("data-turbo-frame");if(s&&"_top"!=s){const e=this.element.querySelector(`#${s}:not([disabled])`);if(e instanceof FrameElement)return e}}}class History{location;restorationIdentifier=uuid();restorationData={};started=!1;pageLoaded=!1;currentIndex=0;constructor(e){this.delegate=e}start(){this.started||(addEventListener("popstate",this.onPopState,!1),addEventListener("load",this.onPageLoad,!1),this.currentIndex=history.state?.turbo?.restorationIndex||0,this.started=!0,this.replace(new URL(window.location.href)))}stop(){this.started&&(removeEventListener("popstate",this.onPopState,!1),removeEventListener("load",this.onPageLoad,!1),this.started=!1)}push(e,t){this.update(history.pushState,e,t)}replace(e,t){this.update(history.replaceState,e,t)}update(e,t,s=uuid()){e===history.pushState&&++this.currentIndex;const r={turbo:{restorationIdentifier:s,restorationIndex:this.currentIndex}};e.call(history,r,"",t.href),this.location=t,this.restorationIdentifier=s}getRestorationDataForIdentifier(e){return this.restorationData[e]||{}}updateRestorationData(e){const{restorationIdentifier:t}=this,s=this.restorationData[t];this.restorationData[t]={...s,...e}}assumeControlOfScrollRestoration(){this.previousScrollRestoration||(this.previousScrollRestoration=history.scrollRestoration??"auto",history.scrollRestoration="manual")}relinquishControlOfScrollRestoration(){this.previousScrollRestoration&&(history.scrollRestoration=this.previousScrollRestoration,delete this.previousScrollRestoration)}onPopState=e=>{if(this.shouldHandlePopState()){const{turbo:t}=e.state||{};if(t){this.location=new URL(window.location.href);const{restorationIdentifier:e,restorationIndex:s}=t;this.restorationIdentifier=e;const r=s>this.currentIndex?"forward":"back";this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location,e,r),this.currentIndex=s}}};onPageLoad=async e=>{await nextMicrotask(),this.pageLoaded=!0};shouldHandlePopState(){return this.pageIsLoaded()}pageIsLoaded(){return this.pageLoaded||"complete"==document.readyState}}class LinkPrefetchObserver{started=!1;#g=null;constructor(e,t){this.delegate=e,this.eventTarget=t}start(){this.started||("loading"===this.eventTarget.readyState?this.eventTarget.addEventListener("DOMContentLoaded",this.#f,{once:!0}):this.#f())}stop(){this.started&&(this.eventTarget.removeEventListener("mouseenter",this.#b,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("mouseleave",this.#v,{capture:!0,passive:!0}),this.eventTarget.removeEventListener("turbo:before-fetch-request",this.#S,!0),this.started=!1)}#f=()=>{this.eventTarget.addEventListener("mouseenter",this.#b,{capture:!0,passive:!0}),this.eventTarget.addEventListener("mouseleave",this.#v,{capture:!0,passive:!0}),this.eventTarget.addEventListener("turbo:before-fetch-request",this.#S,!0),this.started=!0};#b=e=>{if("false"===getMetaContent("turbo-prefetch"))return;const t=e.target;if(t.matches&&t.matches("a[href]:not([target^=_]):not([download])")&&this.#E(t)){const e=t,s=getLocationForLink(e);if(this.delegate.canPrefetchRequestToLocation(e,s)){this.#g=e;const r=new FetchRequest(this,FetchMethod.get,s,new URLSearchParams,t);r.fetchOptions.priority="low",prefetchCache.setLater(s.toString(),r,this.#y)}}};#v=e=>{e.target===this.#g&&this.#w()};#w=()=>{prefetchCache.clear(),this.#g=null};#S=e=>{if("FORM"!==e.target.tagName&&"GET"===e.detail.fetchOptions.method){const t=prefetchCache.get(e.detail.url.toString());t&&(e.detail.fetchRequest=t),prefetchCache.clear()}};prepareRequest(e){const t=e.target;e.headers["X-Sec-Purpose"]="prefetch";const s=t.closest("turbo-frame"),r=t.getAttribute("data-turbo-frame")||s?.getAttribute("target")||s?.id;r&&"_top"!==r&&(e.headers["Turbo-Frame"]=r)}requestSucceededWithResponse(){}requestStarted(e){}requestErrored(e){}requestFinished(e){}requestPreventedHandlingResponse(e,t){}requestFailedWithResponse(e,t){}get#y(){return Number(getMetaContent("turbo-prefetch-cache-time"))||1e4}#E(e){return!!e.getAttribute("href")&&(!unfetchableLink(e)&&(!linkToTheSamePage(e)&&(!linkOptsOut(e)&&(!nonSafeLink(e)&&!eventPrevented(e)))))}}const unfetchableLink=e=>e.origin!==document.location.origin||!["http:","https:"].includes(e.protocol)||e.hasAttribute("target"),linkToTheSamePage=e=>e.pathname+e.search===document.location.pathname+document.location.search||e.href.startsWith("#"),linkOptsOut=e=>{if("false"===e.getAttribute("data-turbo-prefetch"))return!0;if("false"===e.getAttribute("data-turbo"))return!0;const t=findClosestRecursively(e,"[data-turbo-prefetch]");return!(!t||"false"!==t.getAttribute("data-turbo-prefetch"))},nonSafeLink=e=>{const t=e.getAttribute("data-turbo-method");return!(!t||"get"===t.toLowerCase())||(!!isUJS(e)||(!!e.hasAttribute("data-turbo-confirm")||!!e.hasAttribute("data-turbo-stream")))},isUJS=e=>e.hasAttribute("data-remote")||e.hasAttribute("data-behavior")||e.hasAttribute("data-confirm")||e.hasAttribute("data-method"),eventPrevented=e=>dispatch("turbo:before-prefetch",{target:e,cancelable:!0}).defaultPrevented;class Navigator{constructor(e){this.delegate=e}proposeVisit(e,t={}){this.delegate.allowsVisitingLocationWithAction(e,t.action)&&this.delegate.visitProposedToLocation(e,t)}startVisit(e,t,s={}){this.stop(),this.currentVisit=new Visit(this,expandURL(e),t,{referrer:this.location,...s}),this.currentVisit.start()}submitForm(e,t){this.stop(),this.formSubmission=new FormSubmission(this,e,t,!0),this.formSubmission.start()}stop(){this.formSubmission&&(this.formSubmission.stop(),delete this.formSubmission),this.currentVisit&&(this.currentVisit.cancel(),delete this.currentVisit)}get adapter(){return this.delegate.adapter}get view(){return this.delegate.view}get rootLocation(){return this.view.snapshot.rootLocation}get history(){return this.delegate.history}formSubmissionStarted(e){"function"==typeof this.adapter.formSubmissionStarted&&this.adapter.formSubmissionStarted(e)}async formSubmissionSucceededWithResponse(e,t){if(e==this.formSubmission){const s=await t.responseHTML;if(s){const r=e.isSafe;r||this.view.clearSnapshotCache();const{statusCode:i,redirected:n}=t,o={action:this.#R(e,t),shouldCacheSnapshot:r,response:{statusCode:i,responseHTML:s,redirected:n}};this.proposeVisit(t.location,o)}}}async formSubmissionFailedWithResponse(e,t){const s=await t.responseHTML;if(s){const e=PageSnapshot.fromHTMLString(s);t.serverError?await this.view.renderError(e,this.currentVisit):await this.view.renderPage(e,!1,!0,this.currentVisit),e.shouldPreserveScrollPosition||this.view.scrollToTop(),this.view.clearSnapshotCache()}}formSubmissionErrored(e,t){console.error(t)}formSubmissionFinished(e){"function"==typeof this.adapter.formSubmissionFinished&&this.adapter.formSubmissionFinished(e)}linkPrefetchingIsEnabledForLocation(e){return"function"!=typeof this.adapter.linkPrefetchingIsEnabledForLocation||this.adapter.linkPrefetchingIsEnabledForLocation(e)}visitStarted(e){this.delegate.visitStarted(e)}visitCompleted(e){this.delegate.visitCompleted(e),delete this.currentVisit}locationWithActionIsSamePage(e,t){const s=getAnchor(e),r=getAnchor(this.view.lastRenderedLocation),i="restore"===t&&void 0===s;return"replace"!==t&&getRequestURL(e)===getRequestURL(this.view.lastRenderedLocation)&&(i||null!=s&&s!==r)}visitScrolledToSamePageLocation(e,t){this.delegate.visitScrolledToSamePageLocation(e,t)}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}#R(e,t){const{submitter:s,formElement:r}=e;return getVisitAction(s,r)||this.#A(t)}#A(e){return e.redirected&&e.location.href===this.location?.href?"replace":"advance"}}const PageStage={initial:0,loading:1,interactive:2,complete:3};class PageObserver{stage=PageStage.initial;started=!1;constructor(e){this.delegate=e}start(){this.started||(this.stage==PageStage.initial&&(this.stage=PageStage.loading),document.addEventListener("readystatechange",this.interpretReadyState,!1),addEventListener("pagehide",this.pageWillUnload,!1),this.started=!0)}stop(){this.started&&(document.removeEventListener("readystatechange",this.interpretReadyState,!1),removeEventListener("pagehide",this.pageWillUnload,!1),this.started=!1)}interpretReadyState=()=>{const{readyState:e}=this;"interactive"==e?this.pageIsInteractive():"complete"==e&&this.pageIsComplete()};pageIsInteractive(){this.stage==PageStage.loading&&(this.stage=PageStage.interactive,this.delegate.pageBecameInteractive())}pageIsComplete(){this.pageIsInteractive(),this.stage==PageStage.interactive&&(this.stage=PageStage.complete,this.delegate.pageLoaded())}pageWillUnload=()=>{this.delegate.pageWillUnload()};get readyState(){return document.readyState}}class ScrollObserver{started=!1;constructor(e){this.delegate=e}start(){this.started||(addEventListener("scroll",this.onScroll,!1),this.onScroll(),this.started=!0)}stop(){this.started&&(removeEventListener("scroll",this.onScroll,!1),this.started=!1)}onScroll=()=>{this.updatePosition({x:window.pageXOffset,y:window.pageYOffset})};updatePosition(e){this.delegate.scrollPositionChanged(e)}}class StreamMessageRenderer{render({fragment:e}){Bardo.preservingPermanentElements(this,getPermanentElementMapForFragment(e),(()=>{withAutofocusFromFragment(e,(()=>{withPreservedFocus((()=>{document.documentElement.appendChild(e)}))}))}))}enteringBardo(e,t){t.replaceWith(e.cloneNode(!0))}leavingBardo(){}}function getPermanentElementMapForFragment(e){const t=queryPermanentElementsAll(document.documentElement),s={};for(const r of t){const{id:t}=r;for(const i of e.querySelectorAll("turbo-stream")){const e=getPermanentElementById(i.templateElement.content,t);e&&(s[t]=[r,e])}}return s}async function withAutofocusFromFragment(e,t){const s=`turbo-stream-autofocus-${uuid()}`,r=firstAutofocusableElementInStreams(e.querySelectorAll("turbo-stream"));let i=null;r&&(i=r.id?r.id:s,r.id=i),t(),await nextRepaint();if((null==document.activeElement||document.activeElement==document.body)&&i){const e=document.getElementById(i);elementIsFocusable(e)&&e.focus(),e&&e.id==s&&e.removeAttribute("id")}}async function withPreservedFocus(e){const[t,s]=await around(e,(()=>document.activeElement)),r=t&&t.id;if(r){const e=document.getElementById(r);elementIsFocusable(e)&&e!=s&&e.focus()}}function firstAutofocusableElementInStreams(e){for(const t of e){const e=queryAutofocusableElement(t.templateElement.content);if(e)return e}return null}class StreamObserver{sources=new Set;#L=!1;constructor(e){this.delegate=e}start(){this.#L||(this.#L=!0,addEventListener("turbo:before-fetch-response",this.inspectFetchResponse,!1))}stop(){this.#L&&(this.#L=!1,removeEventListener("turbo:before-fetch-response",this.inspectFetchResponse,!1))}connectStreamSource(e){this.streamSourceIsConnected(e)||(this.sources.add(e),e.addEventListener("message",this.receiveMessageEvent,!1))}disconnectStreamSource(e){this.streamSourceIsConnected(e)&&(this.sources.delete(e),e.removeEventListener("message",this.receiveMessageEvent,!1))}streamSourceIsConnected(e){return this.sources.has(e)}inspectFetchResponse=e=>{const t=fetchResponseFromEvent(e);t&&fetchResponseIsStream(t)&&(e.preventDefault(),this.receiveMessageResponse(t))};receiveMessageEvent=e=>{this.#L&&"string"==typeof e.data&&this.receiveMessageHTML(e.data)};async receiveMessageResponse(e){const t=await e.responseHTML;t&&this.receiveMessageHTML(t)}receiveMessageHTML(e){this.delegate.receivedMessageFromStream(StreamMessage.wrap(e))}}function fetchResponseFromEvent(e){const t=e.detail?.fetchResponse;if(t instanceof FetchResponse)return t}function fetchResponseIsStream(e){return(e.contentType??"").startsWith(StreamMessage.contentType)}class ErrorRenderer extends Renderer{static renderElement(e,t){const{documentElement:s,body:r}=document;s.replaceChild(t,r)}async render(){this.replaceHeadAndBody(),this.activateScriptElements()}replaceHeadAndBody(){const{documentElement:e,head:t}=document;e.replaceChild(this.newHead,t),this.renderElement(this.currentElement,this.newElement)}activateScriptElements(){for(const e of this.scriptElements){const t=e.parentNode;if(t){const s=activateScriptElement(e);t.replaceChild(s,e)}}}get newHead(){return this.newSnapshot.headSnapshot.element}get scriptElements(){return document.documentElement.querySelectorAll("script")}}class PageRenderer extends Renderer{static renderElement(e,t){document.body&&t instanceof HTMLBodyElement?document.body.replaceWith(t):document.documentElement.appendChild(t)}get shouldRender(){return this.newSnapshot.isVisitable&&this.trackedElementsAreIdentical}get reloadReason(){return this.newSnapshot.isVisitable?this.trackedElementsAreIdentical?void 0:{reason:"tracked_element_mismatch"}:{reason:"turbo_visit_control_is_reload"}}async prepareToRender(){this.#C(),await this.mergeHead()}async render(){this.willRender&&await this.replaceBody()}finishRendering(){super.finishRendering(),this.isPreview||this.focusFirstAutofocusableElement()}get currentHeadSnapshot(){return this.currentSnapshot.headSnapshot}get newHeadSnapshot(){return this.newSnapshot.headSnapshot}get newElement(){return this.newSnapshot.element}#C(){const{documentElement:e}=this.currentSnapshot,{lang:t}=this.newSnapshot;t?e.setAttribute("lang",t):e.removeAttribute("lang")}async mergeHead(){const e=this.mergeProvisionalElements(),t=this.copyNewHeadStylesheetElements();this.copyNewHeadScriptElements(),await e,await t,this.willRender&&this.removeUnusedDynamicStylesheetElements()}async replaceBody(){await this.preservingPermanentElements((async()=>{this.activateNewBody(),await this.assignNewBody()}))}get trackedElementsAreIdentical(){return this.currentHeadSnapshot.trackedElementSignature==this.newHeadSnapshot.trackedElementSignature}async copyNewHeadStylesheetElements(){const e=[];for(const t of this.newHeadStylesheetElements)e.push(waitForLoad(t)),document.head.appendChild(t);await Promise.all(e)}copyNewHeadScriptElements(){for(const e of this.newHeadScriptElements)document.head.appendChild(activateScriptElement(e))}removeUnusedDynamicStylesheetElements(){for(const e of this.unusedDynamicStylesheetElements)document.head.removeChild(e)}async mergeProvisionalElements(){const e=[...this.newHeadProvisionalElements];for(const t of this.currentHeadProvisionalElements)this.isCurrentElementInElementList(t,e)||document.head.removeChild(t);for(const t of e)document.head.appendChild(t)}isCurrentElementInElementList(e,t){for(const[s,r]of t.entries()){if("TITLE"==e.tagName){if("TITLE"!=r.tagName)continue;if(e.innerHTML==r.innerHTML)return t.splice(s,1),!0}if(r.isEqualNode(e))return t.splice(s,1),!0}return!1}removeCurrentHeadProvisionalElements(){for(const e of this.currentHeadProvisionalElements)document.head.removeChild(e)}copyNewHeadProvisionalElements(){for(const e of this.newHeadProvisionalElements)document.head.appendChild(e)}activateNewBody(){document.adoptNode(this.newElement),this.activateNewBodyScriptElements()}activateNewBodyScriptElements(){for(const e of this.newBodyScriptElements){const t=activateScriptElement(e);e.replaceWith(t)}}async assignNewBody(){await this.renderElement(this.currentElement,this.newElement)}get unusedDynamicStylesheetElements(){return this.oldHeadStylesheetElements.filter((e=>"dynamic"===e.getAttribute("data-turbo-track")))}get oldHeadStylesheetElements(){return this.currentHeadSnapshot.getStylesheetElementsNotInSnapshot(this.newHeadSnapshot)}get newHeadStylesheetElements(){return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot)}get newHeadScriptElements(){return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot)}get currentHeadProvisionalElements(){return this.currentHeadSnapshot.provisionalElements}get newHeadProvisionalElements(){return this.newHeadSnapshot.provisionalElements}get newBodyScriptElements(){return this.newElement.querySelectorAll("script")}}class MorphingPageRenderer extends PageRenderer{static renderElement(e,t){morphElements(e,t,{callbacks:{beforeNodeMorphed:(e,t)=>!(shouldRefreshFrameWithMorphing(e,t)&&!closestFrameReloadableWithMorphing(e))||(e.reload(),!1)}}),dispatch("turbo:morph",{detail:{currentElement:e,newElement:t}})}async preservingPermanentElements(e){return await e()}get renderMethod(){return"morph"}get shouldAutofocus(){return!1}}class SnapshotCache{keys=[];snapshots={};constructor(e){this.size=e}has(e){return toCacheKey(e)in this.snapshots}get(e){if(this.has(e)){const t=this.read(e);return this.touch(e),t}}put(e,t){return this.write(e,t),this.touch(e),t}clear(){this.snapshots={}}read(e){return this.snapshots[toCacheKey(e)]}write(e,t){this.snapshots[toCacheKey(e)]=t}touch(e){const t=toCacheKey(e),s=this.keys.indexOf(t);s>-1&&this.keys.splice(s,1),this.keys.unshift(t),this.trim()}trim(){for(const e of this.keys.splice(this.size))delete this.snapshots[e]}}class PageView extends View{snapshotCache=new SnapshotCache(10);lastRenderedLocation=new URL(location.href);forceReloaded=!1;shouldTransitionTo(e){return this.snapshot.prefersViewTransitions&&e.prefersViewTransitions}renderPage(e,t=!1,s=!0,r){const i=new(this.isPageRefresh(r)&&this.snapshot.shouldMorphPage?MorphingPageRenderer:PageRenderer)(this.snapshot,e,t,s);return i.shouldRender?r?.changeHistory():this.forceReloaded=!0,this.render(i)}renderError(e,t){t?.changeHistory();const s=new ErrorRenderer(this.snapshot,e,!1);return this.render(s)}clearSnapshotCache(){this.snapshotCache.clear()}async cacheSnapshot(e=this.snapshot){if(e.isCacheable){this.delegate.viewWillCacheSnapshot();const{lastRenderedLocation:t}=this;await nextEventLoopTick();const s=e.clone();return this.snapshotCache.put(t,s),s}}getCachedSnapshotForLocation(e){return this.snapshotCache.get(e)}isPageRefresh(e){return!e||this.lastRenderedLocation.pathname===e.location.pathname&&"replace"===e.action}shouldPreserveScrollPosition(e){return this.isPageRefresh(e)&&this.snapshot.shouldPreserveScrollPosition}get snapshot(){return PageSnapshot.fromElement(this.element)}}class Preloader{selector="a[data-turbo-preload]";constructor(e,t){this.delegate=e,this.snapshotCache=t}start(){"loading"===document.readyState?document.addEventListener("DOMContentLoaded",this.#T):this.preloadOnLoadLinksForView(document.body)}stop(){document.removeEventListener("DOMContentLoaded",this.#T)}preloadOnLoadLinksForView(e){for(const t of e.querySelectorAll(this.selector))this.delegate.shouldPreloadLink(t)&&this.preloadURL(t)}async preloadURL(e){const t=new URL(e.href);if(this.snapshotCache.has(t))return;const s=new FetchRequest(this,FetchMethod.get,t,new URLSearchParams,e);await s.perform()}prepareRequest(e){e.headers["X-Sec-Purpose"]="prefetch"}async requestSucceededWithResponse(e,t){try{const s=await t.responseHTML,r=PageSnapshot.fromHTMLString(s);this.snapshotCache.put(e.url,r)}catch(e){}}requestStarted(e){}requestErrored(e){}requestFinished(e){}requestPreventedHandlingResponse(e,t){}requestFailedWithResponse(e,t){}#T=()=>{this.preloadOnLoadLinksForView(document.body)}}class Cache{constructor(e){this.session=e}clear(){this.session.clearCache()}resetCacheControl(){this.#P("")}exemptPageFromCache(){this.#P("no-cache")}exemptPageFromPreview(){this.#P("no-preview")}#P(e){setMetaContent("turbo-cache-control",e)}}class Session{navigator=new Navigator(this);history=new History(this);view=new PageView(this,document.documentElement);adapter=new BrowserAdapter(this);pageObserver=new PageObserver(this);cacheObserver=new CacheObserver;linkPrefetchObserver=new LinkPrefetchObserver(this,document);linkClickObserver=new LinkClickObserver(this,window);formSubmitObserver=new FormSubmitObserver(this,document);scrollObserver=new ScrollObserver(this);streamObserver=new StreamObserver(this);formLinkClickObserver=new FormLinkClickObserver(this,document.documentElement);frameRedirector=new FrameRedirector(this,document.documentElement);streamMessageRenderer=new StreamMessageRenderer;cache=new Cache(this);enabled=!0;started=!1;#F=150;constructor(e){this.recentRequests=e,this.preloader=new Preloader(this,this.view.snapshotCache),this.debouncedRefresh=this.refresh,this.pageRefreshDebouncePeriod=this.pageRefreshDebouncePeriod}start(){this.started||(this.pageObserver.start(),this.cacheObserver.start(),this.linkPrefetchObserver.start(),this.formLinkClickObserver.start(),this.linkClickObserver.start(),this.formSubmitObserver.start(),this.scrollObserver.start(),this.streamObserver.start(),this.frameRedirector.start(),this.history.start(),this.preloader.start(),this.started=!0,this.enabled=!0)}disable(){this.enabled=!1}stop(){this.started&&(this.pageObserver.stop(),this.cacheObserver.stop(),this.linkPrefetchObserver.stop(),this.formLinkClickObserver.stop(),this.linkClickObserver.stop(),this.formSubmitObserver.stop(),this.scrollObserver.stop(),this.streamObserver.stop(),this.frameRedirector.stop(),this.history.stop(),this.preloader.stop(),this.started=!1)}registerAdapter(e){this.adapter=e}visit(e,t={}){const s=t.frame?document.getElementById(t.frame):null;if(s instanceof FrameElement){const r=t.action||getVisitAction(s);s.delegate.proposeVisitIfNavigatedWithAction(s,r),s.src=e.toString()}else this.navigator.proposeVisit(expandURL(e),t)}refresh(e,t){const s=t&&this.recentRequests.has(t),r=e===document.baseURI;s||this.navigator.currentVisit||!r||this.visit(e,{action:"replace",shouldCacheSnapshot:!1})}connectStreamSource(e){this.streamObserver.connectStreamSource(e)}disconnectStreamSource(e){this.streamObserver.disconnectStreamSource(e)}renderStreamMessage(e){this.streamMessageRenderer.render(StreamMessage.wrap(e))}clearCache(){this.view.clearSnapshotCache()}setProgressBarDelay(e){console.warn("Please replace `session.setProgressBarDelay(delay)` with `session.progressBarDelay = delay`. The function is deprecated and will be removed in a future version of Turbo.`"),this.progressBarDelay=e}set progressBarDelay(e){config.drive.progressBarDelay=e}get progressBarDelay(){return config.drive.progressBarDelay}set drive(e){config.drive.enabled=e}get drive(){return config.drive.enabled}set formMode(e){config.forms.mode=e}get formMode(){return config.forms.mode}get location(){return this.history.location}get restorationIdentifier(){return this.history.restorationIdentifier}get pageRefreshDebouncePeriod(){return this.#F}set pageRefreshDebouncePeriod(e){this.refresh=debounce(this.debouncedRefresh.bind(this),e),this.#F=e}shouldPreloadLink(e){const t=e.hasAttribute("data-turbo-method"),s=e.hasAttribute("data-turbo-stream"),r=e.getAttribute("data-turbo-frame"),i="_top"==r?null:document.getElementById(r)||findClosestRecursively(e,"turbo-frame:not([disabled])");if(t||s||i instanceof FrameElement)return!1;{const t=new URL(e.href);return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)}}historyPoppedToLocationWithRestorationIdentifierAndDirection(e,t,s){this.enabled?this.navigator.startVisit(e,t,{action:"restore",historyChanged:!0,direction:s}):this.adapter.pageInvalidated({reason:"turbo_disabled"})}scrollPositionChanged(e){this.history.updateRestorationData({scrollPosition:e})}willSubmitFormLinkToLocation(e,t){return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)}submittedFormLinkToLocation(){}canPrefetchRequestToLocation(e,t){return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)&&this.navigator.linkPrefetchingIsEnabledForLocation(t)}willFollowLinkToLocation(e,t,s){return this.elementIsNavigatable(e)&&locationIsVisitable(t,this.snapshot.rootLocation)&&this.applicationAllowsFollowingLinkToLocation(e,t,s)}followedLinkToLocation(e,t){const s=this.getActionForLink(e),r=e.hasAttribute("data-turbo-stream");this.visit(t.href,{action:s,acceptsStreamResponse:r})}allowsVisitingLocationWithAction(e,t){return this.locationWithActionIsSamePage(e,t)||this.applicationAllowsVisitingLocation(e)}visitProposedToLocation(e,t){extendURLWithDeprecatedProperties(e),this.adapter.visitProposedToLocation(e,t)}visitStarted(e){e.acceptsStreamResponse||(markAsBusy(document.documentElement),this.view.markVisitDirection(e.direction)),extendURLWithDeprecatedProperties(e.location),e.silent||this.notifyApplicationAfterVisitingLocation(e.location,e.action)}visitCompleted(e){this.view.unmarkVisitDirection(),clearBusyState(document.documentElement),this.notifyApplicationAfterPageLoad(e.getTimingMetrics())}locationWithActionIsSamePage(e,t){return this.navigator.locationWithActionIsSamePage(e,t)}visitScrolledToSamePageLocation(e,t){this.notifyApplicationAfterVisitingSamePageLocation(e,t)}willSubmitForm(e,t){const s=getAction$1(e,t);return this.submissionIsNavigatable(e,t)&&locationIsVisitable(expandURL(s),this.snapshot.rootLocation)}formSubmitted(e,t){this.navigator.submitForm(e,t)}pageBecameInteractive(){this.view.lastRenderedLocation=this.location,this.notifyApplicationAfterPageLoad()}pageLoaded(){this.history.assumeControlOfScrollRestoration()}pageWillUnload(){this.history.relinquishControlOfScrollRestoration()}receivedMessageFromStream(e){this.renderStreamMessage(e)}viewWillCacheSnapshot(){this.navigator.currentVisit?.silent||this.notifyApplicationBeforeCachingSnapshot()}allowsImmediateRender({element:e},t){const s=this.notifyApplicationBeforeRender(e,t),{defaultPrevented:r,detail:{render:i}}=s;return this.view.renderer&&i&&(this.view.renderer.renderElement=i),!r}viewRenderedSnapshot(e,t,s){this.view.lastRenderedLocation=this.history.location,this.notifyApplicationAfterRender(s)}preloadOnLoadLinksForView(e){this.preloader.preloadOnLoadLinksForView(e)}viewInvalidated(e){this.adapter.pageInvalidated(e)}frameLoaded(e){this.notifyApplicationAfterFrameLoad(e)}frameRendered(e,t){this.notifyApplicationAfterFrameRender(e,t)}applicationAllowsFollowingLinkToLocation(e,t,s){return!this.notifyApplicationAfterClickingLinkToLocation(e,t,s).defaultPrevented}applicationAllowsVisitingLocation(e){return!this.notifyApplicationBeforeVisitingLocation(e).defaultPrevented}notifyApplicationAfterClickingLinkToLocation(e,t,s){return dispatch("turbo:click",{target:e,detail:{url:t.href,originalEvent:s},cancelable:!0})}notifyApplicationBeforeVisitingLocation(e){return dispatch("turbo:before-visit",{detail:{url:e.href},cancelable:!0})}notifyApplicationAfterVisitingLocation(e,t){return dispatch("turbo:visit",{detail:{url:e.href,action:t}})}notifyApplicationBeforeCachingSnapshot(){return dispatch("turbo:before-cache")}notifyApplicationBeforeRender(e,t){return dispatch("turbo:before-render",{detail:{newBody:e,...t},cancelable:!0})}notifyApplicationAfterRender(e){return dispatch("turbo:render",{detail:{renderMethod:e}})}notifyApplicationAfterPageLoad(e={}){return dispatch("turbo:load",{detail:{url:this.location.href,timing:e}})}notifyApplicationAfterVisitingSamePageLocation(e,t){dispatchEvent(new HashChangeEvent("hashchange",{oldURL:e.toString(),newURL:t.toString()}))}notifyApplicationAfterFrameLoad(e){return dispatch("turbo:frame-load",{target:e})}notifyApplicationAfterFrameRender(e,t){return dispatch("turbo:frame-render",{detail:{fetchResponse:e},target:t,cancelable:!0})}submissionIsNavigatable(e,t){if("off"==config.forms.mode)return!1;{const s=!t||this.elementIsNavigatable(t);return"optin"==config.forms.mode?s&&null!=e.closest('[data-turbo="true"]'):s&&this.elementIsNavigatable(e)}}elementIsNavigatable(e){const t=findClosestRecursively(e,"[data-turbo]"),s=findClosestRecursively(e,"turbo-frame");return config.drive.enabled||s?!t||"false"!=t.getAttribute("data-turbo"):!!t&&"true"==t.getAttribute("data-turbo")}getActionForLink(e){return getVisitAction(e)||"advance"}get snapshot(){return this.view.snapshot}}function extendURLWithDeprecatedProperties(e){Object.defineProperties(e,deprecatedLocationPropertyDescriptors)}const deprecatedLocationPropertyDescriptors={absoluteURL:{get(){return this.toString()}}},session=new Session(recentRequests),{cache:cache,navigator:navigator$1}=session;function start(){session.start()}function registerAdapter(e){session.registerAdapter(e)}function visit(e,t){session.visit(e,t)}function connectStreamSource(e){session.connectStreamSource(e)}function disconnectStreamSource(e){session.disconnectStreamSource(e)}function renderStreamMessage(e){session.renderStreamMessage(e)}function clearCache(){console.warn("Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`"),session.clearCache()}function setProgressBarDelay(e){console.warn("Please replace `Turbo.setProgressBarDelay(delay)` with `Turbo.config.drive.progressBarDelay = delay`. The top-level function is deprecated and will be removed in a future version of Turbo.`"),config.drive.progressBarDelay=e}function setConfirmMethod(e){console.warn("Please replace `Turbo.setConfirmMethod(confirmMethod)` with `Turbo.config.forms.confirm = confirmMethod`. The top-level function is deprecated and will be removed in a future version of Turbo.`"),config.forms.confirm=e}function setFormMode(e){console.warn("Please replace `Turbo.setFormMode(mode)` with `Turbo.config.forms.mode = mode`. The top-level function is deprecated and will be removed in a future version of Turbo.`"),config.forms.mode=e}function morphBodyElements(e,t){MorphingPageRenderer.renderElement(e,t)}function morphTurboFrameElements(e,t){MorphingFrameRenderer.renderElement(e,t)}var Turbo=Object.freeze({__proto__:null,navigator:navigator$1,session:session,cache:cache,PageRenderer:PageRenderer,PageSnapshot:PageSnapshot,FrameRenderer:FrameRenderer,fetch:fetchWithTurboHeaders,config:config,start:start,registerAdapter:registerAdapter,visit:visit,connectStreamSource:connectStreamSource,disconnectStreamSource:disconnectStreamSource,renderStreamMessage:renderStreamMessage,clearCache:clearCache,setProgressBarDelay:setProgressBarDelay,setConfirmMethod:setConfirmMethod,setFormMode:setFormMode,morphBodyElements:morphBodyElements,morphTurboFrameElements:morphTurboFrameElements,morphChildren:morphChildren,morphElements:morphElements});class TurboFrameMissingError extends Error{}class FrameController{fetchResponseLoaded=e=>Promise.resolve();#M=null;#k=()=>{};#I=!1;#q=!1;#B=new Set;#H=!1;action=null;constructor(e){this.element=e,this.view=new FrameView(this,this.element),this.appearanceObserver=new AppearanceObserver(this,this.element),this.formLinkClickObserver=new FormLinkClickObserver(this,this.element),this.linkInterceptor=new LinkInterceptor(this,this.element),this.restorationIdentifier=uuid(),this.formSubmitObserver=new FormSubmitObserver(this,this.element)}connect(){this.#I||(this.#I=!0,this.loadingStyle==FrameLoadingStyle.lazy?this.appearanceObserver.start():this.#O(),this.formLinkClickObserver.start(),this.linkInterceptor.start(),this.formSubmitObserver.start())}disconnect(){this.#I&&(this.#I=!1,this.appearanceObserver.stop(),this.formLinkClickObserver.stop(),this.linkInterceptor.stop(),this.formSubmitObserver.stop())}disabledChanged(){this.loadingStyle==FrameLoadingStyle.eager&&this.#O()}sourceURLChanged(){this.#N("src")||(this.element.isConnected&&(this.complete=!1),(this.loadingStyle==FrameLoadingStyle.eager||this.#q)&&this.#O())}sourceURLReloaded(){const{refresh:e,src:t}=this.element;return this.#H=t&&"morph"===e,this.element.removeAttribute("complete"),this.element.src=null,this.element.src=t,this.element.loaded}loadingStyleChanged(){this.loadingStyle==FrameLoadingStyle.lazy?this.appearanceObserver.start():(this.appearanceObserver.stop(),this.#O())}async#O(){this.enabled&&this.isActive&&!this.complete&&this.sourceURL&&(this.element.loaded=this.#x(expandURL(this.sourceURL)),this.appearanceObserver.stop(),await this.element.loaded,this.#q=!0)}async loadResponse(e){(e.redirected||e.succeeded&&e.isHTML)&&(this.sourceURL=e.response.url);try{const t=await e.responseHTML;if(t){const s=parseHTMLDocument(t);PageSnapshot.fromDocument(s).isVisitable?await this.#D(e,s):await this.#V(e)}}finally{this.#H=!1,this.fetchResponseLoaded=()=>Promise.resolve()}}elementAppearedInViewport(e){this.proposeVisitIfNavigatedWithAction(e,getVisitAction(e)),this.#O()}willSubmitFormLinkToLocation(e){return this.#W(e)}submittedFormLinkToLocation(e,t,s){const r=this.#m(e);r&&s.setAttribute("data-turbo-frame",r.id)}shouldInterceptLinkClick(e,t,s){return this.#W(e)}linkClickIntercepted(e,t){this.#U(e,t)}willSubmitForm(e,t){return e.closest("turbo-frame")==this.element&&this.#W(e,t)}formSubmitted(e,t){this.formSubmission&&this.formSubmission.stop(),this.formSubmission=new FormSubmission(this,e,t);const{fetchRequest:s}=this.formSubmission;this.prepareRequest(s),this.formSubmission.start()}prepareRequest(e){e.headers["Turbo-Frame"]=this.id,this.currentNavigationElement?.hasAttribute("data-turbo-stream")&&e.acceptResponseType(StreamMessage.contentType)}requestStarted(e){markAsBusy(this.element)}requestPreventedHandlingResponse(e,t){this.#k()}async requestSucceededWithResponse(e,t){await this.loadResponse(t),this.#k()}async requestFailedWithResponse(e,t){await this.loadResponse(t),this.#k()}requestErrored(e,t){console.error(t),this.#k()}requestFinished(e){clearBusyState(this.element)}formSubmissionStarted({formElement:e}){markAsBusy(e,this.#m(e))}formSubmissionSucceededWithResponse(e,t){const s=this.#m(e.formElement,e.submitter);s.delegate.proposeVisitIfNavigatedWithAction(s,getVisitAction(e.submitter,e.formElement,s)),s.delegate.loadResponse(t),e.isSafe||session.clearCache()}formSubmissionFailedWithResponse(e,t){this.element.delegate.loadResponse(t),session.clearCache()}formSubmissionErrored(e,t){console.error(t)}formSubmissionFinished({formElement:e}){clearBusyState(e,this.#m(e))}allowsImmediateRender({element:e},t){const s=dispatch("turbo:before-frame-render",{target:this.element,detail:{newFrame:e,...t},cancelable:!0}),{defaultPrevented:r,detail:{render:i}}=s;return this.view.renderer&&i&&(this.view.renderer.renderElement=i),!r}viewRenderedSnapshot(e,t,s){}preloadOnLoadLinksForView(e){session.preloadOnLoadLinksForView(e)}viewInvalidated(){}willRenderFrame(e,t){this.previousFrameElement=e.cloneNode(!0)}visitCachedSnapshot=({element:e})=>{const t=e.querySelector("#"+this.element.id);t&&this.previousFrameElement&&t.replaceChildren(...this.previousFrameElement.children),delete this.previousFrameElement};async#D(e,t){const s=await this.extractForeignFrameElement(t.body),r=this.#H?MorphingFrameRenderer:FrameRenderer;if(s){const t=new Snapshot(s),i=new r(this,this.view.snapshot,t,!1,!1);this.view.renderPromise&&await this.view.renderPromise,this.changeHistory(),await this.view.render(i),this.complete=!0,session.frameRendered(e,this.element),session.frameLoaded(this.element),await this.fetchResponseLoaded(e)}else this.#$(e)&&this.#_(e)}async#x(e){const t=new FetchRequest(this,FetchMethod.get,e,new URLSearchParams,this.element);return this.#M?.cancel(),this.#M=t,new Promise((e=>{this.#k=()=>{this.#k=()=>{},this.#M=null,e()},t.perform()}))}#U(e,t,s){const r=this.#m(e,s);r.delegate.proposeVisitIfNavigatedWithAction(r,getVisitAction(s,e,r)),this.#j(e,(()=>{r.src=t}))}proposeVisitIfNavigatedWithAction(e,t=null){if(this.action=t,this.action){const t=PageSnapshot.fromElement(e).clone(),{visitCachedSnapshot:s}=e.delegate;e.delegate.fetchResponseLoaded=async r=>{if(e.src){const{statusCode:i,redirected:n}=r,o={response:{statusCode:i,redirected:n,responseHTML:await r.responseHTML},visitCachedSnapshot:s,willRender:!1,updateHistory:!1,restorationIdentifier:this.restorationIdentifier,snapshot:t};this.action&&(o.action=this.action),session.visit(e.src,o)}}}}changeHistory(){if(this.action){const e=getHistoryMethodForAction(this.action);session.history.update(e,expandURL(this.element.src||""),this.restorationIdentifier)}}async#V(e){console.warn(`The response (${e.statusCode}) from <turbo-frame id="${this.element.id}"> is performing a full page visit due to turbo-visit-control.`),await this.#z(e.response)}#$(e){this.element.setAttribute("complete","");const t=e.response;return!dispatch("turbo:frame-missing",{target:this.element,detail:{response:t,visit:async(e,t)=>{e instanceof Response?this.#z(e):session.visit(e,t)}},cancelable:!0}).defaultPrevented}#_(e){this.view.missing(),this.#G(e)}#G(e){const t=`The response (${e.statusCode}) did not contain the expected <turbo-frame id="${this.element.id}"> and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`;throw new TurboFrameMissingError(t)}async#z(e){const t=new FetchResponse(e),s=await t.responseHTML,{location:r,redirected:i,statusCode:n}=t;return session.visit(r,{response:{redirected:i,statusCode:n,responseHTML:s}})}#m(e,t){return getFrameElementById(getAttribute("data-turbo-frame",t,e)||this.element.getAttribute("target"))??this.element}async extractForeignFrameElement(e){let t;const s=CSS.escape(this.id);try{if(t=activateElement(e.querySelector(`turbo-frame#${s}`),this.sourceURL),t)return t;if(t=activateElement(e.querySelector(`turbo-frame[src][recurse~=${s}]`),this.sourceURL),t)return await t.loaded,await this.extractForeignFrameElement(t)}catch(e){return console.error(e),new FrameElement}return null}#K(e,t){return locationIsVisitable(expandURL(getAction$1(e,t)),this.rootLocation)}#W(e,t){const s=getAttribute("data-turbo-frame",t,e)||this.element.getAttribute("target");if(e instanceof HTMLFormElement&&!this.#K(e,t))return!1;if(!this.enabled||"_top"==s)return!1;if(s){const e=getFrameElementById(s);if(e)return!e.disabled}return!!session.elementIsNavigatable(e)&&!(t&&!session.elementIsNavigatable(t))}get id(){return this.element.id}get enabled(){return!this.element.disabled}get sourceURL(){if(this.element.src)return this.element.src}set sourceURL(e){this.#J("src",(()=>{this.element.src=e??null}))}get loadingStyle(){return this.element.loading}get isLoading(){return void 0!==this.formSubmission||void 0!==this.#k()}get complete(){return this.element.hasAttribute("complete")}set complete(e){e?this.element.setAttribute("complete",""):this.element.removeAttribute("complete")}get isActive(){return this.element.isActive&&this.#I}get rootLocation(){const e=this.element.ownerDocument.querySelector('meta[name="turbo-root"]');return expandURL(e?.content??"/")}#N(e){return this.#B.has(e)}#J(e,t){this.#B.add(e),t(),this.#B.delete(e)}#j(e,t){this.currentNavigationElement=e,t(),delete this.currentNavigationElement}}function getFrameElementById(e){if(null!=e){const t=document.getElementById(e);if(t instanceof FrameElement)return t}}function activateElement(e,t){if(e){const s=e.getAttribute("src");if(null!=s&&null!=t&&urlsAreEqual(s,t))throw new Error(`Matching <turbo-frame id="${e.id}"> element has a source URL which references itself`);if(e.ownerDocument!==document&&(e=document.importNode(e,!0)),e instanceof FrameElement)return e.connectedCallback(),e.disconnectedCallback(),e}}const StreamActions={after(){this.targetElements.forEach((e=>e.parentElement?.insertBefore(this.templateContent,e.nextSibling)))},append(){this.removeDuplicateTargetChildren(),this.targetElements.forEach((e=>e.append(this.templateContent)))},before(){this.targetElements.forEach((e=>e.parentElement?.insertBefore(this.templateContent,e)))},prepend(){this.removeDuplicateTargetChildren(),this.targetElements.forEach((e=>e.prepend(this.templateContent)))},remove(){this.targetElements.forEach((e=>e.remove()))},replace(){const e=this.getAttribute("method");this.targetElements.forEach((t=>{"morph"===e?morphElements(t,this.templateContent):t.replaceWith(this.templateContent)}))},update(){const e=this.getAttribute("method");this.targetElements.forEach((t=>{"morph"===e?morphChildren(t,this.templateContent):(t.innerHTML="",t.append(this.templateContent))}))},refresh(){session.refresh(this.baseURI,this.requestId)}};class StreamElement extends HTMLElement{static async renderElement(e){await e.performAction()}async connectedCallback(){try{await this.render()}catch(e){console.error(e)}finally{this.disconnect()}}async render(){return this.renderPromise??=(async()=>{const e=this.beforeRenderEvent;this.dispatchEvent(e)&&(await nextRepaint(),await e.detail.render(this))})()}disconnect(){try{this.remove()}catch{}}removeDuplicateTargetChildren(){this.duplicateChildren.forEach((e=>e.remove()))}get duplicateChildren(){const e=this.targetElements.flatMap((e=>[...e.children])).filter((e=>!!e.getAttribute("id"))),t=[...this.templateContent?.children||[]].filter((e=>!!e.getAttribute("id"))).map((e=>e.getAttribute("id")));return e.filter((e=>t.includes(e.getAttribute("id"))))}get performAction(){if(this.action){const e=StreamActions[this.action];if(e)return e;this.#X("unknown action")}this.#X("action attribute is missing")}get targetElements(){return this.target?this.targetElementsById:this.targets?this.targetElementsByQuery:void this.#X("target or targets attribute is missing")}get templateContent(){return this.templateElement.content.cloneNode(!0)}get templateElement(){if(null===this.firstElementChild){const e=this.ownerDocument.createElement("template");return this.appendChild(e),e}if(this.firstElementChild instanceof HTMLTemplateElement)return this.firstElementChild;this.#X("first child element must be a <template> element")}get action(){return this.getAttribute("action")}get target(){return this.getAttribute("target")}get targets(){return this.getAttribute("targets")}get requestId(){return this.getAttribute("request-id")}#X(e){throw new Error(`${this.description}: ${e}`)}get description(){return(this.outerHTML.match(/<[^>]+>/)??[])[0]??"<turbo-stream>"}get beforeRenderEvent(){return new CustomEvent("turbo:before-stream-render",{bubbles:!0,cancelable:!0,detail:{newStream:this,render:StreamElement.renderElement}})}get targetElementsById(){const e=this.ownerDocument?.getElementById(this.target);return null!==e?[e]:[]}get targetElementsByQuery(){const e=this.ownerDocument?.querySelectorAll(this.targets);return 0!==e.length?Array.prototype.slice.call(e):[]}}class StreamSourceElement extends HTMLElement{streamSource=null;connectedCallback(){this.streamSource=this.src.match(/^ws{1,2}:/)?new WebSocket(this.src):new EventSource(this.src),connectStreamSource(this.streamSource)}disconnectedCallback(){this.streamSource&&(this.streamSource.close(),disconnectStreamSource(this.streamSource))}get src(){return this.getAttribute("src")||""}}FrameElement.delegateConstructor=FrameController,void 0===customElements.get("turbo-frame")&&customElements.define("turbo-frame",FrameElement),void 0===customElements.get("turbo-stream")&&customElements.define("turbo-stream",StreamElement),void 0===customElements.get("turbo-stream-source")&&customElements.define("turbo-stream-source",StreamSourceElement),(()=>{let e=document.currentScript;if(e&&!e.hasAttribute("data-turbo-suppress-warning"))for(e=e.parentElement;e;){if(e==document.body)return console.warn(unindent`
26
+ You are loading Turbo from a <script> element inside the <body> element. This is probably not what you meant to do!
27
+
28
+ Load your application’s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.
29
+
30
+ For more information, see: https://turbo.hotwired.dev/handbook/building#working-with-script-elements
31
+
32
+ ——
33
+ Suppress this warning by adding a "data-turbo-suppress-warning" attribute to: %s
34
+ `,e.outerHTML);e=e.parentElement}})(),window.Turbo={...Turbo,StreamActions:StreamActions},start();var Turbo$1=Object.freeze({__proto__:null,FetchEnctype:FetchEnctype,FetchMethod:FetchMethod,FetchRequest:FetchRequest,FetchResponse:FetchResponse,FrameElement:FrameElement,FrameLoadingStyle:FrameLoadingStyle,FrameRenderer:FrameRenderer,PageRenderer:PageRenderer,PageSnapshot:PageSnapshot,StreamActions:StreamActions,StreamElement:StreamElement,StreamSourceElement:StreamSourceElement,cache:cache,clearCache:clearCache,config:config,connectStreamSource:connectStreamSource,disconnectStreamSource:disconnectStreamSource,fetch:fetchWithTurboHeaders,fetchEnctypeFromString:fetchEnctypeFromString,fetchMethodFromString:fetchMethodFromString,isSafe:isSafe,morphBodyElements:morphBodyElements,morphChildren:morphChildren,morphElements:morphElements,morphTurboFrameElements:morphTurboFrameElements,navigator:navigator$1,registerAdapter:registerAdapter,renderStreamMessage:renderStreamMessage,session:session,setConfirmMethod:setConfirmMethod,setFormMode:setFormMode,setProgressBarDelay:setProgressBarDelay,start:start,visit:visit});let consumer;async function getConsumer(){return consumer||setConsumer(createConsumer$1().then(setConsumer))}function setConsumer(e){return consumer=e}async function createConsumer$1(){const{createConsumer:e}=await Promise.resolve().then((function(){return index}));return e()}async function subscribeTo(e,t){const{subscriptions:s}=await getConsumer();return s.create(e,t)}var cable=Object.freeze({__proto__:null,getConsumer:getConsumer,setConsumer:setConsumer,createConsumer:createConsumer$1,subscribeTo:subscribeTo});function walk(e){return e&&"object"==typeof e?e instanceof Date||e instanceof RegExp?e:Array.isArray(e)?e.map(walk):Object.keys(e).reduce((function(t,s){return t[s[0].toLowerCase()+s.slice(1).replace(/([A-Z]+)/g,(function(e,t){return"_"+t.toLowerCase()}))]=walk(e[s]),t}),{}):e}class TurboCableStreamSourceElement extends HTMLElement{static observedAttributes=["channel","signed-stream-name"];async connectedCallback(){connectStreamSource(this),this.subscription=await subscribeTo(this.channel,{received:this.dispatchMessageEvent.bind(this),connected:this.subscriptionConnected.bind(this),disconnected:this.subscriptionDisconnected.bind(this)})}disconnectedCallback(){disconnectStreamSource(this),this.subscription&&this.subscription.unsubscribe(),this.subscriptionDisconnected()}attributeChangedCallback(){this.subscription&&(this.disconnectedCallback(),this.connectedCallback())}dispatchMessageEvent(e){const t=new MessageEvent("message",{data:e});return this.dispatchEvent(t)}subscriptionConnected(){this.setAttribute("connected","")}subscriptionDisconnected(){this.removeAttribute("connected")}get channel(){return{channel:this.getAttribute("channel"),signed_stream_name:this.getAttribute("signed-stream-name"),...walk({...this.dataset})}}}function encodeMethodIntoRequestBody(e){if(e.target instanceof HTMLFormElement){const{target:t,detail:{fetchOptions:s}}=e;t.addEventListener("turbo:submit-start",(({detail:{formSubmission:{submitter:e}}})=>{const r=isBodyInit(s.body)?s.body:new URLSearchParams,i=determineFetchMethod(e,r,t);/get/i.test(i)||(/post/i.test(i)?r.delete("_method"):r.set("_method",i),s.method="post")}),{once:!0})}}function determineFetchMethod(e,t,s){const r=determineFormMethod(e),i=t.get("_method"),n=s.getAttribute("method")||"get";return"string"==typeof r?r:"string"==typeof i?i:n}function determineFormMethod(e){return e instanceof HTMLButtonElement||e instanceof HTMLInputElement?"_method"===e.name?e.value:e.hasAttribute("formmethod")?e.formMethod:null:null}function isBodyInit(e){return e instanceof FormData||e instanceof URLSearchParams}void 0===customElements.get("turbo-cable-stream-source")&&customElements.define("turbo-cable-stream-source",TurboCableStreamSourceElement),window.Turbo=Turbo$1,addEventListener("turbo:before-fetch-request",encodeMethodIntoRequestBody);var adapters={logger:"undefined"!=typeof console?console:void 0,WebSocket:"undefined"!=typeof WebSocket?WebSocket:void 0},logger={log(...e){this.enabled&&(e.push(Date.now()),adapters.logger.log("[ActionCable]",...e))}};const now=()=>(new Date).getTime(),secondsSince=e=>(now()-e)/1e3;class ConnectionMonitor{constructor(e){this.visibilityDidChange=this.visibilityDidChange.bind(this),this.connection=e,this.reconnectAttempts=0}start(){this.isRunning()||(this.startedAt=now(),delete this.stoppedAt,this.startPolling(),addEventListener("visibilitychange",this.visibilityDidChange),logger.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`))}stop(){this.isRunning()&&(this.stoppedAt=now(),this.stopPolling(),removeEventListener("visibilitychange",this.visibilityDidChange),logger.log("ConnectionMonitor stopped"))}isRunning(){return this.startedAt&&!this.stoppedAt}recordMessage(){this.pingedAt=now()}recordConnect(){this.reconnectAttempts=0,delete this.disconnectedAt,logger.log("ConnectionMonitor recorded connect")}recordDisconnect(){this.disconnectedAt=now(),logger.log("ConnectionMonitor recorded disconnect")}startPolling(){this.stopPolling(),this.poll()}stopPolling(){clearTimeout(this.pollTimeout)}poll(){this.pollTimeout=setTimeout((()=>{this.reconnectIfStale(),this.poll()}),this.getPollInterval())}getPollInterval(){const{staleThreshold:e,reconnectionBackoffRate:t}=this.constructor;return 1e3*e*Math.pow(1+t,Math.min(this.reconnectAttempts,10))*(1+(0===this.reconnectAttempts?1:t)*Math.random())}reconnectIfStale(){this.connectionIsStale()&&(logger.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`),this.reconnectAttempts++,this.disconnectedRecently()?logger.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`):(logger.log("ConnectionMonitor reopening"),this.connection.reopen()))}get refreshedAt(){return this.pingedAt?this.pingedAt:this.startedAt}connectionIsStale(){return secondsSince(this.refreshedAt)>this.constructor.staleThreshold}disconnectedRecently(){return this.disconnectedAt&&secondsSince(this.disconnectedAt)<this.constructor.staleThreshold}visibilityDidChange(){"visible"===document.visibilityState&&setTimeout((()=>{!this.connectionIsStale()&&this.connection.isOpen()||(logger.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`),this.connection.reopen())}),200)}}ConnectionMonitor.staleThreshold=6,ConnectionMonitor.reconnectionBackoffRate=.15;var ConnectionMonitor$1=ConnectionMonitor,INTERNAL={message_types:{welcome:"welcome",disconnect:"disconnect",ping:"ping",confirmation:"confirm_subscription",rejection:"reject_subscription"},disconnect_reasons:{unauthorized:"unauthorized",invalid_request:"invalid_request",server_restart:"server_restart",remote:"remote"},default_mount_path:"/cable",protocols:["actioncable-v1-json","actioncable-unsupported"]};const{message_types:message_types,protocols:protocols}=INTERNAL,supportedProtocols=protocols.slice(0,protocols.length-1),indexOf=[].indexOf;class Connection{constructor(e){this.open=this.open.bind(this),this.consumer=e,this.subscriptions=this.consumer.subscriptions,this.monitor=new ConnectionMonitor$1(this),this.disconnected=!0}send(e){return!!this.isOpen()&&(this.webSocket.send(JSON.stringify(e)),!0)}open(){if(this.isActive())return logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`),!1;{const e=[...protocols,...this.consumer.subprotocols||[]];return logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${e}`),this.webSocket&&this.uninstallEventHandlers(),this.webSocket=new adapters.WebSocket(this.consumer.url,e),this.installEventHandlers(),this.monitor.start(),!0}}close({allowReconnect:e}={allowReconnect:!0}){if(e||this.monitor.stop(),this.isOpen())return this.webSocket.close()}reopen(){if(logger.log(`Reopening WebSocket, current state is ${this.getState()}`),!this.isActive())return this.open();try{return this.close()}catch(e){logger.log("Failed to reopen WebSocket",e)}finally{logger.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`),setTimeout(this.open,this.constructor.reopenDelay)}}getProtocol(){if(this.webSocket)return this.webSocket.protocol}isOpen(){return this.isState("open")}isActive(){return this.isState("open","connecting")}triedToReconnect(){return this.monitor.reconnectAttempts>0}isProtocolSupported(){return indexOf.call(supportedProtocols,this.getProtocol())>=0}isState(...e){return indexOf.call(e,this.getState())>=0}getState(){if(this.webSocket)for(let e in adapters.WebSocket)if(adapters.WebSocket[e]===this.webSocket.readyState)return e.toLowerCase();return null}installEventHandlers(){for(let e in this.events){const t=this.events[e].bind(this);this.webSocket[`on${e}`]=t}}uninstallEventHandlers(){for(let e in this.events)this.webSocket[`on${e}`]=function(){}}}Connection.reopenDelay=500,Connection.prototype.events={message(e){if(!this.isProtocolSupported())return;const{identifier:t,message:s,reason:r,reconnect:i,type:n}=JSON.parse(e.data);switch(this.monitor.recordMessage(),n){case message_types.welcome:return this.triedToReconnect()&&(this.reconnectAttempted=!0),this.monitor.recordConnect(),this.subscriptions.reload();case message_types.disconnect:return logger.log(`Disconnecting. Reason: ${r}`),this.close({allowReconnect:i});case message_types.ping:return null;case message_types.confirmation:return this.subscriptions.confirmSubscription(t),this.reconnectAttempted?(this.reconnectAttempted=!1,this.subscriptions.notify(t,"connected",{reconnected:!0})):this.subscriptions.notify(t,"connected",{reconnected:!1});case message_types.rejection:return this.subscriptions.reject(t);default:return this.subscriptions.notify(t,"received",s)}},open(){if(logger.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`),this.disconnected=!1,!this.isProtocolSupported())return logger.log("Protocol is unsupported. Stopping monitor and disconnecting."),this.close({allowReconnect:!1})},close(e){if(logger.log("WebSocket onclose event"),!this.disconnected)return this.disconnected=!0,this.monitor.recordDisconnect(),this.subscriptions.notifyAll("disconnected",{willAttemptReconnect:this.monitor.isRunning()})},error(){logger.log("WebSocket onerror event")}};var Connection$1=Connection;const extend=function(e,t){if(null!=t)for(let s in t){const r=t[s];e[s]=r}return e};class Subscription{constructor(e,t={},s){this.consumer=e,this.identifier=JSON.stringify(t),extend(this,s)}perform(e,t={}){return t.action=e,this.send(t)}send(e){return this.consumer.send({command:"message",identifier:this.identifier,data:JSON.stringify(e)})}unsubscribe(){return this.consumer.subscriptions.remove(this)}}class SubscriptionGuarantor{constructor(e){this.subscriptions=e,this.pendingSubscriptions=[]}guarantee(e){-1==this.pendingSubscriptions.indexOf(e)?(logger.log(`SubscriptionGuarantor guaranteeing ${e.identifier}`),this.pendingSubscriptions.push(e)):logger.log(`SubscriptionGuarantor already guaranteeing ${e.identifier}`),this.startGuaranteeing()}forget(e){logger.log(`SubscriptionGuarantor forgetting ${e.identifier}`),this.pendingSubscriptions=this.pendingSubscriptions.filter((t=>t!==e))}startGuaranteeing(){this.stopGuaranteeing(),this.retrySubscribing()}stopGuaranteeing(){clearTimeout(this.retryTimeout)}retrySubscribing(){this.retryTimeout=setTimeout((()=>{this.subscriptions&&"function"==typeof this.subscriptions.subscribe&&this.pendingSubscriptions.map((e=>{logger.log(`SubscriptionGuarantor resubscribing ${e.identifier}`),this.subscriptions.subscribe(e)}))}),500)}}var SubscriptionGuarantor$1=SubscriptionGuarantor;class Subscriptions{constructor(e){this.consumer=e,this.guarantor=new SubscriptionGuarantor$1(this),this.subscriptions=[]}create(e,t){const s="object"==typeof e?e:{channel:e},r=new Subscription(this.consumer,s,t);return this.add(r)}add(e){return this.subscriptions.push(e),this.consumer.ensureActiveConnection(),this.notify(e,"initialized"),this.subscribe(e),e}remove(e){return this.forget(e),this.findAll(e.identifier).length||this.sendCommand(e,"unsubscribe"),e}reject(e){return this.findAll(e).map((e=>(this.forget(e),this.notify(e,"rejected"),e)))}forget(e){return this.guarantor.forget(e),this.subscriptions=this.subscriptions.filter((t=>t!==e)),e}findAll(e){return this.subscriptions.filter((t=>t.identifier===e))}reload(){return this.subscriptions.map((e=>this.subscribe(e)))}notifyAll(e,...t){return this.subscriptions.map((s=>this.notify(s,e,...t)))}notify(e,t,...s){let r;return r="string"==typeof e?this.findAll(e):[e],r.map((e=>"function"==typeof e[t]?e[t](...s):void 0))}subscribe(e){this.sendCommand(e,"subscribe")&&this.guarantor.guarantee(e)}confirmSubscription(e){logger.log(`Subscription confirmed ${e}`),this.findAll(e).map((e=>this.guarantor.forget(e)))}sendCommand(e,t){const{identifier:s}=e;return this.consumer.send({command:t,identifier:s})}}class Consumer{constructor(e){this._url=e,this.subscriptions=new Subscriptions(this),this.connection=new Connection$1(this),this.subprotocols=[]}get url(){return createWebSocketURL(this._url)}send(e){return this.connection.send(e)}connect(){return this.connection.open()}disconnect(){return this.connection.close({allowReconnect:!1})}ensureActiveConnection(){if(!this.connection.isActive())return this.connection.open()}addSubProtocol(e){this.subprotocols=[...this.subprotocols,e]}}function createWebSocketURL(e){if("function"==typeof e&&(e=e()),e&&!/^wss?:/i.test(e)){const t=document.createElement("a");return t.href=e,t.href=t.href,t.protocol=t.protocol.replace("http","ws"),t.href}return e}function createConsumer(e=getConfig("url")||INTERNAL.default_mount_path){return new Consumer(e)}function getConfig(e){const t=document.head.querySelector(`meta[name='action-cable-${e}']`);if(t)return t.getAttribute("content")}var index=Object.freeze({__proto__:null,Connection:Connection$1,ConnectionMonitor:ConnectionMonitor$1,Consumer:Consumer,INTERNAL:INTERNAL,Subscription:Subscription,Subscriptions:Subscriptions,SubscriptionGuarantor:SubscriptionGuarantor$1,adapters:adapters,createWebSocketURL:createWebSocketURL,logger:logger,createConsumer:createConsumer,getConfig:getConfig});export{Turbo$1 as Turbo,cable};
@@ -184,3 +184,5 @@ module GoodJob
184
184
  attr_accessor :record
185
185
  end
186
186
  end
187
+
188
+ ActiveSupport.run_load_hooks(:good_job_batch, GoodJob::Batch)
@@ -123,3 +123,5 @@ module GoodJob
123
123
  end
124
124
  end
125
125
  end
126
+
127
+ ActiveSupport.run_load_hooks(:good_job_batch_record, GoodJob::BatchRecord)
@@ -250,8 +250,8 @@ module GoodJob
250
250
  )
251
251
  end
252
252
 
253
- def job_class_index_migrated?
254
- return true if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_job_class)
253
+ def historic_finished_at_index_migrated?
254
+ return true unless connection.index_name_exists?(:good_jobs, :index_good_jobs_jobs_on_finished_at)
255
255
 
256
256
  migration_pending_warning!
257
257
  false
@@ -167,3 +167,5 @@ module GoodJob # :nodoc:
167
167
  end
168
168
  end
169
169
  end
170
+
171
+ ActiveSupport.run_load_hooks(:good_job_process, GoodJob::Process)
@@ -127,3 +127,5 @@ module GoodJob
127
127
  end
128
128
  end
129
129
  end
130
+
131
+ ActiveSupport.run_load_hooks(:good_job_setting, GoodJob::Setting)