PageSourceSearch

https://shop.kajiwarakonbu.com/customer/assets/application-ac017ce5.js

js kajiwarakonbu.com collected 2026-10-06 13:09:47 UTC 330,494 bytes, 9,950 lines download raw bytes

vendor: 1,934 bytes, lines 1-39
1var __create = Object.create;
2var __defProp = Object.defineProperty;
3var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4var __getOwnPropNames = Object.getOwnPropertyNames;
5var __getProtoOf = Object.getPrototypeOf;
6var __hasOwnProp = Object.prototype.hasOwnProperty;
7var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9}) : x)(function(x) {
10  if (typeof require !== "undefined") return require.apply(this, arguments);
11  throw Error('Dynamic require of "' + x + '" is not supported');
12});
13var __esm = (fn, res) => function __init() {
14  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15};
16var __commonJS = (cb, mod) => function __require2() {
17  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18};
19var __export = (target, all) => {
20  for (var name in all)
21    __defProp(target, name, { get: all[name], enumerable: true });
22};
23var __copyProps = (to, from, except, desc) => {
24  if (from && typeof from === "object" || typeof from === "function") {
25    for (let key of __getOwnPropNames(from))
26      if (!__hasOwnProp.call(to, key) && key !== except)
27        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
28  }
29  return to;
30};
31var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
32  // If the importer is in node compatibility mode or this is not an ESM
33  // file that has been converted to a CommonJS file using a Babel-
34  // compatible transform (i.e. "__esModule" has not been set), then set
35  // "default" to the CommonJS "module.exports" for node compatibility.
36  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
37  mod
38));
39
vendor: 334 bytes, lines 40-50
40// node_modules/@rails/actioncable/src/adapters.js
41var adapters_default;
42var init_adapters = __esm({
43  "node_modules/@rails/actioncable/src/adapters.js"() {
44    adapters_default = {
45      logger: typeof console !== "undefined" ? console : void 0,
46      WebSocket: typeof WebSocket !== "undefined" ? WebSocket : void 0
47    };
48  }
49});
50
vendor: 386 bytes, lines 51-66
51// node_modules/@rails/actioncable/src/logger.js
52var logger_default;
53var init_logger = __esm({
54  "node_modules/@rails/actioncable/src/logger.js"() {
55    init_adapters();
56    logger_default = {
57      log(...messages) {
58        if (this.enabled) {
59          messages.push(Date.now());
60          adapters_default.logger.log("[ActionCable]", ...messages);
61        }
62      }
63    };
64  }
65});
66
vendor: 4,101 bytes, lines 67-176
67// node_modules/@rails/actioncable/src/connection_monitor.js
68var now, secondsSince, ConnectionMonitor, connection_monitor_default;
69var init_connection_monitor = __esm({
70  "node_modules/@rails/actioncable/src/connection_monitor.js"() {
71    init_logger();
72    now = () => (/* @__PURE__ */ new Date()).getTime();
73    secondsSince = (time) => (now() - time) / 1e3;
74    ConnectionMonitor = class {
75      constructor(connection) {
76        this.visibilityDidChange = this.visibilityDidChange.bind(this);
77        this.connection = connection;
78        this.reconnectAttempts = 0;
79      }
80      start() {
81        if (!this.isRunning()) {
82          this.startedAt = now();
83          delete this.stoppedAt;
84          this.startPolling();
85          addEventListener("visibilitychange", this.visibilityDidChange);
86          logger_default.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`);
87        }
88      }
89      stop() {
90        if (this.isRunning()) {
91          this.stoppedAt = now();
92          this.stopPolling();
93          removeEventListener("visibilitychange", this.visibilityDidChange);
94          logger_default.log("ConnectionMonitor stopped");
95        }
96      }
97      isRunning() {
98        return this.startedAt && !this.stoppedAt;
99      }
100      recordMessage() {
101        this.pingedAt = now();
102      }
103      recordConnect() {
104        this.reconnectAttempts = 0;
105        delete this.disconnectedAt;
106        logger_default.log("ConnectionMonitor recorded connect");
107      }
108      recordDisconnect() {
109        this.disconnectedAt = now();
110        logger_default.log("ConnectionMonitor recorded disconnect");
111      }
112      // Private
113      startPolling() {
114        this.stopPolling();
115        this.poll();
116      }
117      stopPolling() {
118        clearTimeout(this.pollTimeout);
119      }
120      poll() {
121        this.pollTimeout = setTimeout(
122          () => {
123            this.reconnectIfStale();
124            this.poll();
125          },
126          this.getPollInterval()
127        );
128      }
129      getPollInterval() {
130        const { staleThreshold, reconnectionBackoffRate } = this.constructor;
131        const backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10));
132        const jitterMax = this.reconnectAttempts === 0 ? 1 : reconnectionBackoffRate;
133        const jitter = jitterMax * Math.random();
134        return staleThreshold * 1e3 * backoff * (1 + jitter);
135      }
136      reconnectIfStale() {
137        if (this.connectionIsStale()) {
138          logger_default.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`);
139          this.reconnectAttempts++;
140          if (this.disconnectedRecently()) {
141            logger_default.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`);
142          } else {
143            logger_default.log("ConnectionMonitor reopening");
144            this.connection.reopen();
145          }
146        }
147      }
148      get refreshedAt() {
149        return this.pingedAt ? this.pingedAt : this.startedAt;
150      }
151      connectionIsStale() {
152        return secondsSince(this.refreshedAt) > this.constructor.staleThreshold;
153      }
154      disconnectedRecently() {
155        return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
156      }
157      visibilityDidChange() {
158        if (document.visibilityState === "visible") {
159          setTimeout(
160            () => {
161              if (this.connectionIsStale() || !this.connection.isOpen()) {
162                logger_default.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`);
163                this.connection.reopen();
164              }
165            },
166            200
167          );
168        }
169      }
170    };
171    ConnectionMonitor.staleThreshold = 6;
172    ConnectionMonitor.reconnectionBackoffRate = 0.15;
173    connection_monitor_default = ConnectionMonitor;
174  }
175});
176
vendor: 741 bytes, lines 177-203
177// node_modules/@rails/actioncable/src/internal.js
178var internal_default;
179var init_internal = __esm({
180  "node_modules/@rails/actioncable/src/internal.js"() {
181    internal_default = {
182      "message_types": {
183        "welcome": "welcome",
184        "disconnect": "disconnect",
185        "ping": "ping",
186        "confirmation": "confirm_subscription",
187        "rejection": "reject_subscription"
188      },
189      "disconnect_reasons": {
190        "unauthorized": "unauthorized",
191        "invalid_request": "invalid_request",
192        "server_restart": "server_restart",
193        "remote": "remote"
194      },
195      "default_mount_path": "/cable",
196      "protocols": [
197        "actioncable-v1-json",
198        "actioncable-unsupported"
199      ]
200    };
201  }
202});
203
vendor: 5,887 bytes, lines 204-372
204// node_modules/@rails/actioncable/src/connection.js
205var message_types, protocols, supportedProtocols, indexOf, Connection, connection_default;
206var init_connection = __esm({
207  "node_modules/@rails/actioncable/src/connection.js"() {
208    init_adapters();
209    init_connection_monitor();
210    init_internal();
211    init_logger();
212    ({ message_types, protocols } = internal_default);
213    supportedProtocols = protocols.slice(0, protocols.length - 1);
214    indexOf = [].indexOf;
215    Connection = class {
216      constructor(consumer2) {
217        this.open = this.open.bind(this);
218        this.consumer = consumer2;
219        this.subscriptions = this.consumer.subscriptions;
220        this.monitor = new connection_monitor_default(this);
221        this.disconnected = true;
222      }
223      send(data) {
224        if (this.isOpen()) {
225          this.webSocket.send(JSON.stringify(data));
226          return true;
227        } else {
228          return false;
229        }
230      }
231      open() {
232        if (this.isActive()) {
233          logger_default.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`);
234          return false;
235        } else {
236          const socketProtocols = [...protocols, ...this.consumer.subprotocols || []];
237          logger_default.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${socketProtocols}`);
238          if (this.webSocket) {
239            this.uninstallEventHandlers();
240          }
241          this.webSocket = new adapters_default.WebSocket(this.consumer.url, socketProtocols);
242          this.installEventHandlers();
243          this.monitor.start();
244          return true;
245        }
246      }
247      close({ allowReconnect } = { allowReconnect: true }) {
248        if (!allowReconnect) {
249          this.monitor.stop();
250        }
251        if (this.isOpen()) {
252          return this.webSocket.close();
253        }
254      }
255      reopen() {
256        logger_default.log(`Reopening WebSocket, current state is ${this.getState()}`);
257        if (this.isActive()) {
258          try {
259            return this.close();
260          } catch (error2) {
261            logger_default.log("Failed to reopen WebSocket", error2);
262          } finally {
263            logger_default.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`);
264            setTimeout(this.open, this.constructor.reopenDelay);
265          }
266        } else {
267          return this.open();
268        }
269      }
270      getProtocol() {
271        if (this.webSocket) {
272          return this.webSocket.protocol;
273        }
274      }
275      isOpen() {
276        return this.isState("open");
277      }
278      isActive() {
279        return this.isState("open", "connecting");
280      }
281      triedToReconnect() {
282        return this.monitor.reconnectAttempts > 0;
283      }
284      // Private
285      isProtocolSupported() {
286        return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
287      }
288      isState(...states) {
289        return indexOf.call(states, this.getState()) >= 0;
290      }
291      getState() {
292        if (this.webSocket) {
293          for (let state in adapters_default.WebSocket) {
294            if (adapters_default.WebSocket[state] === this.webSocket.readyState) {
295              return state.toLowerCase();
296            }
297          }
298        }
299        return null;
300      }
301      installEventHandlers() {
302        for (let eventName in this.events) {
303          const handler = this.events[eventName].bind(this);
304          this.webSocket[`on${eventName}`] = handler;
305        }
306      }
307      uninstallEventHandlers() {
308        for (let eventName in this.events) {
309          this.webSocket[`on${eventName}`] = function() {
310          };
311        }
312      }
313    };
314    Connection.reopenDelay = 500;
315    Connection.prototype.events = {
316      message(event) {
317        if (!this.isProtocolSupported()) {
318          return;
319        }
320        const { identifier, message, reason, reconnect, type } = JSON.parse(event.data);
321        this.monitor.recordMessage();
322        switch (type) {
323          case message_types.welcome:
324            if (this.triedToReconnect()) {
325              this.reconnectAttempted = true;
326            }
327            this.monitor.recordConnect();
328            return this.subscriptions.reload();
329          case message_types.disconnect:
330            logger_default.log(`Disconnecting. Reason: ${reason}`);
331            return this.close({ allowReconnect: reconnect });
332          case message_types.ping:
333            return null;
334          case message_types.confirmation:
335            this.subscriptions.confirmSubscription(identifier);
336            if (this.reconnectAttempted) {
337              this.reconnectAttempted = false;
338              return this.subscriptions.notify(identifier, "connected", { reconnected: true });
339            } else {
340              return this.subscriptions.notify(identifier, "connected", { reconnected: false });
341            }
342          case message_types.rejection:
343            return this.subscriptions.reject(identifier);
344          default:
345            return this.subscriptions.notify(identifier, "received", message);
346        }
347      },
348      open() {
349        logger_default.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`);
350        this.disconnected = false;
351        if (!this.isProtocolSupported()) {
352          logger_default.log("Protocol is unsupported. Stopping monitor and disconnecting.");
353          return this.close({ allowReconnect: false });
354        }
355      },
356      close(event) {
357        logger_default.log("WebSocket onclose event");
358        if (this.disconnected) {
359          return;
360        }
361        this.disconnected = true;
362        this.monitor.recordDisconnect();
363        return this.subscriptions.notifyAll("disconnected", { willAttemptReconnect: this.monitor.isRunning() });
364      },
365      error() {
366        logger_default.log("WebSocket onerror event");
367      }
368    };
369    connection_default = Connection;
370  }
371});
372
vendor: 1,036 bytes, lines 373-406
373// node_modules/@rails/actioncable/src/subscription.js
374var extend, Subscription;
375var init_subscription = __esm({
376  "node_modules/@rails/actioncable/src/subscription.js"() {
377    extend = function(object, properties) {
378      if (properties != null) {
379        for (let key in properties) {
380          const value = properties[key];
381          object[key] = value;
382        }
383      }
384      return object;
385    };
386    Subscription = class {
387      constructor(consumer2, params = {}, mixin) {
388        this.consumer = consumer2;
389        this.identifier = JSON.stringify(params);
390        extend(this, mixin);
391      }
392      // Perform a channel action with the optional data passed as an attribute
393      perform(action, data = {}) {
394        data.action = action;
395        return this.send(data);
396      }
397      send(data) {
398        return this.consumer.send({ command: "message", identifier: this.identifier, data: JSON.stringify(data) });
399      }
400      unsubscribe() {
401        return this.consumer.subscriptions.remove(this);
402      }
403    };
404  }
405});
406
vendor: 1,802 bytes, lines 407-454
407// node_modules/@rails/actioncable/src/subscription_guarantor.js
408var SubscriptionGuarantor, subscription_guarantor_default;
409var init_subscription_guarantor = __esm({
410  "node_modules/@rails/actioncable/src/subscription_guarantor.js"() {
411    init_logger();
412    SubscriptionGuarantor = class {
413      constructor(subscriptions) {
414        this.subscriptions = subscriptions;
415        this.pendingSubscriptions = [];
416      }
417      guarantee(subscription) {
418        if (this.pendingSubscriptions.indexOf(subscription) == -1) {
419          logger_default.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
420          this.pendingSubscriptions.push(subscription);
421        } else {
422          logger_default.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
423        }
424        this.startGuaranteeing();
425      }
426      forget(subscription) {
427        logger_default.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
428        this.pendingSubscriptions = this.pendingSubscriptions.filter((s) => s !== subscription);
429      }
430      startGuaranteeing() {
431        this.stopGuaranteeing();
432        this.retrySubscribing();
433      }
434      stopGuaranteeing() {
435        clearTimeout(this.retryTimeout);
436      }
437      retrySubscribing() {
438        this.retryTimeout = setTimeout(
439          () => {
440            if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
441              this.pendingSubscriptions.map((subscription) => {
442                logger_default.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
443                this.subscriptions.subscribe(subscription);
444              });
445            }
446          },
447          500
448        );
449      }
450    };
451    subscription_guarantor_default = SubscriptionGuarantor;
452  }
453});
454
vendor: 2,968 bytes, lines 455-535
455// node_modules/@rails/actioncable/src/subscriptions.js
456var Subscriptions;
457var init_subscriptions = __esm({
458  "node_modules/@rails/actioncable/src/subscriptions.js"() {
459    init_subscription();
460    init_subscription_guarantor();
461    init_logger();
462    Subscriptions = class {
463      constructor(consumer2) {
464        this.consumer = consumer2;
465        this.guarantor = new subscription_guarantor_default(this);
466        this.subscriptions = [];
467      }
468      create(channelName, mixin) {
469        const channel = channelName;
470        const params = typeof channel === "object" ? channel : { channel };
471        const subscription = new Subscription(this.consumer, params, mixin);
472        return this.add(subscription);
473      }
474      // Private
475      add(subscription) {
476        this.subscriptions.push(subscription);
477        this.consumer.ensureActiveConnection();
478        this.notify(subscription, "initialized");
479        this.subscribe(subscription);
480        return subscription;
481      }
482      remove(subscription) {
483        this.forget(subscription);
484        if (!this.findAll(subscription.identifier).length) {
485          this.sendCommand(subscription, "unsubscribe");
486        }
487        return subscription;
488      }
489      reject(identifier) {
490        return this.findAll(identifier).map((subscription) => {
491          this.forget(subscription);
492          this.notify(subscription, "rejected");
493          return subscription;
494        });
495      }
496      forget(subscription) {
497        this.guarantor.forget(subscription);
498        this.subscriptions = this.subscriptions.filter((s) => s !== subscription);
499        return subscription;
500      }
501      findAll(identifier) {
502        return this.subscriptions.filter((s) => s.identifier === identifier);
503      }
504      reload() {
505        return this.subscriptions.map((subscription) => this.subscribe(subscription));
506      }
507      notifyAll(callbackName, ...args) {
508        return this.subscriptions.map((subscription) => this.notify(subscription, callbackName, ...args));
509      }
510      notify(subscription, callbackName, ...args) {
511        let subscriptions;
512        if (typeof subscription === "string") {
513          subscriptions = this.findAll(subscription);
514        } else {
515          subscriptions = [subscription];
516        }
517        return subscriptions.map((subscription2) => typeof subscription2[callbackName] === "function" ? subscription2[callbackName](...args) : void 0);
518      }
519      subscribe(subscription) {
520        if (this.sendCommand(subscription, "subscribe")) {
521          this.guarantor.guarantee(subscription);
522        }
523      }
524      confirmSubscription(identifier) {
525        logger_default.log(`Subscription confirmed ${identifier}`);
526        this.findAll(identifier).map((subscription) => this.guarantor.forget(subscription));
527      }
528      sendCommand(subscription, command) {
529        const { identifier } = subscription;
530        return this.consumer.send({ command, identifier });
531      }
532    };
533  }
534});
535
vendor: 1,295 bytes, lines 536-586
536// node_modules/@rails/actioncable/src/consumer.js
537function createWebSocketURL(url) {
538  if (typeof url === "function") {
539    url = url();
540  }
541  if (url && !/^wss?:/i.test(url)) {
542    const a = document.createElement("a");
543    a.href = url;
544    a.href = a.href;
545    a.protocol = a.protocol.replace("http", "ws");
546    return a.href;
547  } else {
548    return url;
549  }
550}
551var Consumer;
552var init_consumer = __esm({
553  "node_modules/@rails/actioncable/src/consumer.js"() {
554    init_connection();
555    init_subscriptions();
556    Consumer = class {
557      constructor(url) {
558        this._url = url;
559        this.subscriptions = new Subscriptions(this);
560        this.connection = new connection_default(this);
561        this.subprotocols = [];
562      }
563      get url() {
564        return createWebSocketURL(this._url);
565      }
566      send(data) {
567        return this.connection.send(data);
568      }
569      connect() {
570        return this.connection.open();
571      }
572      disconnect() {
573        return this.connection.close({ allowReconnect: false });
574      }
575      ensureActiveConnection() {
576        if (!this.connection.isActive()) {
577          return this.connection.open();
578        }
579      }
580      addSubProtocol(subprotocol) {
581        this.subprotocols = [...this.subprotocols, subprotocol];
582      }
583    };
584  }
585});
586
vendor: 1,183 bytes, lines 587-625
587// node_modules/@rails/actioncable/src/index.js
588var src_exports = {};
589__export(src_exports, {
590  Connection: () => connection_default,
591  ConnectionMonitor: () => connection_monitor_default,
592  Consumer: () => Consumer,
593  INTERNAL: () => internal_default,
594  Subscription: () => Subscription,
595  SubscriptionGuarantor: () => subscription_guarantor_default,
596  Subscriptions: () => Subscriptions,
597  adapters: () => adapters_default,
598  createConsumer: () => createConsumer,
599  createWebSocketURL: () => createWebSocketURL,
600  getConfig: () => getConfig,
601  logger: () => logger_default
602});
603function createConsumer(url = getConfig("url") || internal_default.default_mount_path) {
604  return new Consumer(url);
605}
606function getConfig(name) {
607  const element = document.head.querySelector(`meta[name='action-cable-${name}']`);
608  if (element) {
609    return element.getAttribute("content");
610  }
611}
612var init_src = __esm({
613  "node_modules/@rails/actioncable/src/index.js"() {
614    init_connection();
615    init_connection_monitor();
616    init_consumer();
617    init_internal();
618    init_subscription();
619    init_subscriptions();
620    init_subscription_guarantor();
621    init_adapters();
622    init_logger();
623  }
624});
625
vendor: 3,699 bytes, lines 626-722
626// node_modules/fetch-jsonp/build/fetch-jsonp.js
627var require_fetch_jsonp = __commonJS({
628  "node_modules/fetch-jsonp/build/fetch-jsonp.js"(exports, module) {
629    (function(global, factory) {
630      if (typeof define === "function" && define.amd) {
631        define(["exports", "module"], factory);
632      } else if (typeof exports !== "undefined" && typeof module !== "undefined") {
633        factory(exports, module);
634      } else {
635        var mod = {
636          exports: {}
637        };
638        factory(mod.exports, mod);
639        global.fetchJsonp = mod.exports;
640      }
641    })(exports, function(exports2, module2) {
642      "use strict";
643      var defaultOptions2 = {
644        timeout: 5e3,
645        jsonpCallback: "callback",
646        jsonpCallbackFunction: null
647      };
648      function generateCallbackFunction() {
649        return "jsonp_" + Date.now() + "_" + Math.ceil(Math.random() * 1e5);
650      }
651      function clearFunction(functionName) {
652        try {
653          delete window[functionName];
654        } catch (e) {
655          window[functionName] = void 0;
656        }
657      }
658      function removeScript(scriptId) {
659        var script = document.getElementById(scriptId);
660        if (script) {
661          document.getElementsByTagName("head")[0].removeChild(script);
662        }
663      }
664      function fetchJsonp2(_url) {
665        var options = arguments.length <= 1 || arguments[1] === void 0 ? {} : arguments[1];
666        var url = _url;
667        var timeout = options.timeout || defaultOptions2.timeout;
668        var jsonpCallback = options.jsonpCallback || defaultOptions2.jsonpCallback;
669        var timeoutId = void 0;
670        return new Promise(function(resolve, reject) {
671          var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
672          var scriptId = jsonpCallback + "_" + callbackFunction;
673          window[callbackFunction] = function(response) {
674            resolve({
675              ok: true,
676              // keep consistent with fetch API
677              json: function json() {
678                return Promise.resolve(response);
679              }
680            });
681            if (timeoutId) clearTimeout(timeoutId);
682            removeScript(scriptId);
683            clearFunction(callbackFunction);
684          };
685          url += url.indexOf("?") === -1 ? "?" : "&";
686          var jsonpScript = document.createElement("script");
687          jsonpScript.setAttribute("src", "" + url + jsonpCallback + "=" + callbackFunction);
688          if (options.charset) {
689            jsonpScript.setAttribute("charset", options.charset);
690          }
691          if (options.nonce) {
692            jsonpScript.setAttribute("nonce", options.nonce);
693          }
694          if (options.referrerPolicy) {
695            jsonpScript.setAttribute("referrerPolicy", options.referrerPolicy);
696          }
697          if (options.crossorigin) {
698            jsonpScript.setAttribute("crossorigin", "true");
699          }
700          jsonpScript.id = scriptId;
701          document.getElementsByTagName("head")[0].appendChild(jsonpScript);
702          timeoutId = setTimeout(function() {
703            reject(new Error("JSONP request to " + _url + " timed out"));
704            clearFunction(callbackFunction);
705            removeScript(scriptId);
706            window[callbackFunction] = function() {
707              clearFunction(callbackFunction);
708            };
709          }, timeout);
710          jsonpScript.onerror = function() {
711            reject(new Error("JSONP request to " + _url + " failed"));
712            clearFunction(callbackFunction);
713            removeScript(scriptId);
714            if (timeoutId) clearTimeout(timeoutId);
715          };
716        });
717      }
718      module2.exports = fetchJsonp2;
719    });
720  }
721});
722
vendor: 37,450 bytes, lines 723-1647
723// node_modules/pikaday/pikaday.js
724var require_pikaday = __commonJS({
725  "node_modules/pikaday/pikaday.js"(exports, module) {
726    (function(root, factory) {
727      "use strict";
728      var moment;
729      if (typeof exports === "object") {
730        try {
731          moment = __require("moment");
732        } catch (e) {
733        }
734        module.exports = factory(moment);
735      } else if (typeof define === "function" && define.amd) {
736        define(function(req) {
737          var id = "moment";
738          try {
739            moment = req(id);
740          } catch (e) {
741          }
742          return factory(moment);
743        });
744      } else {
745        root.Pikaday = factory(root.moment);
746      }
747    })(exports, function(moment) {
748      "use strict";
749      var hasMoment = typeof moment === "function", hasEventListeners = !!window.addEventListener, document2 = window.document, sto = window.setTimeout, addEvent = function(el, e, callback, capture) {
750        if (hasEventListeners) {
751          el.addEventListener(e, callback, !!capture);
752        } else {
753          el.attachEvent("on" + e, callback);
754        }
755      }, removeEvent = function(el, e, callback, capture) {
756        if (hasEventListeners) {
757          el.removeEventListener(e, callback, !!capture);
758        } else {
759          el.detachEvent("on" + e, callback);
760        }
761      }, trim = function(str) {
762        return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, "");
763      }, hasClass = function(el, cn) {
764        return (" " + el.className + " ").indexOf(" " + cn + " ") !== -1;
765      }, addClass = function(el, cn) {
766        if (!hasClass(el, cn)) {
767          el.className = el.className === "" ? cn : el.className + " " + cn;
768        }
769      }, removeClass = function(el, cn) {
770        el.className = trim((" " + el.className + " ").replace(" " + cn + " ", " "));
771      }, isArray = function(obj) {
772        return /Array/.test(Object.prototype.toString.call(obj));
773      }, isDate = function(obj) {
774        return /Date/.test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
775      }, isWeekend = function(date) {
776        var day = date.getDay();
777        return day === 0 || day === 6;
778      }, isLeapYear = function(year) {
779        return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
780      }, getDaysInMonth = function(year, month) {
781        return [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
782      }, setToStartOfDay = function(date) {
783        if (isDate(date)) date.setHours(0, 0, 0, 0);
784      }, compareDates = function(a, b) {
785        return a.getTime() === b.getTime();
786      }, extend3 = function(to, from, overwrite) {
787        var prop, hasProp;
788        for (prop in from) {
789          hasProp = to[prop] !== void 0;
790          if (hasProp && typeof from[prop] === "object" && from[prop] !== null && from[prop].nodeName === void 0) {
791            if (isDate(from[prop])) {
792              if (overwrite) {
793                to[prop] = new Date(from[prop].getTime());
794              }
795            } else if (isArray(from[prop])) {
796              if (overwrite) {
797                to[prop] = from[prop].slice(0);
798              }
799            } else {
800              to[prop] = extend3({}, from[prop], overwrite);
801            }
802          } else if (overwrite || !hasProp) {
803            to[prop] = from[prop];
804          }
805        }
806        return to;
807      }, fireEvent = function(el, eventName, data) {
808        var ev;
809        if (document2.createEvent) {
810          ev = document2.createEvent("HTMLEvents");
811          ev.initEvent(eventName, true, false);
812          ev = extend3(ev, data);
813          el.dispatchEvent(ev);
814        } else if (document2.createEventObject) {
815          ev = document2.createEventObject();
816          ev = extend3(ev, data);
817          el.fireEvent("on" + eventName, ev);
818        }
819      }, adjustCalendar = function(calendar) {
820        if (calendar.month < 0) {
821          calendar.year -= Math.ceil(Math.abs(calendar.month) / 12);
822          calendar.month += 12;
823        }
824        if (calendar.month > 11) {
825          calendar.year += Math.floor(Math.abs(calendar.month) / 12);
826          calendar.month -= 12;
827        }
828        return calendar;
829      }, defaults = {
830        // bind the picker to a form field
831        field: null,
832        // automatically show/hide the picker on `field` focus (default `true` if `field` is set)
833        bound: void 0,
834        // data-attribute on the input field with an aria assistance text (only applied when `bound` is set)
835        ariaLabel: "Use the arrow keys to pick a date",
836        // position of the datepicker, relative to the field (default to bottom & left)
837        // ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position)
838        position: "bottom left",
839        // automatically fit in the viewport even if it means repositioning from the position option
840        reposition: true,
841        // the default output format for `.toString()` and `field` value
842        format: "YYYY-MM-DD",
843        // the toString function which gets passed a current date object and format
844        // and returns a string
845        toString: null,
846        // used to create date object from current input string
847        parse: null,
848        // the initial date to view when first opened
849        defaultDate: null,
850        // make the `defaultDate` the initial selected value
851        setDefaultDate: false,
852        // first day of week (0: Sunday, 1: Monday etc)
853        firstDay: 0,
854        // minimum number of days in the week that gets week number one
855        // default ISO 8601, week 01 is the week with the first Thursday (4)
856        firstWeekOfYearMinDays: 4,
857        // the default flag for moment's strict date parsing
858        formatStrict: false,
859        // the minimum/earliest date that can be selected
860        minDate: null,
861        // the maximum/latest date that can be selected
862        maxDate: null,
863        // number of years either side, or array of upper/lower range
864        yearRange: 10,
865        // show week numbers at head of row
866        showWeekNumber: false,
867        // Week picker mode
868        pickWholeWeek: false,
869        // used internally (don't config outside)
870        minYear: 0,
871        maxYear: 9999,
872        minMonth: void 0,
873        maxMonth: void 0,
874        startRange: null,
875        endRange: null,
876        isRTL: false,
877        // Additional text to append to the year in the calendar title
878        yearSuffix: "",
879        // Render the month after year in the calendar title
880        showMonthAfterYear: false,
881        // Render days of the calendar grid that fall in the next or previous month
882        showDaysInNextAndPreviousMonths: false,
883        // Allows user to select days that fall in the next or previous month
884        enableSelectionDaysInNextAndPreviousMonths: false,
885        // how many months are visible
886        numberOfMonths: 1,
887        // when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`)
888        // only used for the first display or when a selected date is not visible
889        mainCalendar: "left",
890        // Specify a DOM element to render the calendar in
891        container: void 0,
892        // Blur field when date is selected
893        blurFieldOnSelect: true,
894        // internationalization
895        i18n: {
896          previousMonth: "Previous Month",
897          nextMonth: "Next Month",
898          months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
899          weekdays: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
900          weekdaysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
901        },
902        // Theme Classname
903        theme: null,
904        // events array
905        events: [],
906        // callback function
907        onSelect: null,
908        onOpen: null,
909        onClose: null,
910        onDraw: null,
911        // Enable keyboard input
912        keyboardInput: true
913      }, renderDayName = function(opts, day, abbr) {
914        day += opts.firstDay;
915        while (day >= 7) {
916          day -= 7;
917        }
918        return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day];
919      }, renderDay = function(opts) {
920        var arr = [];
921        var ariaSelected = "false";
922        if (opts.isEmpty) {
923          if (opts.showDaysInNextAndPreviousMonths) {
924            arr.push("is-outside-current-month");
925            if (!opts.enableSelectionDaysInNextAndPreviousMonths) {
926              arr.push("is-selection-disabled");
927            }
928          } else {
929            return '<td class="is-empty"></td>';
930          }
931        }
932        if (opts.isDisabled) {
933          arr.push("is-disabled");
934        }
935        if (opts.isToday) {
936          arr.push("is-today");
937        }
938        if (opts.isSelected) {
939          arr.push("is-selected");
940          ariaSelected = "true";
941        }
942        if (opts.hasEvent) {
943          arr.push("has-event");
944        }
945        if (opts.isInRange) {
946          arr.push("is-inrange");
947        }
948        if (opts.isStartRange) {
949          arr.push("is-startrange");
950        }
951        if (opts.isEndRange) {
952          arr.push("is-endrange");
953        }
954        return '<td data-day="' + opts.day + '" class="' + arr.join(" ") + '" aria-selected="' + ariaSelected + '"><button class="pika-button pika-day" type="button" data-pika-year="' + opts.year + '" data-pika-month="' + opts.month + '" data-pika-day="' + opts.day + '">' + opts.day + "</button></td>";
955      }, isoWeek = function(date, firstWeekOfYearMinDays) {
956        date.setHours(0, 0, 0, 0);
957        var yearDay = date.getDate(), weekDay = date.getDay(), dayInFirstWeek = firstWeekOfYearMinDays, dayShift = dayInFirstWeek - 1, daysPerWeek = 7, prevWeekDay = function(day) {
958          return (day + daysPerWeek - 1) % daysPerWeek;
959        };
960        date.setDate(yearDay + dayShift - prevWeekDay(weekDay));
961        var jan4th = new Date(date.getFullYear(), 0, dayInFirstWeek), msPerDay = 24 * 60 * 60 * 1e3, daysBetween = (date.getTime() - jan4th.getTime()) / msPerDay, weekNum = 1 + Math.round((daysBetween - dayShift + prevWeekDay(jan4th.getDay())) / daysPerWeek);
962        return weekNum;
963      }, renderWeek = function(d, m, y, firstWeekOfYearMinDays) {
964        var date = new Date(y, m, d), week = hasMoment ? moment(date).isoWeek() : isoWeek(date, firstWeekOfYearMinDays);
965        return '<td class="pika-week">' + week + "</td>";
966      }, renderRow = function(days, isRTL, pickWholeWeek, isRowSelected) {
967        return '<tr class="pika-row' + (pickWholeWeek ? " pick-whole-week" : "") + (isRowSelected ? " is-selected" : "") + '">' + (isRTL ? days.reverse() : days).join("") + "</tr>";
968      }, renderBody = function(rows) {
969        return "<tbody>" + rows.join("") + "</tbody>";
970      }, renderHead = function(opts) {
971        var i, arr = [];
972        if (opts.showWeekNumber) {
973          arr.push("<th></th>");
974        }
975        for (i = 0; i < 7; i++) {
976          arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + "</abbr></th>");
977        }
978        return "<thead><tr>" + (opts.isRTL ? arr.reverse() : arr).join("") + "</tr></thead>";
979      }, renderTitle = function(instance, c, year, month, refYear, randId) {
980        var i, j, arr, opts = instance._o, isMinYear = year === opts.minYear, isMaxYear = year === opts.maxYear, html = '<div id="' + randId + '" class="pika-title" role="heading" aria-live="assertive">', monthHtml, yearHtml, prev = true, next = true;
981        for (arr = [], i = 0; i < 12; i++) {
982          arr.push('<option value="' + (year === refYear ? i - c : 12 + i - c) + '"' + (i === month ? ' selected="selected"' : "") + (isMinYear && i < opts.minMonth || isMaxYear && i > opts.maxMonth ? ' disabled="disabled"' : "") + ">" + opts.i18n.months[i] + "</option>");
983        }
984        monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month" tabindex="-1">' + arr.join("") + "</select></div>";
985        if (isArray(opts.yearRange)) {
986          i = opts.yearRange[0];
987          j = opts.yearRange[1] + 1;
988        } else {
989          i = year - opts.yearRange;
990          j = 1 + year + opts.yearRange;
991        }
992        for (arr = []; i < j && i <= opts.maxYear; i++) {
993          if (i >= opts.minYear) {
994            arr.push('<option value="' + i + '"' + (i === year ? ' selected="selected"' : "") + ">" + i + "</option>");
995          }
996        }
997        yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year" tabindex="-1">' + arr.join("") + "</select></div>";
998        if (opts.showMonthAfterYear) {
999          html += yearHtml + monthHtml;
1000        } else {
1001          html += monthHtml + yearHtml;
1002        }
1003        if (isMinYear && (month === 0 || opts.minMonth >= month)) {
1004          prev = false;
1005        }
1006        if (isMaxYear && (month === 11 || opts.maxMonth <= month)) {
1007          next = false;
1008        }
1009        if (c === 0) {
1010          html += '<button class="pika-prev' + (prev ? "" : " is-disabled") + '" type="button">' + opts.i18n.previousMonth + "</button>";
1011        }
1012        if (c === instance._o.numberOfMonths - 1) {
1013          html += '<button class="pika-next' + (next ? "" : " is-disabled") + '" type="button">' + opts.i18n.nextMonth + "</button>";
1014        }
1015        return html += "</div>";
1016      }, renderTable = function(opts, data, randId) {
1017        return '<table cellpadding="0" cellspacing="0" class="pika-table" role="grid" aria-labelledby="' + randId + '">' + renderHead(opts) + renderBody(data) + "</table>";
1018      }, Pikaday2 = function(options) {
1019        var self = this, opts = self.config(options);
1020        self._onMouseDown = function(e) {
1021          if (!self._v) {
1022            return;
1023          }
1024          e = e || window.event;
1025          var target = e.target || e.srcElement;
1026          if (!target) {
1027            return;
1028          }
1029          if (!hasClass(target, "is-disabled")) {
1030            if (hasClass(target, "pika-button") && !hasClass(target, "is-empty") && !hasClass(target.parentNode, "is-disabled")) {
1031              self.setDate(new Date(target.getAttribute("data-pika-year"), target.getAttribute("data-pika-month"), target.getAttribute("data-pika-day")));
1032              if (opts.bound) {
1033                sto(function() {
1034                  self.hide();
1035                  if (opts.blurFieldOnSelect && opts.field) {
1036                    opts.field.blur();
1037                  }
1038                }, 100);
1039              }
1040            } else if (hasClass(target, "pika-prev")) {
1041              self.prevMonth();
1042            } else if (hasClass(target, "pika-next")) {
1043              self.nextMonth();
1044            }
1045          }
1046          if (!hasClass(target, "pika-select")) {
1047            if (e.preventDefault) {
1048              e.preventDefault();
1049            } else {
1050              e.returnValue = false;
1051              return false;
1052            }
1053          } else {
1054            self._c = true;
1055          }
1056        };
1057        self._onChange = function(e) {
1058          e = e || window.event;
1059          var target = e.target || e.srcElement;
1060          if (!target) {
1061            return;
1062          }
1063          if (hasClass(target, "pika-select-month")) {
1064            self.gotoMonth(target.value);
1065          } else if (hasClass(target, "pika-select-year")) {
1066            self.gotoYear(target.value);
1067          }
1068        };
1069        self._onKeyChange = function(e) {
1070          e = e || window.event;
1071          if (self.isVisible()) {
1072            switch (e.keyCode) {
1073              case 13:
1074              case 27:
1075                if (opts.field) {
1076                  opts.field.blur();
1077                }
1078                break;
1079              case 37:
1080                self.adjustDate("subtract", 1);
1081                break;
1082              case 38:
1083                self.adjustDate("subtract", 7);
1084                break;
1085              case 39:
1086                self.adjustDate("add", 1);
1087                break;
1088              case 40:
1089                self.adjustDate("add", 7);
1090                break;
1091              case 8:
1092              case 46:
1093                self.setDate(null);
1094                break;
1095            }
1096          }
1097        };
1098        self._parseFieldValue = function() {
1099          if (opts.parse) {
1100            return opts.parse(opts.field.value, opts.format);
1101          } else if (hasMoment) {
1102            var date = moment(opts.field.value, opts.format, opts.formatStrict);
1103            return date && date.isValid() ? date.toDate() : null;
1104          } else {
1105            return new Date(Date.parse(opts.field.value));
1106          }
1107        };
1108        self._onInputChange = function(e) {
1109          var date;
1110          if (e.firedBy === self) {
1111            return;
1112          }
1113          date = self._parseFieldValue();
1114          if (isDate(date)) {
1115            self.setDate(date);
1116          }
1117          if (!self._v) {
1118            self.show();
1119          }
1120        };
1121        self._onInputFocus = function() {
1122          self.show();
1123        };
1124        self._onInputClick = function() {
1125          self.show();
1126        };
1127        self._onInputBlur = function() {
1128          var pEl = document2.activeElement;
1129          do {
1130            if (hasClass(pEl, "pika-single")) {
1131              return;
1132            }
1133          } while (pEl = pEl.parentNode);
1134          if (!self._c) {
1135            self._b = sto(function() {
1136              self.hide();
1137            }, 50);
1138          }
1139          self._c = false;
1140        };
1141        self._onClick = function(e) {
1142          e = e || window.event;
1143          var target = e.target || e.srcElement, pEl = target;
1144          if (!target) {
1145            return;
1146          }
1147          if (!hasEventListeners && hasClass(target, "pika-select")) {
1148            if (!target.onchange) {
1149              target.setAttribute("onchange", "return;");
1150              addEvent(target, "change", self._onChange);
1151            }
1152          }
1153          do {
1154            if (hasClass(pEl, "pika-single") || pEl === opts.trigger) {
1155              return;
1156            }
1157          } while (pEl = pEl.parentNode);
1158          if (self._v && target !== opts.trigger && pEl !== opts.trigger) {
1159            self.hide();
1160          }
1161        };
1162        self.el = document2.createElement("div");
1163        self.el.className = "pika-single" + (opts.isRTL ? " is-rtl" : "") + (opts.theme ? " " + opts.theme : "");
1164        addEvent(self.el, "mousedown", self._onMouseDown, true);
1165        addEvent(self.el, "touchend", self._onMouseDown, true);
1166        addEvent(self.el, "change", self._onChange);
1167        if (opts.keyboardInput) {
1168          addEvent(document2, "keydown", self._onKeyChange);
1169        }
1170        if (opts.field) {
1171          if (opts.container) {
1172            opts.container.appendChild(self.el);
1173          } else if (opts.bound) {
1174            document2.body.appendChild(self.el);
1175          } else {
1176            opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling);
1177          }
1178          addEvent(opts.field, "change", self._onInputChange);
1179          if (!opts.defaultDate) {
1180            opts.defaultDate = self._parseFieldValue();
1181            opts.setDefaultDate = true;
1182          }
1183        }
1184        var defDate = opts.defaultDate;
1185        if (isDate(defDate)) {
1186          if (opts.setDefaultDate) {
1187            self.setDate(defDate, true);
1188          } else {
1189            self.gotoDate(defDate);
1190          }
1191        } else {
1192          self.gotoDate(/* @__PURE__ */ new Date());
1193        }
1194        if (opts.bound) {
1195          this.hide();
1196          self.el.className += " is-bound";
1197          addEvent(opts.trigger, "click", self._onInputClick);
1198          addEvent(opts.trigger, "focus", self._onInputFocus);
1199          addEvent(opts.trigger, "blur", self._onInputBlur);
1200        } else {
1201          this.show();
1202        }
1203      };
1204      Pikaday2.prototype = {
1205        /**
1206         * configure functionality
1207         */
1208        config: function(options) {
1209          if (!this._o) {
1210            this._o = extend3({}, defaults, true);
1211          }
1212          var opts = extend3(this._o, options, true);
1213          opts.isRTL = !!opts.isRTL;
1214          opts.field = opts.field && opts.field.nodeName ? opts.field : null;
1215          opts.theme = typeof opts.theme === "string" && opts.theme ? opts.theme : null;
1216          opts.bound = !!(opts.bound !== void 0 ? opts.field && opts.bound : opts.field);
1217          opts.trigger = opts.trigger && opts.trigger.nodeName ? opts.trigger : opts.field;
1218          opts.disableWeekends = !!opts.disableWeekends;
1219          opts.disableDayFn = typeof opts.disableDayFn === "function" ? opts.disableDayFn : null;
1220          var nom = parseInt(opts.numberOfMonths, 10) || 1;
1221          opts.numberOfMonths = nom > 4 ? 4 : nom;
1222          if (!isDate(opts.minDate)) {
1223            opts.minDate = false;
1224          }
1225          if (!isDate(opts.maxDate)) {
1226            opts.maxDate = false;
1227          }
1228          if (opts.minDate && opts.maxDate && opts.maxDate < opts.minDate) {
1229            opts.maxDate = opts.minDate = false;
1230          }
1231          if (opts.minDate) {
1232            this.setMinDate(opts.minDate);
1233          }
1234          if (opts.maxDate) {
1235            this.setMaxDate(opts.maxDate);
1236          }
1237          if (isArray(opts.yearRange)) {
1238            var fallback = (/* @__PURE__ */ new Date()).getFullYear() - 10;
1239            opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback;
1240            opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback;
1241          } else {
1242            opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange;
1243            if (opts.yearRange > 100) {
1244              opts.yearRange = 100;
1245            }
1246          }
1247          return opts;
1248        },
1249        /**
1250         * return a formatted string of the current selection (using Moment.js if available)
1251         */
1252        toString: function(format) {
1253          format = format || this._o.format;
1254          if (!isDate(this._d)) {
1255            return "";
1256          }
1257          if (this._o.toString) {
1258            return this._o.toString(this._d, format);
1259          }
1260          if (hasMoment) {
1261            return moment(this._d).format(format);
1262          }
1263          return this._d.toDateString();
1264        },
1265        /**
1266         * return a Moment.js object of the current selection (if available)
1267         */
1268        getMoment: function() {
1269          return hasMoment ? moment(this._d) : null;
1270        },
1271        /**
1272         * set the current selection from a Moment.js object (if available)
1273         */
1274        setMoment: function(date, preventOnSelect) {
1275          if (hasMoment && moment.isMoment(date)) {
1276            this.setDate(date.toDate(), preventOnSelect);
1277          }
1278        },
1279        /**
1280         * return a Date object of the current selection
1281         */
1282        getDate: function() {
1283          return isDate(this._d) ? new Date(this._d.getTime()) : null;
1284        },
1285        /**
1286         * set the current selection
1287         */
1288        setDate: function(date, preventOnSelect) {
1289          if (!date) {
1290            this._d = null;
1291            if (this._o.field) {
1292              this._o.field.value = "";
1293              fireEvent(this._o.field, "change", { firedBy: this });
1294            }
1295            return this.draw();
1296          }
1297          if (typeof date === "string") {
1298            date = new Date(Date.parse(date));
1299          }
1300          if (!isDate(date)) {
1301            return;
1302          }
1303          var min = this._o.minDate, max = this._o.maxDate;
1304          if (isDate(min) && date < min) {
1305            date = min;
1306          } else if (isDate(max) && date > max) {
1307            date = max;
1308          }
1309          this._d = new Date(date.getTime());
1310          setToStartOfDay(this._d);
1311          this.gotoDate(this._d);
1312          if (this._o.field) {
1313            this._o.field.value = this.toString();
1314            fireEvent(this._o.field, "change", { firedBy: this });
1315          }
1316          if (!preventOnSelect && typeof this._o.onSelect === "function") {
1317            this._o.onSelect.call(this, this.getDate());
1318          }
1319        },
1320        /**
1321         * clear and reset the date
1322         */
1323        clear: function() {
1324          this.setDate(null);
1325        },
1326        /**
1327         * change view to a specific date
1328         */
1329        gotoDate: function(date) {
1330          var newCalendar = true;
1331          if (!isDate(date)) {
1332            return;
1333          }
1334          if (this.calendars) {
1335            var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1), lastVisibleDate = new Date(this.calendars[this.calendars.length - 1].year, this.calendars[this.calendars.length - 1].month, 1), visibleDate = date.getTime();
1336            lastVisibleDate.setMonth(lastVisibleDate.getMonth() + 1);
1337            lastVisibleDate.setDate(lastVisibleDate.getDate() - 1);
1338            newCalendar = visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate;
1339          }
1340          if (newCalendar) {
1341            this.calendars = [{
1342              month: date.getMonth(),
1343              year: date.getFullYear()
1344            }];
1345            if (this._o.mainCalendar === "right") {
1346              this.calendars[0].month += 1 - this._o.numberOfMonths;
1347            }
1348          }
1349          this.adjustCalendars();
1350        },
1351        adjustDate: function(sign, days) {
1352          var day = this.getDate() || /* @__PURE__ */ new Date();
1353          var difference = parseInt(days) * 24 * 60 * 60 * 1e3;
1354          var newDay;
1355          if (sign === "add") {
1356            newDay = new Date(day.valueOf() + difference);
1357          } else if (sign === "subtract") {
1358            newDay = new Date(day.valueOf() - difference);
1359          }
1360          this.setDate(newDay);
1361        },
1362        adjustCalendars: function() {
1363          this.calendars[0] = adjustCalendar(this.calendars[0]);
1364          for (var c = 1; c < this._o.numberOfMonths; c++) {
1365            this.calendars[c] = adjustCalendar({
1366              month: this.calendars[0].month + c,
1367              year: this.calendars[0].year
1368            });
1369          }
1370          this.draw();
1371        },
1372        gotoToday: function() {
1373          this.gotoDate(/* @__PURE__ */ new Date());
1374        },
1375        /**
1376         * change view to a specific month (zero-index, e.g. 0: January)
1377         */
1378        gotoMonth: function(month) {
1379          if (!isNaN(month)) {
1380            this.calendars[0].month = parseInt(month, 10);
1381            this.adjustCalendars();
1382          }
1383        },
1384        nextMonth: function() {
1385          this.calendars[0].month++;
1386          this.adjustCalendars();
1387        },
1388        prevMonth: function() {
1389          this.calendars[0].month--;
1390          this.adjustCalendars();
1391        },
1392        /**
1393         * change view to a specific full year (e.g. "2012")
1394         */
1395        gotoYear: function(year) {
1396          if (!isNaN(year)) {
1397            this.calendars[0].year = parseInt(year, 10);
1398            this.adjustCalendars();
1399          }
1400        },
1401        /**
1402         * change the minDate
1403         */
1404        setMinDate: function(value) {
1405          if (value instanceof Date) {
1406            setToStartOfDay(value);
1407            this._o.minDate = value;
1408            this._o.minYear = value.getFullYear();
1409            this._o.minMonth = value.getMonth();
1410          } else {
1411            this._o.minDate = defaults.minDate;
1412            this._o.minYear = defaults.minYear;
1413            this._o.minMonth = defaults.minMonth;
1414            this._o.startRange = defaults.startRange;
1415          }
1416          this.draw();
1417        },
1418        /**
1419         * change the maxDate
1420         */
1421        setMaxDate: function(value) {
1422          if (value instanceof Date) {
1423            setToStartOfDay(value);
1424            this._o.maxDate = value;
1425            this._o.maxYear = value.getFullYear();
1426            this._o.maxMonth = value.getMonth();
1427          } else {
1428            this._o.maxDate = defaults.maxDate;
1429            this._o.maxYear = defaults.maxYear;
1430            this._o.maxMonth = defaults.maxMonth;
1431            this._o.endRange = defaults.endRange;
1432          }
1433          this.draw();
1434        },
1435        setStartRange: function(value) {
1436          this._o.startRange = value;
1437        },
1438        setEndRange: function(value) {
1439          this._o.endRange = value;
1440        },
1441        /**
1442         * refresh the HTML
1443         */
1444        draw: function(force) {
1445          if (!this._v && !force) {
1446            return;
1447          }
1448          var opts = this._o, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth, html = "", randId;
1449          if (this._y <= minYear) {
1450            this._y = minYear;
1451            if (!isNaN(minMonth) && this._m < minMonth) {
1452              this._m = minMonth;
1453            }
1454          }
1455          if (this._y >= maxYear) {
1456            this._y = maxYear;
1457            if (!isNaN(maxMonth) && this._m > maxMonth) {
1458              this._m = maxMonth;
1459            }
1460          }
1461          for (var c = 0; c < opts.numberOfMonths; c++) {
1462            randId = "pika-title-" + Math.random().toString(36).replace(/[^a-z]+/g, "").substr(0, 2);
1463            html += '<div class="pika-lendar">' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId) + "</div>";
1464          }
1465          this.el.innerHTML = html;
1466          if (opts.bound) {
1467            if (opts.field.type !== "hidden") {
1468              sto(function() {
1469                opts.trigger.focus();
1470              }, 1);
1471            }
1472          }
1473          if (typeof this._o.onDraw === "function") {
1474            this._o.onDraw(this);
1475          }
1476          if (opts.bound) {
1477            opts.field.setAttribute("aria-label", opts.ariaLabel);
1478          }
1479        },
1480        adjustPosition: function() {
1481          var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect, leftAligned, bottomAligned;
1482          if (this._o.container) return;
1483          this.el.style.position = "absolute";
1484          field = this._o.trigger;
1485          pEl = field;
1486          width = this.el.offsetWidth;
1487          height = this.el.offsetHeight;
1488          viewportWidth = window.innerWidth || document2.documentElement.clientWidth;
1489          viewportHeight = window.innerHeight || document2.documentElement.clientHeight;
1490          scrollTop = window.pageYOffset || document2.body.scrollTop || document2.documentElement.scrollTop;
1491          leftAligned = true;
1492          bottomAligned = true;
1493          if (typeof field.getBoundingClientRect === "function") {
1494            clientRect = field.getBoundingClientRect();
1495            left = clientRect.left + window.pageXOffset;
1496            top = clientRect.bottom + window.pageYOffset;
1497          } else {
1498            left = pEl.offsetLeft;
1499            top = pEl.offsetTop + pEl.offsetHeight;
1500            while (pEl = pEl.offsetParent) {
1501              left += pEl.offsetLeft;
1502              top += pEl.offsetTop;
1503            }
1504          }
1505          if (this._o.reposition && left + width > viewportWidth || this._o.position.indexOf("right") > -1 && left - width + field.offsetWidth > 0) {
1506            left = left - width + field.offsetWidth;
1507            leftAligned = false;
1508          }
1509          if (this._o.reposition && top + height > viewportHeight + scrollTop || this._o.position.indexOf("top") > -1 && top - height - field.offsetHeight > 0) {
1510            top = top - height - field.offsetHeight;
1511            bottomAligned = false;
1512          }
1513          this.el.style.left = left + "px";
1514          this.el.style.top = top + "px";
1515          addClass(this.el, leftAligned ? "left-aligned" : "right-aligned");
1516          addClass(this.el, bottomAligned ? "bottom-aligned" : "top-aligned");
1517          removeClass(this.el, !leftAligned ? "left-aligned" : "right-aligned");
1518          removeClass(this.el, !bottomAligned ? "bottom-aligned" : "top-aligned");
1519        },
1520        /**
1521         * render HTML for a particular month
1522         */
1523        render: function(year, month, randId) {
1524          var opts = this._o, now2 = /* @__PURE__ */ new Date(), days = getDaysInMonth(year, month), before = new Date(year, month, 1).getDay(), data = [], row = [];
1525          setToStartOfDay(now2);
1526          if (opts.firstDay > 0) {
1527            before -= opts.firstDay;
1528            if (before < 0) {
1529              before += 7;
1530            }
1531          }
1532          var previousMonth = month === 0 ? 11 : month - 1, nextMonth = month === 11 ? 0 : month + 1, yearOfPreviousMonth = month === 0 ? year - 1 : year, yearOfNextMonth = month === 11 ? year + 1 : year, daysInPreviousMonth = getDaysInMonth(yearOfPreviousMonth, previousMonth);
1533          var cells = days + before, after = cells;
1534          while (after > 7) {
1535            after -= 7;
1536          }
1537          cells += 7 - after;
1538          var isWeekSelected = false;
1539          for (var i = 0, r = 0; i < cells; i++) {
1540            var day = new Date(year, month, 1 + (i - before)), isSelected = isDate(this._d) ? compareDates(day, this._d) : false, isToday = compareDates(day, now2), hasEvent = opts.events.indexOf(day.toDateString()) !== -1 ? true : false, isEmpty = i < before || i >= days + before, dayNumber = 1 + (i - before), monthNumber = month, yearNumber = year, isStartRange = opts.startRange && compareDates(opts.startRange, day), isEndRange = opts.endRange && compareDates(opts.endRange, day), isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange, isDisabled = opts.minDate && day < opts.minDate || opts.maxDate && day > opts.maxDate || opts.disableWeekends && isWeekend(day) || opts.disableDayFn && opts.disableDayFn(day);
1541            if (isEmpty) {
1542              if (i < before) {
1543                dayNumber = daysInPreviousMonth + dayNumber;
1544                monthNumber = previousMonth;
1545                yearNumber = yearOfPreviousMonth;
1546              } else {
1547                dayNumber = dayNumber - days;
1548                monthNumber = nextMonth;
1549                yearNumber = yearOfNextMonth;
1550              }
1551            }
1552            var dayConfig = {
1553              day: dayNumber,
1554              month: monthNumber,
1555              year: yearNumber,
1556              hasEvent,
1557              isSelected,
1558              isToday,
1559              isDisabled,
1560              isEmpty,
1561              isStartRange,
1562              isEndRange,
1563              isInRange,
1564              showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths,
1565              enableSelectionDaysInNextAndPreviousMonths: opts.enableSelectionDaysInNextAndPreviousMonths
1566            };
1567            if (opts.pickWholeWeek && isSelected) {
1568              isWeekSelected = true;
1569            }
1570            row.push(renderDay(dayConfig));
1571            if (++r === 7) {
1572              if (opts.showWeekNumber) {
1573                row.unshift(renderWeek(i - before, month, year, opts.firstWeekOfYearMinDays));
1574              }
1575              data.push(renderRow(row, opts.isRTL, opts.pickWholeWeek, isWeekSelected));
1576              row = [];
1577              r = 0;
1578              isWeekSelected = false;
1579            }
1580          }
1581          return renderTable(opts, data, randId);
1582        },
1583        isVisible: function() {
1584          return this._v;
1585        },
1586        show: function() {
1587          if (!this.isVisible()) {
1588            this._v = true;
1589            this.draw();
1590            removeClass(this.el, "is-hidden");
1591            if (this._o.bound) {
1592              addEvent(document2, "click", this._onClick);
1593              this.adjustPosition();
1594            }
1595            if (typeof this._o.onOpen === "function") {
1596              this._o.onOpen.call(this);
1597            }
1598          }
1599        },
1600        hide: function() {
1601          var v = this._v;
1602          if (v !== false) {
1603            if (this._o.bound) {
1604              removeEvent(document2, "click", this._onClick);
1605            }
1606            if (!this._o.container) {
1607              this.el.style.position = "static";
1608              this.el.style.left = "auto";
1609              this.el.style.top = "auto";
1610            }
1611            addClass(this.el, "is-hidden");
1612            this._v = false;
1613            if (v !== void 0 && typeof this._o.onClose === "function") {
1614              this._o.onClose.call(this);
1615            }
1616          }
1617        },
1618        /**
1619         * GAME OVER
1620         */
1621        destroy: function() {
1622          var opts = this._o;
1623          this.hide();
1624          removeEvent(this.el, "mousedown", this._onMouseDown, true);
1625          removeEvent(this.el, "touchend", this._onMouseDown, true);
1626          removeEvent(this.el, "change", this._onChange);
1627          if (opts.keyboardInput) {
1628            removeEvent(document2, "keydown", this._onKeyChange);
1629          }
1630          if (opts.field) {
1631            removeEvent(opts.field, "change", this._onInputChange);
1632            if (opts.bound) {
1633              removeEvent(opts.trigger, "click", this._onInputClick);
1634              removeEvent(opts.trigger, "focus", this._onInputFocus);
1635              removeEvent(opts.trigger, "blur", this._onInputBlur);
1636            }
1637          }
1638          if (this.el.parentNode) {
1639            this.el.parentNode.removeChild(this.el);
1640          }
1641        }
1642      };
1643      return Pikaday2;
1644    });
1645  }
1646});
1647
vendor: 167,495 bytes, lines 1648-6861
1648// node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js
1649var turbo_es2017_esm_exports = {};
1650__export(turbo_es2017_esm_exports, {
1651  FetchEnctype: () => FetchEnctype,
1652  FetchMethod: () => FetchMethod,
1653  FetchRequest: () => FetchRequest,
1654  FetchResponse: () => FetchResponse,
1655  FrameElement: () => FrameElement,
1656  FrameLoadingStyle: () => FrameLoadingStyle,
1657  FrameRenderer: () => FrameRenderer,
1658  PageRenderer: () => PageRenderer,
1659  PageSnapshot: () => PageSnapshot,
1660  StreamActions: () => StreamActions,
1661  StreamElement: () => StreamElement,
1662  StreamSourceElement: () => StreamSourceElement,
1663  cache: () => cache,
1664  clearCache: () => clearCache,
1665  config: () => config,
1666  connectStreamSource: () => connectStreamSource,
1667  disconnectStreamSource: () => disconnectStreamSource,
1668  fetch: () => fetchWithTurboHeaders,
1669  fetchEnctypeFromString: () => fetchEnctypeFromString,
1670  fetchMethodFromString: () => fetchMethodFromString,
1671  isSafe: () => isSafe,
1672  navigator: () => navigator$1,
1673  registerAdapter: () => registerAdapter,
1674  renderStreamMessage: () => renderStreamMessage,
1675  session: () => session,
1676  setConfirmMethod: () => setConfirmMethod,
1677  setFormMode: () => setFormMode,
1678  setProgressBarDelay: () => setProgressBarDelay,
1679  start: () => start,
1680  visit: () => visit
1681});
1682(function(prototype) {
1683  if (typeof prototype.requestSubmit == "function") return;
1684  prototype.requestSubmit = function(submitter2) {
1685    if (submitter2) {
1686      validateSubmitter(submitter2, this);
1687      submitter2.click();
1688    } else {
1689      submitter2 = document.createElement("input");
1690      submitter2.type = "submit";
1691      submitter2.hidden = true;
1692      this.appendChild(submitter2);
1693      submitter2.click();
1694      this.removeChild(submitter2);
1695    }
1696  };
1697  function validateSubmitter(submitter2, form) {
1698    submitter2 instanceof HTMLElement || raise(TypeError, "parameter 1 is not of type 'HTMLElement'");
1699    submitter2.type == "submit" || raise(TypeError, "The specified element is not a submit button");
1700    submitter2.form == form || raise(DOMException, "The specified element is not owned by this form element", "NotFoundError");
1701  }
1702  function raise(errorConstructor, message, name) {
1703    throw new errorConstructor("Failed to execute 'requestSubmit' on 'HTMLFormElement': " + message + ".", name);
1704  }
1705})(HTMLFormElement.prototype);
1706var submittersByForm = /* @__PURE__ */ new WeakMap();
1707function findSubmitterFromClickTarget(target) {
1708  const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
1709  const candidate = element ? element.closest("input, button") : null;
1710  return candidate?.type == "submit" ? candidate : null;
1711}
1712function clickCaptured(event) {
1713  const submitter2 = findSubmitterFromClickTarget(event.target);
1714  if (submitter2 && submitter2.form) {
1715    submittersByForm.set(submitter2.form, submitter2);
1716  }
1717}
1718(function() {
1719  if ("submitter" in Event.prototype) return;
1720  let prototype = window.Event.prototype;
1721  if ("SubmitEvent" in window) {
1722    const prototypeOfSubmitEvent = window.SubmitEvent.prototype;
1723    if (/Apple Computer/.test(navigator.vendor) && !("submitter" in prototypeOfSubmitEvent)) {
1724      prototype = prototypeOfSubmitEvent;
1725    } else {
1726      return;
1727    }
1728  }
1729  addEventListener("click", clickCaptured, true);
1730  Object.defineProperty(prototype, "submitter", {
1731    get() {
1732      if (this.type == "submit" && this.target instanceof HTMLFormElement) {
1733        return submittersByForm.get(this.target);
1734      }
1735    }
1736  });
1737})();
1738var FrameLoadingStyle = {
1739  eager: "eager",
1740  lazy: "lazy"
1741};
1742var FrameElement = class _FrameElement extends HTMLElement {
1743  static delegateConstructor = void 0;
1744  loaded = Promise.resolve();
1745  static get observedAttributes() {
1746    return ["disabled", "loading", "src"];
1747  }
1748  constructor() {
1749    super();
1750    this.delegate = new _FrameElement.delegateConstructor(this);
1751  }
1752  connectedCallback() {
1753    this.delegate.connect();
1754  }
1755  disconnectedCallback() {
1756    this.delegate.disconnect();
1757  }
1758  reload() {
1759    return this.delegate.sourceURLReloaded();
1760  }
1761  attributeChangedCallback(name) {
1762    if (name == "loading") {
1763      this.delegate.loadingStyleChanged();
1764    } else if (name == "src") {
1765      this.delegate.sourceURLChanged();
1766    } else if (name == "disabled") {
1767      this.delegate.disabledChanged();
1768    }
1769  }
1770  /**
1771   * Gets the URL to lazily load source HTML from
1772   */
1773  get src() {
1774    return this.getAttribute("src");
1775  }
1776  /**
1777   * Sets the URL to lazily load source HTML from
1778   */
1779  set src(value) {
1780    if (value) {
1781      this.setAttribute("src", value);
1782    } else {
1783      this.removeAttribute("src");
1784    }
1785  }
1786  /**
1787   * Gets the refresh mode for the frame.
1788   */
1789  get refresh() {
1790    return this.getAttribute("refresh");
1791  }
1792  /**
1793   * Sets the refresh mode for the frame.
1794   */
1795  set refresh(value) {
1796    if (value) {
1797      this.setAttribute("refresh", value);
1798    } else {
1799      this.removeAttribute("refresh");
1800    }
1801  }
1802  get shouldReloadWithMorph() {
1803    return this.src && this.refresh === "morph";
1804  }
1805  /**
1806   * Determines if the element is loading
1807   */
1808  get loading() {
1809    return frameLoadingStyleFromString(this.getAttribute("loading") || "");
1810  }
1811  /**
1812   * Sets the value of if the element is loading
1813   */
1814  set loading(value) {
1815    if (value) {
1816      this.setAttribute("loading", value);
1817    } else {
1818      this.removeAttribute("loading");
1819    }
1820  }
1821  /**
1822   * Gets the disabled state of the frame.
1823   *
1824   * If disabled, no requests will be intercepted by the frame.
1825   */
1826  get disabled() {
1827    return this.hasAttribute("disabled");
1828  }
1829  /**
1830   * Sets the disabled state of the frame.
1831   *
1832   * If disabled, no requests will be intercepted by the frame.
1833   */
1834  set disabled(value) {
1835    if (value) {
1836      this.setAttribute("disabled", "");
1837    } else {
1838      this.removeAttribute("disabled");
1839    }
1840  }
1841  /**
1842   * Gets the autoscroll state of the frame.
1843   *
1844   * If true, the frame will be scrolled into view automatically on update.
1845   */
1846  get autoscroll() {
1847    return this.hasAttribute("autoscroll");
1848  }
1849  /**
1850   * Sets the autoscroll state of the frame.
1851   *
1852   * If true, the frame will be scrolled into view automatically on update.
1853   */
1854  set autoscroll(value) {
1855    if (value) {
1856      this.setAttribute("autoscroll", "");
1857    } else {
1858      this.removeAttribute("autoscroll");
1859    }
1860  }
1861  /**
1862   * Determines if the element has finished loading
1863   */
1864  get complete() {
1865    return !this.delegate.isLoading;
1866  }
1867  /**
1868   * Gets the active state of the frame.
1869   *
1870   * If inactive, source changes will not be observed.
1871   */
1872  get isActive() {
1873    return this.ownerDocument === document && !this.isPreview;
1874  }
1875  /**
1876   * Sets the active state of the frame.
1877   *
1878   * If inactive, source changes will not be observed.
1879   */
1880  get isPreview() {
1881    return this.ownerDocument?.documentElement?.hasAttribute("data-turbo-preview");
1882  }
1883};
1884function frameLoadingStyleFromString(style) {
1885  switch (style.toLowerCase()) {
1886    case "lazy":
1887      return FrameLoadingStyle.lazy;
1888    default:
1889      return FrameLoadingStyle.eager;
1890  }
1891}
1892var drive = {
1893  enabled: true,
1894  progressBarDelay: 500,
1895  unvisitableExtensions: /* @__PURE__ */ new Set(
1896    [
1897      ".7z",
1898      ".aac",
1899      ".apk",
1900      ".avi",
1901      ".bmp",
1902      ".bz2",
1903      ".css",
1904      ".csv",
1905      ".deb",
1906      ".dmg",
1907      ".doc",
1908      ".docx",
1909      ".exe",
1910      ".gif",
1911      ".gz",
1912      ".heic",
1913      ".heif",
1914      ".ico",
1915      ".iso",
1916      ".jpeg",
1917      ".jpg",
1918      ".js",
1919      ".json",
1920      ".m4a",
1921      ".mkv",
1922      ".mov",
1923      ".mp3",
1924      ".mp4",
1925      ".mpeg",
1926      ".mpg",
1927      ".msi",
1928      ".ogg",
1929      ".ogv",
1930      ".pdf",
1931      ".pkg",
1932      ".png",
1933      ".ppt",
1934      ".pptx",
1935      ".rar",
1936      ".rtf",
1937      ".svg",
1938      ".tar",
1939      ".tif",
1940      ".tiff",
1941      ".txt",
1942      ".wav",
1943      ".webm",
1944      ".webp",
1945      ".wma",
1946      ".wmv",
1947      ".xls",
1948      ".xlsx",
1949      ".xml",
1950      ".zip"
1951    ]
1952  )
1953};
1954function activateScriptElement(element) {
1955  if (element.getAttribute("data-turbo-eval") == "false") {
1956    return element;
1957  } else {
1958    const createdScriptElement = document.createElement("script");
1959    const cspNonce = getMetaContent("csp-nonce");
1960    if (cspNonce) {
1961      createdScriptElement.nonce = cspNonce;
1962    }
1963    createdScriptElement.textContent = element.textContent;
1964    createdScriptElement.async = false;
1965    copyElementAttributes(createdScriptElement, element);
1966    return createdScriptElement;
1967  }
1968}
1969function copyElementAttributes(destinationElement, sourceElement) {
1970  for (const { name, value } of sourceElement.attributes) {
1971    destinationElement.setAttribute(name, value);
1972  }
1973}
1974function createDocumentFragment(html) {
1975  const template = document.createElement("template");
1976  template.innerHTML = html;
1977  return template.content;
1978}
1979function dispatch(eventName, { target, cancelable, detail } = {}) {
1980  const event = new CustomEvent(eventName, {
1981    cancelable,
1982    bubbles: true,
1983    composed: true,
1984    detail
1985  });
1986  if (target && target.isConnected) {
1987    target.dispatchEvent(event);
1988  } else {
1989    document.documentElement.dispatchEvent(event);
1990  }
1991  return event;
1992}
1993function cancelEvent(event) {
1994  event.preventDefault();
1995  event.stopImmediatePropagation();
1996}
1997function nextRepaint() {
1998  if (document.visibilityState === "hidden") {
1999    return nextEventLoopTick();
2000  } else {
2001    return nextAnimationFrame();
2002  }
2003}
2004function nextAnimationFrame() {
2005  return new Promise((resolve) => requestAnimationFrame(() => resolve()));
2006}
2007function nextEventLoopTick() {
2008  return new Promise((resolve) => setTimeout(() => resolve(), 0));
2009}
2010function nextMicrotask() {
2011  return Promise.resolve();
2012}
2013function parseHTMLDocument(html = "") {
2014  return new DOMParser().parseFromString(html, "text/html");
2015}
2016function unindent(strings, ...values) {
2017  const lines = interpolate(strings, values).replace(/^\n/, "").split("\n");
2018  const match = lines[0].match(/^\s+/);
2019  const indent = match ? match[0].length : 0;
2020  return lines.map((line) => line.slice(indent)).join("\n");
2021}
2022function interpolate(strings, values) {
2023  return strings.reduce((result, string, i) => {
2024    const value = values[i] == void 0 ? "" : values[i];
2025    return result + string + value;
2026  }, "");
2027}
2028function uuid() {
2029  return Array.from({ length: 36 }).map((_, i) => {
2030    if (i == 8 || i == 13 || i == 18 || i == 23) {
2031      return "-";
2032    } else if (i == 14) {
2033      return "4";
2034    } else if (i == 19) {
2035      return (Math.floor(Math.random() * 4) + 8).toString(16);
2036    } else {
2037      return Math.floor(Math.random() * 15).toString(16);
2038    }
2039  }).join("");
2040}
2041function getAttribute(attributeName, ...elements) {
2042  for (const value of elements.map((element) => element?.getAttribute(attributeName))) {
2043    if (typeof value == "string") return value;
2044  }
2045  return null;
2046}
2047function hasAttribute(attributeName, ...elements) {
2048  return elements.some((element) => element && element.hasAttribute(attributeName));
2049}
2050function markAsBusy(...elements) {
2051  for (const element of elements) {
2052    if (element.localName == "turbo-frame") {
2053      element.setAttribute("busy", "");
2054    }
2055    element.setAttribute("aria-busy", "true");
2056  }
2057}
2058function clearBusyState(...elements) {
2059  for (const element of elements) {
2060    if (element.localName == "turbo-frame") {
2061      element.removeAttribute("busy");
2062    }
2063    element.removeAttribute("aria-busy");
2064  }
2065}
2066function waitForLoad(element, timeoutInMilliseconds = 2e3) {
2067  return new Promise((resolve) => {
2068    const onComplete = () => {
2069      element.removeEventListener("error", onComplete);
2070      element.removeEventListener("load", onComplete);
2071      resolve();
2072    };
2073    element.addEventListener("load", onComplete, { once: true });
2074    element.addEventListener("error", onComplete, { once: true });
2075    setTimeout(resolve, timeoutInMilliseconds);
2076  });
2077}
2078function getHistoryMethodForAction(action) {
2079  switch (action) {
2080    case "replace":
2081      return history.replaceState;
2082    case "advance":
2083    case "restore":
2084      return history.pushState;
2085  }
2086}
2087function isAction(action) {
2088  return action == "advance" || action == "replace" || action == "restore";
2089}
2090function getVisitAction(...elements) {
2091  const action = getAttribute("data-turbo-action", ...elements);
2092  return isAction(action) ? action : null;
2093}
2094function getMetaElement(name) {
2095  return document.querySelector(`meta[name="${name}"]`);
2096}
2097function getMetaContent(name) {
2098  const element = getMetaElement(name);
2099  return element && element.content;
2100}
2101function setMetaContent(name, content) {
2102  let element = getMetaElement(name);
2103  if (!element) {
2104    element = document.createElement("meta");
2105    element.setAttribute("name", name);
2106    document.head.appendChild(element);
2107  }
2108  element.setAttribute("content", content);
2109  return element;
2110}
2111function findClosestRecursively(element, selector) {
2112  if (element instanceof Element) {
2113    return element.closest(selector) || findClosestRecursively(element.assignedSlot || element.getRootNode()?.host, selector);
2114  }
2115}
2116function elementIsFocusable(element) {
2117  const inertDisabledOrHidden = "[inert], :disabled, [hidden], details:not([open]), dialog:not([open])";
2118  return !!element && element.closest(inertDisabledOrHidden) == null && typeof element.focus == "function";
2119}
2120function queryAutofocusableElement(elementOrDocumentFragment) {
2121  return Array.from(elementOrDocumentFragment.querySelectorAll("[autofocus]")).find(elementIsFocusable);
2122}
2123async function around(callback, reader) {
2124  const before = reader();
2125  callback();
2126  await nextAnimationFrame();
2127  const after = reader();
2128  return [before, after];
2129}
2130function doesNotTargetIFrame(name) {
2131  if (name === "_blank") {
2132    return false;
2133  } else if (name) {
2134    for (const element of document.getElementsByName(name)) {
2135      if (element instanceof HTMLIFrameElement) return false;
2136    }
2137    return true;
2138  } else {
2139    return true;
2140  }
2141}
2142function findLinkFromClickTarget(target) {
2143  return findClosestRecursively(target, "a[href]:not([target^=_]):not([download])");
2144}
2145function getLocationForLink(link) {
2146  return expandURL(link.getAttribute("href") || "");
2147}
2148function debounce(fn, delay) {
2149  let timeoutId = null;
2150  return (...args) => {
2151    const callback = () => fn.apply(this, args);
2152    clearTimeout(timeoutId);
2153    timeoutId = setTimeout(callback, delay);
2154  };
2155}
2156var submitter = {
2157  "aria-disabled": {
2158    beforeSubmit: (submitter2) => {
2159      submitter2.setAttribute("aria-disabled", "true");
2160      submitter2.addEventListener("click", cancelEvent);
2161    },
2162    afterSubmit: (submitter2) => {
2163      submitter2.removeAttribute("aria-disabled");
2164      submitter2.removeEventListener("click", cancelEvent);
2165    }
2166  },
2167  "disabled": {
2168    beforeSubmit: (submitter2) => submitter2.disabled = true,
2169    afterSubmit: (submitter2) => submitter2.disabled = false
2170  }
2171};
2172var Config = class {
2173  #submitter = null;
2174  constructor(config2) {
2175    Object.assign(this, config2);
2176  }
2177  get submitter() {
2178    return this.#submitter;
2179  }
2180  set submitter(value) {
2181    this.#submitter = submitter[value] || value;
2182  }
2183};
2184var forms = new Config({
2185  mode: "on",
2186  submitter: "disabled"
2187});
2188var config = {
2189  drive,
2190  forms
2191};
2192function expandURL(locatable) {
2193  return new URL(locatable.toString(), document.baseURI);
2194}
2195function getAnchor(url) {
2196  let anchorMatch;
2197  if (url.hash) {
2198    return url.hash.slice(1);
2199  } else if (anchorMatch = url.href.match(/#(.*)$/)) {
2200    return anchorMatch[1];
2201  }
2202}
2203function getAction$1(form, submitter2) {
2204  const action = submitter2?.getAttribute("formaction") || form.getAttribute("action") || form.action;
2205  return expandURL(action);
2206}
2207function getExtension(url) {
2208  return (getLastPathComponent(url).match(/\.[^.]*$/) || [])[0] || "";
2209}
2210function isPrefixedBy(baseURL, url) {
2211  const prefix = getPrefix(url);
2212  return baseURL.href === expandURL(prefix).href || baseURL.href.startsWith(prefix);
2213}
2214function locationIsVisitable(location2, rootLocation) {
2215  return isPrefixedBy(location2, rootLocation) && !config.drive.unvisitableExtensions.has(getExtension(location2));
2216}
2217function getRequestURL(url) {
2218  const anchor = getAnchor(url);
2219  return anchor != null ? url.href.slice(0, -(anchor.length + 1)) : url.href;
2220}
2221function toCacheKey(url) {
2222  return getRequestURL(url);
2223}
2224function urlsAreEqual(left, right) {
2225  return expandURL(left).href == expandURL(right).href;
2226}
2227function getPathComponents(url) {
2228  return url.pathname.split("/").slice(1);
2229}
2230function getLastPathComponent(url) {
2231  return getPathComponents(url).slice(-1)[0];
2232}
2233function getPrefix(url) {
2234  return addTrailingSlash(url.origin + url.pathname);
2235}
2236function addTrailingSlash(value) {
2237  return value.endsWith("/") ? value : value + "/";
2238}
2239var FetchResponse = class {
2240  constructor(response) {
2241    this.response = response;
2242  }
2243  get succeeded() {
2244    return this.response.ok;
2245  }
2246  get failed() {
2247    return !this.succeeded;
2248  }
2249  get clientError() {
2250    return this.statusCode >= 400 && this.statusCode <= 499;
2251  }
2252  get serverError() {
2253    return this.statusCode >= 500 && this.statusCode <= 599;
2254  }
2255  get redirected() {
2256    return this.response.redirected;
2257  }
2258  get location() {
2259    return expandURL(this.response.url);
2260  }
2261  get isHTML() {
2262    return this.contentType && this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/);
2263  }
2264  get statusCode() {
2265    return this.response.status;
2266  }
2267  get contentType() {
2268    return this.header("Content-Type");
2269  }
2270  get responseText() {
2271    return this.response.clone().text();
2272  }
2273  get responseHTML() {
2274    if (this.isHTML) {
2275      return this.response.clone().text();
2276    } else {
2277      return Promise.resolve(void 0);
2278    }
2279  }
2280  header(name) {
2281    return this.response.headers.get(name);
2282  }
2283};
2284var LimitedSet = class extends Set {
2285  constructor(maxSize) {
2286    super();
2287    this.maxSize = maxSize;
2288  }
2289  add(value) {
2290    if (this.size >= this.maxSize) {
2291      const iterator = this.values();
2292      const oldestValue = iterator.next().value;
2293      this.delete(oldestValue);
2294    }
2295    super.add(value);
2296  }
2297};
2298var recentRequests = new LimitedSet(20);
2299var nativeFetch = window.fetch;
2300function fetchWithTurboHeaders(url, options = {}) {
2301  const modifiedHeaders = new Headers(options.headers || {});
2302  const requestUID = uuid();
2303  recentRequests.add(requestUID);
2304  modifiedHeaders.append("X-Turbo-Request-Id", requestUID);
2305  return nativeFetch(url, {
2306    ...options,
2307    headers: modifiedHeaders
2308  });
2309}
2310function fetchMethodFromString(method) {
2311  switch (method.toLowerCase()) {
2312    case "get":
2313      return FetchMethod.get;
2314    case "post":
2315      return FetchMethod.post;
2316    case "put":
2317      return FetchMethod.put;
2318    case "patch":
2319      return FetchMethod.patch;
2320    case "delete":
2321      return FetchMethod.delete;
2322  }
2323}
2324var FetchMethod = {
2325  get: "get",
2326  post: "post",
2327  put: "put",
2328  patch: "patch",
2329  delete: "delete"
2330};
2331function fetchEnctypeFromString(encoding) {
2332  switch (encoding.toLowerCase()) {
2333    case FetchEnctype.multipart:
2334      return FetchEnctype.multipart;
2335    case FetchEnctype.plain:
2336      return FetchEnctype.plain;
2337    default:
2338      return FetchEnctype.urlEncoded;
2339  }
2340}
2341var FetchEnctype = {
2342  urlEncoded: "application/x-www-form-urlencoded",
2343  multipart: "multipart/form-data",
2344  plain: "text/plain"
2345};
2346var FetchRequest = class {
2347  abortController = new AbortController();
2348  #resolveRequestPromise = (_value) => {
2349  };
2350  constructor(delegate, method, location2, requestBody = new URLSearchParams(), target = null, enctype = FetchEnctype.urlEncoded) {
2351    const [url, body] = buildResourceAndBody(expandURL(location2), method, requestBody, enctype);
2352    this.delegate = delegate;
2353    this.url = url;
2354    this.target = target;
2355    this.fetchOptions = {
2356      credentials: "same-origin",
2357      redirect: "follow",
2358      method: method.toUpperCase(),
2359      headers: { ...this.defaultHeaders },
2360      body,
2361      signal: this.abortSignal,
2362      referrer: this.delegate.referrer?.href
2363    };
2364    this.enctype = enctype;
2365  }
2366  get method() {
2367    return this.fetchOptions.method;
2368  }
2369  set method(value) {
2370    const fetchBody = this.isSafe ? this.url.searchParams : this.fetchOptions.body || new FormData();
2371    const fetchMethod = fetchMethodFromString(value) || FetchMethod.get;
2372    this.url.search = "";
2373    const [url, body] = buildResourceAndBody(this.url, fetchMethod, fetchBody, this.enctype);
2374    this.url = url;
2375    this.fetchOptions.body = body;
2376    this.fetchOptions.method = fetchMethod.toUpperCase();
2377  }
2378  get headers() {
2379    return this.fetchOptions.headers;
2380  }
2381  set headers(value) {
2382    this.fetchOptions.headers = value;
2383  }
2384  get body() {
2385    if (this.isSafe) {
2386      return this.url.searchParams;
2387    } else {
2388      return this.fetchOptions.body;
2389    }
2390  }
2391  set body(value) {
2392    this.fetchOptions.body = value;
2393  }
2394  get location() {
2395    return this.url;
2396  }
2397  get params() {
2398    return this.url.searchParams;
2399  }
2400  get entries() {
2401    return this.body ? Array.from(this.body.entries()) : [];
2402  }
2403  cancel() {
2404    this.abortController.abort();
2405  }
2406  async perform() {
2407    const { fetchOptions } = this;
2408    this.delegate.prepareRequest(this);
2409    const event = await this.#allowRequestToBeIntercepted(fetchOptions);
2410    try {
2411      this.delegate.requestStarted(this);
2412      if (event.detail.fetchRequest) {
2413        this.response = event.detail.fetchRequest.response;
2414      } else {
2415        this.response = fetchWithTurboHeaders(this.url.href, fetchOptions);
2416      }
2417      const response = await this.response;
2418      return await this.receive(response);
2419    } catch (error2) {
2420      if (error2.name !== "AbortError") {
2421        if (this.#willDelegateErrorHandling(error2)) {
2422          this.delegate.requestErrored(this, error2);
2423        }
2424        throw error2;
2425      }
2426    } finally {
2427      this.delegate.requestFinished(this);
2428    }
2429  }
2430  async receive(response) {
2431    const fetchResponse = new FetchResponse(response);
2432    const event = dispatch("turbo:before-fetch-response", {
2433      cancelable: true,
2434      detail: { fetchResponse },
2435      target: this.target
2436    });
2437    if (event.defaultPrevented) {
2438      this.delegate.requestPreventedHandlingResponse(this, fetchResponse);
2439    } else if (fetchResponse.succeeded) {
2440      this.delegate.requestSucceededWithResponse(this, fetchResponse);
2441    } else {
2442      this.delegate.requestFailedWithResponse(this, fetchResponse);
2443    }
2444    return fetchResponse;
2445  }
2446  get defaultHeaders() {
2447    return {
2448      Accept: "text/html, application/xhtml+xml"
2449    };
2450  }
2451  get isSafe() {
2452    return isSafe(this.method);
2453  }
2454  get abortSignal() {
2455    return this.abortController.signal;
2456  }
2457  acceptResponseType(mimeType) {
2458    this.headers["Accept"] = [mimeType, this.headers["Accept"]].join(", ");
2459  }
2460  async #allowRequestToBeIntercepted(fetchOptions) {
2461    const requestInterception = new Promise((resolve) => this.#resolveRequestPromise = resolve);
2462    const event = dispatch("turbo:before-fetch-request", {
2463      cancelable: true,
2464      detail: {
2465        fetchOptions,
2466        url: this.url,
2467        resume: this.#resolveRequestPromise
2468      },
2469      target: this.target
2470    });
2471    this.url = event.detail.url;
2472    if (event.defaultPrevented) await requestInterception;
2473    return event;
2474  }
2475  #willDelegateErrorHandling(error2) {
2476    const event = dispatch("turbo:fetch-request-error", {
2477      target: this.target,
2478      cancelable: true,
2479      detail: { request: this, error: error2 }
2480    });
2481    return !event.defaultPrevented;
2482  }
2483};
2484function isSafe(fetchMethod) {
2485  return fetchMethodFromString(fetchMethod) == FetchMethod.get;
2486}
2487function buildResourceAndBody(resource, method, requestBody, enctype) {
2488  const searchParams = Array.from(requestBody).length > 0 ? new URLSearchParams(entriesExcludingFiles(requestBody)) : resource.searchParams;
2489  if (isSafe(method)) {
2490    return [mergeIntoURLSearchParams(resource, searchParams), null];
2491  } else if (enctype == FetchEnctype.urlEncoded) {
2492    return [resource, searchParams];
2493  } else {
2494    return [resource, requestBody];
2495  }
2496}
2497function entriesExcludingFiles(requestBody) {
2498  const entries = [];
2499  for (const [name, value] of requestBody) {
2500    if (value instanceof File) continue;
2501    else entries.push([name, value]);
2502  }
2503  return entries;
2504}
2505function mergeIntoURLSearchParams(url, requestBody) {
2506  const searchParams = new URLSearchParams(entriesExcludingFiles(requestBody));
2507  url.search = searchParams.toString();
2508  return url;
2509}
2510var AppearanceObserver = class {
2511  started = false;
2512  constructor(delegate, element) {
2513    this.delegate = delegate;
2514    this.element = element;
2515    this.intersectionObserver = new IntersectionObserver(this.intersect);
2516  }
2517  start() {
2518    if (!this.started) {
2519      this.started = true;
2520      this.intersectionObserver.observe(this.element);
2521    }
2522  }
2523  stop() {
2524    if (this.started) {
2525      this.started = false;
2526      this.intersectionObserver.unobserve(this.element);
2527    }
2528  }
2529  intersect = (entries) => {
2530    const lastEntry = entries.slice(-1)[0];
2531    if (lastEntry?.isIntersecting) {
2532      this.delegate.elementAppearedInViewport(this.element);
2533    }
2534  };
2535};
2536var StreamMessage = class {
2537  static contentType = "text/vnd.turbo-stream.html";
2538  static wrap(message) {
2539    if (typeof message == "string") {
2540      return new this(createDocumentFragment(message));
2541    } else {
2542      return message;
2543    }
2544  }
2545  constructor(fragment) {
2546    this.fragment = importStreamElements(fragment);
2547  }
2548};
2549function importStreamElements(fragment) {
2550  for (const element of fragment.querySelectorAll("turbo-stream")) {
2551    const streamElement = document.importNode(element, true);
2552    for (const inertScriptElement of streamElement.templateElement.content.querySelectorAll("script")) {
2553      inertScriptElement.replaceWith(activateScriptElement(inertScriptElement));
2554    }
2555    element.replaceWith(streamElement);
2556  }
2557  return fragment;
2558}
2559var PREFETCH_DELAY = 100;
2560var PrefetchCache = class {
2561  #prefetchTimeout = null;
2562  #prefetched = null;
2563  get(url) {
2564    if (this.#prefetched && this.#prefetched.url === url && this.#prefetched.expire > Date.now()) {
2565      return this.#prefetched.request;
2566    }
2567  }
2568  setLater(url, request, ttl) {
2569    this.clear();
2570    this.#prefetchTimeout = setTimeout(() => {
2571      request.perform();
2572      this.set(url, request, ttl);
2573      this.#prefetchTimeout = null;
2574    }, PREFETCH_DELAY);
2575  }
2576  set(url, request, ttl) {
2577    this.#prefetched = { url, request, expire: new Date((/* @__PURE__ */ new Date()).getTime() + ttl) };
2578  }
2579  clear() {
2580    if (this.#prefetchTimeout) clearTimeout(this.#prefetchTimeout);
2581    this.#prefetched = null;
2582  }
2583};
2584var cacheTtl = 10 * 1e3;
2585var prefetchCache = new PrefetchCache();
2586var FormSubmissionState = {
2587  initialized: "initialized",
2588  requesting: "requesting",
2589  waiting: "waiting",
2590  receiving: "receiving",
2591  stopping: "stopping",
2592  stopped: "stopped"
2593};
2594var FormSubmission = class _FormSubmission {
2595  state = FormSubmissionState.initialized;
2596  static confirmMethod(message) {
2597    return Promise.resolve(confirm(message));
2598  }
2599  constructor(delegate, formElement, submitter2, mustRedirect = false) {
2600    const method = getMethod(formElement, submitter2);
2601    const action = getAction(getFormAction(formElement, submitter2), method);
2602    const body = buildFormData(formElement, submitter2);
2603    const enctype = getEnctype(formElement, submitter2);
2604    this.delegate = delegate;
2605    this.formElement = formElement;
2606    this.submitter = submitter2;
2607    this.fetchRequest = new FetchRequest(this, method, action, body, formElement, enctype);
2608    this.mustRedirect = mustRedirect;
2609  }
2610  get method() {
2611    return this.fetchRequest.method;
2612  }
2613  set method(value) {
2614    this.fetchRequest.method = value;
2615  }
2616  get action() {
2617    return this.fetchRequest.url.toString();
2618  }
2619  set action(value) {
2620    this.fetchRequest.url = expandURL(value);
2621  }
2622  get body() {
2623    return this.fetchRequest.body;
2624  }
2625  get enctype() {
2626    return this.fetchRequest.enctype;
2627  }
2628  get isSafe() {
2629    return this.fetchRequest.isSafe;
2630  }
2631  get location() {
2632    return this.fetchRequest.url;
2633  }
2634  // The submission process
2635  async start() {
2636    const { initialized, requesting } = FormSubmissionState;
2637    const confirmationMessage = getAttribute("data-turbo-confirm", this.submitter, this.formElement);
2638    if (typeof confirmationMessage === "string") {
2639      const confirmMethod = typeof config.forms.confirm === "function" ? config.forms.confirm : _FormSubmission.confirmMethod;
2640      const answer = await confirmMethod(confirmationMessage, this.formElement, this.submitter);
2641      if (!answer) {
2642        return;
2643      }
2644    }
2645    if (this.state == initialized) {
2646      this.state = requesting;
2647      return this.fetchRequest.perform();
2648    }
2649  }
2650  stop() {
2651    const { stopping, stopped } = FormSubmissionState;
2652    if (this.state != stopping && this.state != stopped) {
2653      this.state = stopping;
2654      this.fetchRequest.cancel();
2655      return true;
2656    }
2657  }
2658  // Fetch request delegate
2659  prepareRequest(request) {
2660    if (!request.isSafe) {
2661      const token = getCookieValue(getMetaContent("csrf-param")) || getMetaContent("csrf-token");
2662      if (token) {
2663        request.headers["X-CSRF-Token"] = token;
2664      }
2665    }
2666    if (this.requestAcceptsTurboStreamResponse(request)) {
2667      request.acceptResponseType(StreamMessage.contentType);
2668    }
2669  }
2670  requestStarted(_request) {
2671    this.state = FormSubmissionState.waiting;
2672    if (this.submitter) config.forms.submitter.beforeSubmit(this.submitter);
2673    this.setSubmitsWith();
2674    markAsBusy(this.formElement);
2675    dispatch("turbo:submit-start", {
2676      target: this.formElement,
2677      detail: { formSubmission: this }
2678    });
2679    this.delegate.formSubmissionStarted(this);
2680  }
2681  requestPreventedHandlingResponse(request, response) {
2682    prefetchCache.clear();
2683    this.result = { success: response.succeeded, fetchResponse: response };
2684  }
2685  requestSucceededWithResponse(request, response) {
2686    if (response.clientError || response.serverError) {
2687      this.delegate.formSubmissionFailedWithResponse(this, response);
2688      return;
2689    }
2690    prefetchCache.clear();
2691    if (this.requestMustRedirect(request) && responseSucceededWithoutRedirect(response)) {
2692      const error2 = new Error("Form responses must redirect to another location");
2693      this.delegate.formSubmissionErrored(this, error2);
2694    } else {
2695      this.state = FormSubmissionState.receiving;
2696      this.result = { success: true, fetchResponse: response };
2697      this.delegate.formSubmissionSucceededWithResponse(this, response);
2698    }
2699  }
2700  requestFailedWithResponse(request, response) {
2701    this.result = { success: false, fetchResponse: response };
2702    this.delegate.formSubmissionFailedWithResponse(this, response);
2703  }
2704  requestErrored(request, error2) {
2705    this.result = { success: false, error: error2 };
2706    this.delegate.formSubmissionErrored(this, error2);
2707  }
2708  requestFinished(_request) {
2709    this.state = FormSubmissionState.stopped;
2710    if (this.submitter) config.forms.submitter.afterSubmit(this.submitter);
2711    this.resetSubmitterText();
2712    clearBusyState(this.formElement);
2713    dispatch("turbo:submit-end", {
2714      target: this.formElement,
2715      detail: { formSubmission: this, ...this.result }
2716    });
2717    this.delegate.formSubmissionFinished(this);
2718  }
2719  // Private
2720  setSubmitsWith() {
2721    if (!this.submitter || !this.submitsWith) return;
2722    if (this.submitter.matches("button")) {
2723      this.originalSubmitText = this.submitter.innerHTML;
2724      this.submitter.innerHTML = this.submitsWith;
2725    } else if (this.submitter.matches("input")) {
2726      const input = this.submitter;
2727      this.originalSubmitText = input.value;
2728      input.value = this.submitsWith;
2729    }
2730  }
2731  resetSubmitterText() {
2732    if (!this.submitter || !this.originalSubmitText) return;
2733    if (this.submitter.matches("button")) {
2734      this.submitter.innerHTML = this.originalSubmitText;
2735    } else if (this.submitter.matches("input")) {
2736      const input = this.submitter;
2737      input.value = this.originalSubmitText;
2738    }
2739  }
2740  requestMustRedirect(request) {
2741    return !request.isSafe && this.mustRedirect;
2742  }
2743  requestAcceptsTurboStreamResponse(request) {
2744    return !request.isSafe || hasAttribute("data-turbo-stream", this.submitter, this.formElement);
2745  }
2746  get submitsWith() {
2747    return this.submitter?.getAttribute("data-turbo-submits-with");
2748  }
2749};
2750function buildFormData(formElement, submitter2) {
2751  const formData = new FormData(formElement);
2752  const name = submitter2?.getAttribute("name");
2753  const value = submitter2?.getAttribute("value");
2754  if (name) {
2755    formData.append(name, value || "");
2756  }
2757  return formData;
2758}
2759function getCookieValue(cookieName) {
2760  if (cookieName != null) {
2761    const cookies = document.cookie ? document.cookie.split("; ") : [];
2762    const cookie = cookies.find((cookie2) => cookie2.startsWith(cookieName));
2763    if (cookie) {
2764      const value = cookie.split("=").slice(1).join("=");
2765      return value ? decodeURIComponent(value) : void 0;
2766    }
2767  }
2768}
2769function responseSucceededWithoutRedirect(response) {
2770  return response.statusCode == 200 && !response.redirected;
2771}
2772function getFormAction(formElement, submitter2) {
2773  const formElementAction = typeof formElement.action === "string" ? formElement.action : null;
2774  if (submitter2?.hasAttribute("formaction")) {
2775    return submitter2.getAttribute("formaction") || "";
2776  } else {
2777    return formElement.getAttribute("action") || formElementAction || "";
2778  }
2779}
2780function getAction(formAction, fetchMethod) {
2781  const action = expandURL(formAction);
2782  if (isSafe(fetchMethod)) {
2783    action.search = "";
2784  }
2785  return action;
2786}
2787function getMethod(formElement, submitter2) {
2788  const method = submitter2?.getAttribute("formmethod") || formElement.getAttribute("method") || "";
2789  return fetchMethodFromString(method.toLowerCase()) || FetchMethod.get;
2790}
2791function getEnctype(formElement, submitter2) {
2792  return fetchEnctypeFromString(submitter2?.getAttribute("formenctype") || formElement.enctype);
2793}
2794var Snapshot = class {
2795  constructor(element) {
2796    this.element = element;
2797  }
2798  get activeElement() {
2799    return this.element.ownerDocument.activeElement;
2800  }
2801  get children() {
2802    return [...this.element.children];
2803  }
2804  hasAnchor(anchor) {
2805    return this.getElementForAnchor(anchor) != null;
2806  }
2807  getElementForAnchor(anchor) {
2808    return anchor ? this.element.querySelector(`[id='${anchor}'], a[name='${anchor}']`) : null;
2809  }
2810  get isConnected() {
2811    return this.element.isConnected;
2812  }
2813  get firstAutofocusableElement() {
2814    return queryAutofocusableElement(this.element);
2815  }
2816  get permanentElements() {
2817    return queryPermanentElementsAll(this.element);
2818  }
2819  getPermanentElementById(id) {
2820    return getPermanentElementById(this.element, id);
2821  }
2822  getPermanentElementMapForSnapshot(snapshot) {
2823    const permanentElementMap = {};
2824    for (const currentPermanentElement of this.permanentElements) {
2825      const { id } = currentPermanentElement;
2826      const newPermanentElement = snapshot.getPermanentElementById(id);
2827      if (newPermanentElement) {
2828        permanentElementMap[id] = [currentPermanentElement, newPermanentElement];
2829      }
2830    }
2831    return permanentElementMap;
2832  }
2833};
2834function getPermanentElementById(node, id) {
2835  return node.querySelector(`#${id}[data-turbo-permanent]`);
2836}
2837function queryPermanentElementsAll(node) {
2838  return node.querySelectorAll("[id][data-turbo-permanent]");
2839}
2840var FormSubmitObserver = class {
2841  started = false;
2842  constructor(delegate, eventTarget) {
2843    this.delegate = delegate;
2844    this.eventTarget = eventTarget;
2845  }
2846  start() {
2847    if (!this.started) {
2848      this.eventTarget.addEventListener("submit", this.submitCaptured, true);
2849      this.started = true;
2850    }
2851  }
2852  stop() {
2853    if (this.started) {
2854      this.eventTarget.removeEventListener("submit", this.submitCaptured, true);
2855      this.started = false;
2856    }
2857  }
2858  submitCaptured = () => {
2859    this.eventTarget.removeEventListener("submit", this.submitBubbled, false);
2860    this.eventTarget.addEventListener("submit", this.submitBubbled, false);
2861  };
2862  submitBubbled = (event) => {
2863    if (!event.defaultPrevented) {
2864      const form = event.target instanceof HTMLFormElement ? event.target : void 0;
2865      const submitter2 = event.submitter || void 0;
2866      if (form && submissionDoesNotDismissDialog(form, submitter2) && submissionDoesNotTargetIFrame(form, submitter2) && this.delegate.willSubmitForm(form, submitter2)) {
2867        event.preventDefault();
2868        event.stopImmediatePropagation();
2869        this.delegate.formSubmitted(form, submitter2);
2870      }
2871    }
2872  };
2873};
2874function submissionDoesNotDismissDialog(form, submitter2) {
2875  const method = submitter2?.getAttribute("formmethod") || form.getAttribute("method");
2876  return method != "dialog";
2877}
2878function submissionDoesNotTargetIFrame(form, submitter2) {
2879  const target = submitter2?.getAttribute("formtarget") || form.getAttribute("target");
2880  return doesNotTargetIFrame(target);
2881}
2882var View = class {
2883  #resolveRenderPromise = (_value) => {
2884  };
2885  #resolveInterceptionPromise = (_value) => {
2886  };
2887  constructor(delegate, element) {
2888    this.delegate = delegate;
2889    this.element = element;
2890  }
2891  // Scrolling
2892  scrollToAnchor(anchor) {
2893    const element = this.snapshot.getElementForAnchor(anchor);
2894    if (element) {
2895      this.scrollToElement(element);
2896      this.focusElement(element);
2897    } else {
2898      this.scrollToPosition({ x: 0, y: 0 });
2899    }
2900  }
2901  scrollToAnchorFromLocation(location2) {
2902    this.scrollToAnchor(getAnchor(location2));
2903  }
2904  scrollToElement(element) {
2905    element.scrollIntoView();
2906  }
2907  focusElement(element) {
2908    if (element instanceof HTMLElement) {
2909      if (element.hasAttribute("tabindex")) {
2910        element.focus();
2911      } else {
2912        element.setAttribute("tabindex", "-1");
2913        element.focus();
2914        element.removeAttribute("tabindex");
2915      }
2916    }
2917  }
2918  scrollToPosition({ x, y }) {
2919    this.scrollRoot.scrollTo(x, y);
2920  }
2921  scrollToTop() {
2922    this.scrollToPosition({ x: 0, y: 0 });
2923  }
2924  get scrollRoot() {
2925    return window;
2926  }
2927  // Rendering
2928  async render(renderer) {
2929    const { isPreview, shouldRender, willRender, newSnapshot: snapshot } = renderer;
2930    const shouldInvalidate = willRender;
2931    if (shouldRender) {
2932      try {
2933        this.renderPromise = new Promise((resolve) => this.#resolveRenderPromise = resolve);
2934        this.renderer = renderer;
2935        await this.prepareToRenderSnapshot(renderer);
2936        const renderInterception = new Promise((resolve) => this.#resolveInterceptionPromise = resolve);
2937        const options = { resume: this.#resolveInterceptionPromise, render: this.renderer.renderElement, renderMethod: this.renderer.renderMethod };
2938        const immediateRender = this.delegate.allowsImmediateRender(snapshot, options);
2939        if (!immediateRender) await renderInterception;
2940        await this.renderSnapshot(renderer);
2941        this.delegate.viewRenderedSnapshot(snapshot, isPreview, this.renderer.renderMethod);
2942        this.delegate.preloadOnLoadLinksForView(this.element);
2943        this.finishRenderingSnapshot(renderer);
2944      } finally {
2945        delete this.renderer;
2946        this.#resolveRenderPromise(void 0);
2947        delete this.renderPromise;
2948      }
2949    } else if (shouldInvalidate) {
2950      this.invalidate(renderer.reloadReason);
2951    }
2952  }
2953  invalidate(reason) {
2954    this.delegate.viewInvalidated(reason);
2955  }
2956  async prepareToRenderSnapshot(renderer) {
2957    this.markAsPreview(renderer.isPreview);
2958    await renderer.prepareToRender();
2959  }
2960  markAsPreview(isPreview) {
2961    if (isPreview) {
2962      this.element.setAttribute("data-turbo-preview", "");
2963    } else {
2964      this.element.removeAttribute("data-turbo-preview");
2965    }
2966  }
2967  markVisitDirection(direction) {
2968    this.element.setAttribute("data-turbo-visit-direction", direction);
2969  }
2970  unmarkVisitDirection() {
2971    this.element.removeAttribute("data-turbo-visit-direction");
2972  }
2973  async renderSnapshot(renderer) {
2974    await renderer.render();
2975  }
2976  finishRenderingSnapshot(renderer) {
2977    renderer.finishRendering();
2978  }
2979};
2980var FrameView = class extends View {
2981  missing() {
2982    this.element.innerHTML = `<strong class="turbo-frame-error">Content missing</strong>`;
2983  }
2984  get snapshot() {
2985    return new Snapshot(this.element);
2986  }
2987};
2988var LinkInterceptor = class {
2989  constructor(delegate, element) {
2990    this.delegate = delegate;
2991    this.element = element;
2992  }
2993  start() {
2994    this.element.addEventListener("click", this.clickBubbled);
2995    document.addEventListener("turbo:click", this.linkClicked);
2996    document.addEventListener("turbo:before-visit", this.willVisit);
2997  }
2998  stop() {
2999    this.element.removeEventListener("click", this.clickBubbled);
3000    document.removeEventListener("turbo:click", this.linkClicked);
3001    document.removeEventListener("turbo:before-visit", this.willVisit);
3002  }
3003  clickBubbled = (event) => {
3004    if (this.clickEventIsSignificant(event)) {
3005      this.clickEvent = event;
3006    } else {
3007      delete this.clickEvent;
3008    }
3009  };
3010  linkClicked = (event) => {
3011    if (this.clickEvent && this.clickEventIsSignificant(event)) {
3012      if (this.delegate.shouldInterceptLinkClick(event.target, event.detail.url, event.detail.originalEvent)) {
3013        this.clickEvent.preventDefault();
3014        event.preventDefault();
3015        this.delegate.linkClickIntercepted(event.target, event.detail.url, event.detail.originalEvent);
3016      }
3017    }
3018    delete this.clickEvent;
3019  };
3020  willVisit = (_event) => {
3021    delete this.clickEvent;
3022  };
3023  clickEventIsSignificant(event) {
3024    const target = event.composed ? event.target?.parentElement : event.target;
3025    const element = findLinkFromClickTarget(target) || target;
3026    return element instanceof Element && element.closest("turbo-frame, html") == this.element;
3027  }
3028};
3029var LinkClickObserver = class {
3030  started = false;
3031  constructor(delegate, eventTarget) {
3032    this.delegate = delegate;
3033    this.eventTarget = eventTarget;
3034  }
3035  start() {
3036    if (!this.started) {
3037      this.eventTarget.addEventListener("click", this.clickCaptured, true);
3038      this.started = true;
3039    }
3040  }
3041  stop() {
3042    if (this.started) {
3043      this.eventTarget.removeEventListener("click", this.clickCaptured, true);
3044      this.started = false;
3045    }
3046  }
3047  clickCaptured = () => {
3048    this.eventTarget.removeEventListener("click", this.clickBubbled, false);
3049    this.eventTarget.addEventListener("click", this.clickBubbled, false);
3050  };
3051  clickBubbled = (event) => {
3052    if (event instanceof MouseEvent && this.clickEventIsSignificant(event)) {
3053      const target = event.composedPath && event.composedPath()[0] || event.target;
3054      const link = findLinkFromClickTarget(target);
3055      if (link && doesNotTargetIFrame(link.target)) {
3056        const location2 = getLocationForLink(link);
3057        if (this.delegate.willFollowLinkToLocation(link, location2, event)) {
3058          event.preventDefault();
3059          this.delegate.followedLinkToLocation(link, location2);
3060        }
3061      }
3062    }
3063  };
3064  clickEventIsSignificant(event) {
3065    return !(event.target && event.target.isContentEditable || event.defaultPrevented || event.which > 1 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey);
3066  }
3067};
3068var FormLinkClickObserver = class {
3069  constructor(delegate, element) {
3070    this.delegate = delegate;
3071    this.linkInterceptor = new LinkClickObserver(this, element);
3072  }
3073  start() {
3074    this.linkInterceptor.start();
3075  }
3076  stop() {
3077    this.linkInterceptor.stop();
3078  }
3079  // Link hover observer delegate
3080  canPrefetchRequestToLocation(link, location2) {
3081    return false;
3082  }
3083  prefetchAndCacheRequestToLocation(link, location2) {
3084    return;
3085  }
3086  // Link click observer delegate
3087  willFollowLinkToLocation(link, location2, originalEvent) {
3088    return this.delegate.willSubmitFormLinkToLocation(link, location2, originalEvent) && (link.hasAttribute("data-turbo-method") || link.hasAttribute("data-turbo-stream"));
3089  }
3090  followedLinkToLocation(link, location2) {
3091    const form = document.createElement("form");
3092    const type = "hidden";
3093    for (const [name, value] of location2.searchParams) {
3094      form.append(Object.assign(document.createElement("input"), { type, name, value }));
3095    }
3096    const action = Object.assign(location2, { search: "" });
3097    form.setAttribute("data-turbo", "true");
3098    form.setAttribute("action", action.href);
3099    form.setAttribute("hidden", "");
3100    const method = link.getAttribute("data-turbo-method");
3101    if (method) form.setAttribute("method", method);
3102    const turboFrame = link.getAttribute("data-turbo-frame");
3103    if (turboFrame) form.setAttribute("data-turbo-frame", turboFrame);
3104    const turboAction = getVisitAction(link);
3105    if (turboAction) form.setAttribute("data-turbo-action", turboAction);
3106    const turboConfirm = link.getAttribute("data-turbo-confirm");
3107    if (turboConfirm) form.setAttribute("data-turbo-confirm", turboConfirm);
3108    const turboStream = link.hasAttribute("data-turbo-stream");
3109    if (turboStream) form.setAttribute("data-turbo-stream", "");
3110    this.delegate.submittedFormLinkToLocation(link, location2, form);
3111    document.body.appendChild(form);
3112    form.addEventListener("turbo:submit-end", () => form.remove(), { once: true });
3113    requestAnimationFrame(() => form.requestSubmit());
3114  }
3115};
3116var Bardo = class {
3117  static async preservingPermanentElements(delegate, permanentElementMap, callback) {
3118    const bardo = new this(delegate, permanentElementMap);
3119    bardo.enter();
3120    await callback();
3121    bardo.leave();
3122  }
3123  constructor(delegate, permanentElementMap) {
3124    this.delegate = delegate;
3125    this.permanentElementMap = permanentElementMap;
3126  }
3127  enter() {
3128    for (const id in this.permanentElementMap) {
3129      const [currentPermanentElement, newPermanentElement] = this.permanentElementMap[id];
3130      this.delegate.enteringBardo(currentPermanentElement, newPermanentElement);
3131      this.replaceNewPermanentElementWithPlaceholder(newPermanentElement);
3132    }
3133  }
3134  leave() {
3135    for (const id in this.permanentElementMap) {
3136      const [currentPermanentElement] = this.permanentElementMap[id];
3137      this.replaceCurrentPermanentElementWithClone(currentPermanentElement);
3138      this.replacePlaceholderWithPermanentElement(currentPermanentElement);
3139      this.delegate.leavingBardo(currentPermanentElement);
3140    }
3141  }
3142  replaceNewPermanentElementWithPlaceholder(permanentElement) {
3143    const placeholder = createPlaceholderForPermanentElement(permanentElement);
3144    permanentElement.replaceWith(placeholder);
3145  }
3146  replaceCurrentPermanentElementWithClone(permanentElement) {
3147    const clone = permanentElement.cloneNode(true);
3148    permanentElement.replaceWith(clone);
3149  }
3150  replacePlaceholderWithPermanentElement(permanentElement) {
3151    const placeholder = this.getPlaceholderById(permanentElement.id);
3152    placeholder?.replaceWith(permanentElement);
3153  }
3154  getPlaceholderById(id) {
3155    return this.placeholders.find((element) => element.content == id);
3156  }
3157  get placeholders() {
3158    return [...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")];
3159  }
3160};
3161function createPlaceholderForPermanentElement(permanentElement) {
3162  const element = document.createElement("meta");
3163  element.setAttribute("name", "turbo-permanent-placeholder");
3164  element.setAttribute("content", permanentElement.id);
3165  return element;
3166}
3167var Renderer = class {
3168  #activeElement = null;
3169  static renderElement(currentElement, newElement) {
3170  }
3171  constructor(currentSnapshot, newSnapshot, isPreview, willRender = true) {
3172    this.currentSnapshot = currentSnapshot;
3173    this.newSnapshot = newSnapshot;
3174    this.isPreview = isPreview;
3175    this.willRender = willRender;
3176    this.renderElement = this.constructor.renderElement;
3177    this.promise = new Promise((resolve, reject) => this.resolvingFunctions = { resolve, reject });
3178  }
3179  get shouldRender() {
3180    return true;
3181  }
3182  get shouldAutofocus() {
3183    return true;
3184  }
3185  get reloadReason() {
3186    return;
3187  }
3188  prepareToRender() {
3189    return;
3190  }
3191  render() {
3192  }
3193  finishRendering() {
3194    if (this.resolvingFunctions) {
3195      this.resolvingFunctions.resolve();
3196      delete this.resolvingFunctions;
3197    }
3198  }
3199  async preservingPermanentElements(callback) {
3200    await Bardo.preservingPermanentElements(this, this.permanentElementMap, callback);
3201  }
3202  focusFirstAutofocusableElement() {
3203    if (this.shouldAutofocus) {
3204      const element = this.connectedSnapshot.firstAutofocusableElement;
3205      if (element) {
3206        element.focus();
3207      }
3208    }
3209  }
3210  // Bardo delegate
3211  enteringBardo(currentPermanentElement) {
3212    if (this.#activeElement) return;
3213    if (currentPermanentElement.contains(this.currentSnapshot.activeElement)) {
3214      this.#activeElement = this.currentSnapshot.activeElement;
3215    }
3216  }
3217  leavingBardo(currentPermanentElement) {
3218    if (currentPermanentElement.contains(this.#activeElement) && this.#activeElement instanceof HTMLElement) {
3219      this.#activeElement.focus();
3220      this.#activeElement = null;
3221    }
3222  }
3223  get connectedSnapshot() {
3224    return this.newSnapshot.isConnected ? this.newSnapshot : this.currentSnapshot;
3225  }
3226  get currentElement() {
3227    return this.currentSnapshot.element;
3228  }
3229  get newElement() {
3230    return this.newSnapshot.element;
3231  }
3232  get permanentElementMap() {
3233    return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot);
3234  }
3235  get renderMethod() {
3236    return "replace";
3237  }
3238};
3239var FrameRenderer = class extends Renderer {
3240  static renderElement(currentElement, newElement) {
3241    const destinationRange = document.createRange();
3242    destinationRange.selectNodeContents(currentElement);
3243    destinationRange.deleteContents();
3244    const frameElement = newElement;
3245    const sourceRange = frameElement.ownerDocument?.createRange();
3246    if (sourceRange) {
3247      sourceRange.selectNodeContents(frameElement);
3248      currentElement.appendChild(sourceRange.extractContents());
3249    }
3250  }
3251  constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {
3252    super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender);
3253    this.delegate = delegate;
3254  }
3255  get shouldRender() {
3256    return true;
3257  }
3258  async render() {
3259    await nextRepaint();
3260    this.preservingPermanentElements(() => {
3261      this.loadFrameElement();
3262    });
3263    this.scrollFrameIntoView();
3264    await nextRepaint();
3265    this.focusFirstAutofocusableElement();
3266    await nextRepaint();
3267    this.activateScriptElements();
3268  }
3269  loadFrameElement() {
3270    this.delegate.willRenderFrame(this.currentElement, this.newElement);
3271    this.renderElement(this.currentElement, this.newElement);
3272  }
3273  scrollFrameIntoView() {
3274    if (this.currentElement.autoscroll || this.newElement.autoscroll) {
3275      const element = this.currentElement.firstElementChild;
3276      const block = readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"), "end");
3277      const behavior = readScrollBehavior(this.currentElement.getAttribute("data-autoscroll-behavior"), "auto");
3278      if (element) {
3279        element.scrollIntoView({ block, behavior });
3280        return true;
3281      }
3282    }
3283    return false;
3284  }
3285  activateScriptElements() {
3286    for (const inertScriptElement of this.newScriptElements) {
3287      const activatedScriptElement = activateScriptElement(inertScriptElement);
3288      inertScriptElement.replaceWith(activatedScriptElement);
3289    }
3290  }
3291  get newScriptElements() {
3292    return this.currentElement.querySelectorAll("script");
3293  }
3294};
3295function readScrollLogicalPosition(value, defaultValue) {
3296  if (value == "end" || value == "start" || value == "center" || value == "nearest") {
3297    return value;
3298  } else {
3299    return defaultValue;
3300  }
3301}
3302function readScrollBehavior(value, defaultValue) {
3303  if (value == "auto" || value == "smooth") {
3304    return value;
3305  } else {
3306    return defaultValue;
3307  }
3308}
3309var Idiomorph = /* @__PURE__ */ function() {
3310  let EMPTY_SET = /* @__PURE__ */ new Set();
3311  let defaults = {
3312    morphStyle: "outerHTML",
3313    callbacks: {
3314      beforeNodeAdded: noOp,
3315      afterNodeAdded: noOp,
3316      beforeNodeMorphed: noOp,
3317      afterNodeMorphed: noOp,
3318      beforeNodeRemoved: noOp,
3319      afterNodeRemoved: noOp,
3320      beforeAttributeUpdated: noOp
3321    },
3322    head: {
3323      style: "merge",
3324      shouldPreserve: function(elt) {
3325        return elt.getAttribute("im-preserve") === "true";
3326      },
3327      shouldReAppend: function(elt) {
3328        return elt.getAttribute("im-re-append") === "true";
3329      },
3330      shouldRemove: noOp,
3331      afterHeadMorphed: noOp
3332    }
3333  };
3334  function morph(oldNode, newContent, config2 = {}) {
3335    if (oldNode instanceof Document) {
3336      oldNode = oldNode.documentElement;
3337    }
3338    if (typeof newContent === "string") {
3339      newContent = parseContent(newContent);
3340    }
3341    let normalizedContent = normalizeContent(newContent);
3342    let ctx = createMorphContext(oldNode, normalizedContent, config2);
3343    return morphNormalizedContent(oldNode, normalizedContent, ctx);
3344  }
3345  function morphNormalizedContent(oldNode, normalizedNewContent, ctx) {
3346    if (ctx.head.block) {
3347      let oldHead = oldNode.querySelector("head");
3348      let newHead = normalizedNewContent.querySelector("head");
3349      if (oldHead && newHead) {
3350        let promises = handleHeadElement(newHead, oldHead, ctx);
3351        Promise.all(promises).then(function() {
3352          morphNormalizedContent(oldNode, normalizedNewContent, Object.assign(ctx, {
3353            head: {
3354              block: false,
3355              ignore: true
3356            }
3357          }));
3358        });
3359        return;
3360      }
3361    }
3362    if (ctx.morphStyle === "innerHTML") {
3363      morphChildren2(normalizedNewContent, oldNode, ctx);
3364      return oldNode.children;
3365    } else if (ctx.morphStyle === "outerHTML" || ctx.morphStyle == null) {
3366      let bestMatch = findBestNodeMatch(normalizedNewContent, oldNode, ctx);
3367      let previousSibling = bestMatch?.previousSibling;
3368      let nextSibling = bestMatch?.nextSibling;
3369      let morphedNode = morphOldNodeTo(oldNode, bestMatch, ctx);
3370      if (bestMatch) {
3371        return insertSiblings(previousSibling, morphedNode, nextSibling);
3372      } else {
3373        return [];
3374      }
3375    } else {
3376      throw "Do not understand how to morph style " + ctx.morphStyle;
3377    }
3378  }
3379  function ignoreValueOfActiveElement(possibleActiveElement, ctx) {
3380    return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;
3381  }
3382  function morphOldNodeTo(oldNode, newContent, ctx) {
3383    if (ctx.ignoreActive && oldNode === document.activeElement) ;
3384    else if (newContent == null) {
3385      if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;
3386      oldNode.remove();
3387      ctx.callbacks.afterNodeRemoved(oldNode);
3388      return null;
3389    } else if (!isSoftMatch(oldNode, newContent)) {
3390      if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;
3391      if (ctx.callbacks.beforeNodeAdded(newContent) === false) return oldNode;
3392      oldNode.parentElement.replaceChild(newContent, oldNode);
3393      ctx.callbacks.afterNodeAdded(newContent);
3394      ctx.callbacks.afterNodeRemoved(oldNode);
3395      return newContent;
3396    } else {
3397      if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return oldNode;
3398      if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) ;
3399      else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== "morph") {
3400        handleHeadElement(newContent, oldNode, ctx);
3401      } else {
3402        syncNodeFrom(newContent, oldNode, ctx);
3403        if (!ignoreValueOfActiveElement(oldNode, ctx)) {
3404          morphChildren2(newContent, oldNode, ctx);
3405        }
3406      }
3407      ctx.callbacks.afterNodeMorphed(oldNode, newContent);
3408      return oldNode;
3409    }
3410  }
3411  function morphChildren2(newParent, oldParent, ctx) {
3412    let nextNewChild = newParent.firstChild;
3413    let insertionPoint = oldParent.firstChild;
3414    let newChild;
3415    while (nextNewChild) {
3416      newChild = nextNewChild;
3417      nextNewChild = newChild.nextSibling;
3418      if (insertionPoint == null) {
3419        if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;
3420        oldParent.appendChild(newChild);
3421        ctx.callbacks.afterNodeAdded(newChild);
3422        removeIdsFromConsideration(ctx, newChild);
3423        continue;
3424      }
3425      if (isIdSetMatch(newChild, insertionPoint, ctx)) {
3426        morphOldNodeTo(insertionPoint, newChild, ctx);
3427        insertionPoint = insertionPoint.nextSibling;
3428        removeIdsFromConsideration(ctx, newChild);
3429        continue;
3430      }
3431      let idSetMatch = findIdSetMatch(newParent, oldParent, newChild, insertionPoint, ctx);
3432      if (idSetMatch) {
3433        insertionPoint = removeNodesBetween(insertionPoint, idSetMatch, ctx);
3434        morphOldNodeTo(idSetMatch, newChild, ctx);
3435        removeIdsFromConsideration(ctx, newChild);
3436        continue;
3437      }
3438      let softMatch = findSoftMatch(newParent, oldParent, newChild, insertionPoint, ctx);
3439      if (softMatch) {
3440        insertionPoint = removeNodesBetween(insertionPoint, softMatch, ctx);
3441        morphOldNodeTo(softMatch, newChild, ctx);
3442        removeIdsFromConsideration(ctx, newChild);
3443        continue;
3444      }
3445      if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;
3446      oldParent.insertBefore(newChild, insertionPoint);
3447      ctx.callbacks.afterNodeAdded(newChild);
3448      removeIdsFromConsideration(ctx, newChild);
3449    }
3450    while (insertionPoint !== null) {
3451      let tempNode = insertionPoint;
3452      insertionPoint = insertionPoint.nextSibling;
3453      removeNode(tempNode, ctx);
3454    }
3455  }
3456  function ignoreAttribute(attr, to, updateType, ctx) {
3457    if (attr === "value" && ctx.ignoreActiveValue && to === document.activeElement) {
3458      return true;
3459    }
3460    return ctx.callbacks.beforeAttributeUpdated(attr, to, updateType) === false;
3461  }
3462  function syncNodeFrom(from, to, ctx) {
3463    let type = from.nodeType;
3464    if (type === 1) {
3465      const fromAttributes = from.attributes;
3466      const toAttributes = to.attributes;
3467      for (const fromAttribute of fromAttributes) {
3468        if (ignoreAttribute(fromAttribute.name, to, "update", ctx)) {
3469          continue;
3470        }
3471        if (to.getAttribute(fromAttribute.name) !== fromAttribute.value) {
3472          to.setAttribute(fromAttribute.name, fromAttribute.value);
3473        }
3474      }
3475      for (let i = toAttributes.length - 1; 0 <= i; i--) {
3476        const toAttribute = toAttributes[i];
3477        if (ignoreAttribute(toAttribute.name, to, "remove", ctx)) {
3478          continue;
3479        }
3480        if (!from.hasAttribute(toAttribute.name)) {
3481          to.removeAttribute(toAttribute.name);
3482        }
3483      }
3484    }
3485    if (type === 8 || type === 3) {
3486      if (to.nodeValue !== from.nodeValue) {
3487        to.nodeValue = from.nodeValue;
3488      }
3489    }
3490    if (!ignoreValueOfActiveElement(to, ctx)) {
3491      syncInputValue(from, to, ctx);
3492    }
3493  }
3494  function syncBooleanAttribute(from, to, attributeName, ctx) {
3495    if (from[attributeName] !== to[attributeName]) {
3496      let ignoreUpdate = ignoreAttribute(attributeName, to, "update", ctx);
3497      if (!ignoreUpdate) {
3498        to[attributeName] = from[attributeName];
3499      }
3500      if (from[attributeName]) {
3501        if (!ignoreUpdate) {
3502          to.setAttribute(attributeName, from[attributeName]);
3503        }
3504      } else {
3505        if (!ignoreAttribute(attributeName, to, "remove", ctx)) {
3506          to.removeAttribute(attributeName);
3507        }
3508      }
3509    }
3510  }
3511  function syncInputValue(from, to, ctx) {
3512    if (from instanceof HTMLInputElement && to instanceof HTMLInputElement && from.type !== "file") {
3513      let fromValue = from.value;
3514      let toValue = to.value;
3515      syncBooleanAttribute(from, to, "checked", ctx);
3516      syncBooleanAttribute(from, to, "disabled", ctx);
3517      if (!from.hasAttribute("value")) {
3518        if (!ignoreAttribute("value", to, "remove", ctx)) {
3519          to.value = "";
3520          to.removeAttribute("value");
3521        }
3522      } else if (fromValue !== toValue) {
3523        if (!ignoreAttribute("value", to, "update", ctx)) {
3524          to.setAttribute("value", fromValue);
3525          to.value = fromValue;
3526        }
3527      }
3528    } else if (from instanceof HTMLOptionElement) {
3529      syncBooleanAttribute(from, to, "selected", ctx);
3530    } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) {
3531      let fromValue = from.value;
3532      let toValue = to.value;
3533      if (ignoreAttribute("value", to, "update", ctx)) {
3534        return;
3535      }
3536      if (fromValue !== toValue) {
3537        to.value = fromValue;
3538      }
3539      if (to.firstChild && to.firstChild.nodeValue !== fromValue) {
3540        to.firstChild.nodeValue = fromValue;
3541      }
3542    }
3543  }
3544  function handleHeadElement(newHeadTag, currentHead, ctx) {
3545    let added = [];
3546    let removed = [];
3547    let preserved = [];
3548    let nodesToAppend = [];
3549    let headMergeStyle = ctx.head.style;
3550    let srcToNewHeadNodes = /* @__PURE__ */ new Map();
3551    for (const newHeadChild of newHeadTag.children) {
3552      srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);
3553    }
3554    for (const currentHeadElt of currentHead.children) {
3555      let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);
3556      let isReAppended = ctx.head.shouldReAppend(currentHeadElt);
3557      let isPreserved = ctx.head.shouldPreserve(currentHeadElt);
3558      if (inNewContent || isPreserved) {
3559        if (isReAppended) {
3560          removed.push(currentHeadElt);
3561        } else {
3562          srcToNewHeadNodes.delete(currentHeadElt.outerHTML);
3563          preserved.push(currentHeadElt);
3564        }
3565      } else {
3566        if (headMergeStyle === "append") {
3567          if (isReAppended) {
3568            removed.push(currentHeadElt);
3569            nodesToAppend.push(currentHeadElt);
3570          }
3571        } else {
3572          if (ctx.head.shouldRemove(currentHeadElt) !== false) {
3573            removed.push(currentHeadElt);
3574          }
3575        }
3576      }
3577    }
3578    nodesToAppend.push(...srcToNewHeadNodes.values());
3579    let promises = [];
3580    for (const newNode of nodesToAppend) {
3581      let newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild;
3582      if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {
3583        if (newElt.href || newElt.src) {
3584          let resolve = null;
3585          let promise = new Promise(function(_resolve) {
3586            resolve = _resolve;
3587          });
3588          newElt.addEventListener("load", function() {
3589            resolve();
3590          });
3591          promises.push(promise);
3592        }
3593        currentHead.appendChild(newElt);
3594        ctx.callbacks.afterNodeAdded(newElt);
3595        added.push(newElt);
3596      }
3597    }
3598    for (const removedElement of removed) {
3599      if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {
3600        currentHead.removeChild(removedElement);
3601        ctx.callbacks.afterNodeRemoved(removedElement);
3602      }
3603    }
3604    ctx.head.afterHeadMorphed(currentHead, { added, kept: preserved, removed });
3605    return promises;
3606  }
3607  function noOp() {
3608  }
3609  function mergeDefaults(config2) {
3610    let finalConfig = {};
3611    Object.assign(finalConfig, defaults);
3612    Object.assign(finalConfig, config2);
3613    finalConfig.callbacks = {};
3614    Object.assign(finalConfig.callbacks, defaults.callbacks);
3615    Object.assign(finalConfig.callbacks, config2.callbacks);
3616    finalConfig.head = {};
3617    Object.assign(finalConfig.head, defaults.head);
3618    Object.assign(finalConfig.head, config2.head);
3619    return finalConfig;
3620  }
3621  function createMorphContext(oldNode, newContent, config2) {
3622    config2 = mergeDefaults(config2);
3623    return {
3624      target: oldNode,
3625      newContent,
3626      config: config2,
3627      morphStyle: config2.morphStyle,
3628      ignoreActive: config2.ignoreActive,
3629      ignoreActiveValue: config2.ignoreActiveValue,
3630      idMap: createIdMap(oldNode, newContent),
3631      deadIds: /* @__PURE__ */ new Set(),
3632      callbacks: config2.callbacks,
3633      head: config2.head
3634    };
3635  }
3636  function isIdSetMatch(node1, node2, ctx) {
3637    if (node1 == null || node2 == null) {
3638      return false;
3639    }
3640    if (node1.nodeType === node2.nodeType && node1.tagName === node2.tagName) {
3641      if (node1.id !== "" && node1.id === node2.id) {
3642        return true;
3643      } else {
3644        return getIdIntersectionCount(ctx, node1, node2) > 0;
3645      }
3646    }
3647    return false;
3648  }
3649  function isSoftMatch(node1, node2) {
3650    if (node1 == null || node2 == null) {
3651      return false;
3652    }
3653    return node1.nodeType === node2.nodeType && node1.tagName === node2.tagName;
3654  }
3655  function removeNodesBetween(startInclusive, endExclusive, ctx) {
3656    while (startInclusive !== endExclusive) {
3657      let tempNode = startInclusive;
3658      startInclusive = startInclusive.nextSibling;
3659      removeNode(tempNode, ctx);
3660    }
3661    removeIdsFromConsideration(ctx, endExclusive);
3662    return endExclusive.nextSibling;
3663  }
3664  function findIdSetMatch(newContent, oldParent, newChild, insertionPoint, ctx) {
3665    let newChildPotentialIdCount = getIdIntersectionCount(ctx, newChild, oldParent);
3666    let potentialMatch = null;
3667    if (newChildPotentialIdCount > 0) {
3668      let potentialMatch2 = insertionPoint;
3669      let otherMatchCount = 0;
3670      while (potentialMatch2 != null) {
3671        if (isIdSetMatch(newChild, potentialMatch2, ctx)) {
3672          return potentialMatch2;
3673        }
3674        otherMatchCount += getIdIntersectionCount(ctx, potentialMatch2, newContent);
3675        if (otherMatchCount > newChildPotentialIdCount) {
3676          return null;
3677        }
3678        potentialMatch2 = potentialMatch2.nextSibling;
3679      }
3680    }
3681    return potentialMatch;
3682  }
3683  function findSoftMatch(newContent, oldParent, newChild, insertionPoint, ctx) {
3684    let potentialSoftMatch = insertionPoint;
3685    let nextSibling = newChild.nextSibling;
3686    let siblingSoftMatchCount = 0;
3687    while (potentialSoftMatch != null) {
3688      if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) {
3689        return null;
3690      }
3691      if (isSoftMatch(newChild, potentialSoftMatch)) {
3692        return potentialSoftMatch;
3693      }
3694      if (isSoftMatch(nextSibling, potentialSoftMatch)) {
3695        siblingSoftMatchCount++;
3696        nextSibling = nextSibling.nextSibling;
3697        if (siblingSoftMatchCount >= 2) {
3698          return null;
3699        }
3700      }
3701      potentialSoftMatch = potentialSoftMatch.nextSibling;
3702    }
3703    return potentialSoftMatch;
3704  }
3705  function parseContent(newContent) {
3706    let parser = new DOMParser();
3707    let contentWithSvgsRemoved = newContent.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim, "");
3708    if (contentWithSvgsRemoved.match(/<\/html>/) || contentWithSvgsRemoved.match(/<\/head>/) || contentWithSvgsRemoved.match(/<\/body>/)) {
3709      let content = parser.parseFromString(newContent, "text/html");
3710      if (contentWithSvgsRemoved.match(/<\/html>/)) {
3711        content.generatedByIdiomorph = true;
3712        return content;
3713      } else {
3714        let htmlElement = content.firstChild;
3715        if (htmlElement) {
3716          htmlElement.generatedByIdiomorph = true;
3717          return htmlElement;
3718        } else {
3719          return null;
3720        }
3721      }
3722    } else {
3723      let responseDoc = parser.parseFromString("<body><template>" + newContent + "</template></body>", "text/html");
3724      let content = responseDoc.body.querySelector("template").content;
3725      content.generatedByIdiomorph = true;
3726      return content;
3727    }
3728  }
3729  function normalizeContent(newContent) {
3730    if (newContent == null) {
3731      const dummyParent = document.createElement("div");
3732      return dummyParent;
3733    } else if (newContent.generatedByIdiomorph) {
3734      return newContent;
3735    } else if (newContent instanceof Node) {
3736      const dummyParent = document.createElement("div");
3737      dummyParent.append(newContent);
3738      return dummyParent;
3739    } else {
3740      const dummyParent = document.createElement("div");
3741      for (const elt of [...newContent]) {
3742        dummyParent.append(elt);
3743      }
3744      return dummyParent;
3745    }
3746  }
3747  function insertSiblings(previousSibling, morphedNode, nextSibling) {
3748    let stack = [];
3749    let added = [];
3750    while (previousSibling != null) {
3751      stack.push(previousSibling);
3752      previousSibling = previousSibling.previousSibling;
3753    }
3754    while (stack.length > 0) {
3755      let node = stack.pop();
3756      added.push(node);
3757      morphedNode.parentElement.insertBefore(node, morphedNode);
3758    }
3759    added.push(morphedNode);
3760    while (nextSibling != null) {
3761      stack.push(nextSibling);
3762      added.push(nextSibling);
3763      nextSibling = nextSibling.nextSibling;
3764    }
3765    while (stack.length > 0) {
3766      morphedNode.parentElement.insertBefore(stack.pop(), morphedNode.nextSibling);
3767    }
3768    return added;
3769  }
3770  function findBestNodeMatch(newContent, oldNode, ctx) {
3771    let currentElement;
3772    currentElement = newContent.firstChild;
3773    let bestElement = currentElement;
3774    let score = 0;
3775    while (currentElement) {
3776      let newScore = scoreElement(currentElement, oldNode, ctx);
3777      if (newScore > score) {
3778        bestElement = currentElement;
3779        score = newScore;
3780      }
3781      currentElement = currentElement.nextSibling;
3782    }
3783    return bestElement;
3784  }
3785  function scoreElement(node1, node2, ctx) {
3786    if (isSoftMatch(node1, node2)) {
3787      return 0.5 + getIdIntersectionCount(ctx, node1, node2);
3788    }
3789    return 0;
3790  }
3791  function removeNode(tempNode, ctx) {
3792    removeIdsFromConsideration(ctx, tempNode);
3793    if (ctx.callbacks.beforeNodeRemoved(tempNode) === false) return;
3794    tempNode.remove();
3795    ctx.callbacks.afterNodeRemoved(tempNode);
3796  }
3797  function isIdInConsideration(ctx, id) {
3798    return !ctx.deadIds.has(id);
3799  }
3800  function idIsWithinNode(ctx, id, targetNode) {
3801    let idSet = ctx.idMap.get(targetNode) || EMPTY_SET;
3802    return idSet.has(id);
3803  }
3804  function removeIdsFromConsideration(ctx, node) {
3805    let idSet = ctx.idMap.get(node) || EMPTY_SET;
3806    for (const id of idSet) {
3807      ctx.deadIds.add(id);
3808    }
3809  }
3810  function getIdIntersectionCount(ctx, node1, node2) {
3811    let sourceSet = ctx.idMap.get(node1) || EMPTY_SET;
3812    let matchCount = 0;
3813    for (const id of sourceSet) {
3814      if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) {
3815        ++matchCount;
3816      }
3817    }
3818    return matchCount;
3819  }
3820  function populateIdMapForNode(node, idMap) {
3821    let nodeParent = node.parentElement;
3822    let idElements = node.querySelectorAll("[id]");
3823    for (const elt of idElements) {
3824      let current = elt;
3825      while (current !== nodeParent && current != null) {
3826        let idSet = idMap.get(current);
3827        if (idSet == null) {
3828          idSet = /* @__PURE__ */ new Set();
3829          idMap.set(current, idSet);
3830        }
3831        idSet.add(elt.id);
3832        current = current.parentElement;
3833      }
3834    }
3835  }
3836  function createIdMap(oldContent, newContent) {
3837    let idMap = /* @__PURE__ */ new Map();
3838    populateIdMapForNode(oldContent, idMap);
3839    populateIdMapForNode(newContent, idMap);
3840    return idMap;
3841  }
3842  return {
3843    morph,
3844    defaults
3845  };
3846}();
3847function morphElements(currentElement, newElement, { callbacks, ...options } = {}) {
3848  Idiomorph.morph(currentElement, newElement, {
3849    ...options,
3850    callbacks: new DefaultIdiomorphCallbacks(callbacks)
3851  });
3852}
3853function morphChildren(currentElement, newElement) {
3854  morphElements(currentElement, newElement.children, {
3855    morphStyle: "innerHTML"
3856  });
3857}
3858var DefaultIdiomorphCallbacks = class {
3859  #beforeNodeMorphed;
3860  constructor({ beforeNodeMorphed } = {}) {
3861    this.#beforeNodeMorphed = beforeNodeMorphed || (() => true);
3862  }
3863  beforeNodeAdded = (node) => {
3864    return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id));
3865  };
3866  beforeNodeMorphed = (currentElement, newElement) => {
3867    if (currentElement instanceof Element) {
3868      if (!currentElement.hasAttribute("data-turbo-permanent") && this.#beforeNodeMorphed(currentElement, newElement)) {
3869        const event = dispatch("turbo:before-morph-element", {
3870          cancelable: true,
3871          target: currentElement,
3872          detail: { currentElement, newElement }
3873        });
3874        return !event.defaultPrevented;
3875      } else {
3876        return false;
3877      }
3878    }
3879  };
3880  beforeAttributeUpdated = (attributeName, target, mutationType) => {
3881    const event = dispatch("turbo:before-morph-attribute", {
3882      cancelable: true,
3883      target,
3884      detail: { attributeName, mutationType }
3885    });
3886    return !event.defaultPrevented;
3887  };
3888  beforeNodeRemoved = (node) => {
3889    return this.beforeNodeMorphed(node);
3890  };
3891  afterNodeMorphed = (currentElement, newElement) => {
3892    if (currentElement instanceof Element) {
3893      dispatch("turbo:morph-element", {
3894        target: currentElement,
3895        detail: { currentElement, newElement }
3896      });
3897    }
3898  };
3899};
3900var MorphingFrameRenderer = class extends FrameRenderer {
3901  static renderElement(currentElement, newElement) {
3902    dispatch("turbo:before-frame-morph", {
3903      target: currentElement,
3904      detail: { currentElement, newElement }
3905    });
3906    morphChildren(currentElement, newElement);
3907  }
3908  async preservingPermanentElements(callback) {
3909    return await callback();
3910  }
3911};
3912var ProgressBar = class _ProgressBar {
3913  static animationDuration = 300;
3914  /*ms*/
3915  static get defaultCSS() {
3916    return unindent`
3917      .turbo-progress-bar {
3918        position: fixed;
3919        display: block;
3920        top: 0;
3921        left: 0;
3922        height: 3px;
3923        background: #0076ff;
3924        z-index: 2147483647;
3925        transition:
3926          width ${_ProgressBar.animationDuration}ms ease-out,
3927          opacity ${_ProgressBar.animationDuration / 2}ms ${_ProgressBar.animationDuration / 2}ms ease-in;
3928        transform: translate3d(0, 0, 0);
3929      }
3930    `;
3931  }
3932  hiding = false;
3933  value = 0;
3934  visible = false;
3935  constructor() {
3936    this.stylesheetElement = this.createStylesheetElement();
3937    this.progressElement = this.createProgressElement();
3938    this.installStylesheetElement();
3939    this.setValue(0);
3940  }
3941  show() {
3942    if (!this.visible) {
3943      this.visible = true;
3944      this.installProgressElement();
3945      this.startTrickling();
3946    }
3947  }
3948  hide() {
3949    if (this.visible && !this.hiding) {
3950      this.hiding = true;
3951      this.fadeProgressElement(() => {
3952        this.uninstallProgressElement();
3953        this.stopTrickling();
3954        this.visible = false;
3955        this.hiding = false;
3956      });
3957    }
3958  }
3959  setValue(value) {
3960    this.value = value;
3961    this.refresh();
3962  }
3963  // Private
3964  installStylesheetElement() {
3965    document.head.insertBefore(this.stylesheetElement, document.head.firstChild);
3966  }
3967  installProgressElement() {
3968    this.progressElement.style.width = "0";
3969    this.progressElement.style.opacity = "1";
3970    document.documentElement.insertBefore(this.progressElement, document.body);
3971    this.refresh();
3972  }
3973  fadeProgressElement(callback) {
3974    this.progressElement.style.opacity = "0";
3975    setTimeout(callback, _ProgressBar.animationDuration * 1.5);
3976  }
3977  uninstallProgressElement() {
3978    if (this.progressElement.parentNode) {
3979      document.documentElement.removeChild(this.progressElement);
3980    }
3981  }
3982  startTrickling() {
3983    if (!this.trickleInterval) {
3984      this.trickleInterval = window.setInterval(this.trickle, _ProgressBar.animationDuration);
3985    }
3986  }
3987  stopTrickling() {
3988    window.clearInterval(this.trickleInterval);
3989    delete this.trickleInterval;
3990  }
3991  trickle = () => {
3992    this.setValue(this.value + Math.random() / 100);
3993  };
3994  refresh() {
3995    requestAnimationFrame(() => {
3996      this.progressElement.style.width = `${10 + this.value * 90}%`;
3997    });
3998  }
3999  createStylesheetElement() {
4000    const element = document.createElement("style");
4001    element.type = "text/css";
4002    element.textContent = _ProgressBar.defaultCSS;
4003    if (this.cspNonce) {
4004      element.nonce = this.cspNonce;
4005    }
4006    return element;
4007  }
4008  createProgressElement() {
4009    const element = document.createElement("div");
4010    element.className = "turbo-progress-bar";
4011    return element;
4012  }
4013  get cspNonce() {
4014    return getMetaContent("csp-nonce");
4015  }
4016};
4017var HeadSnapshot = class extends Snapshot {
4018  detailsByOuterHTML = this.children.filter((element) => !elementIsNoscript(element)).map((element) => elementWithoutNonce(element)).reduce((result, element) => {
4019    const { outerHTML } = element;
4020    const details = outerHTML in result ? result[outerHTML] : {
4021      type: elementType(element),
4022      tracked: elementIsTracked(element),
4023      elements: []
4024    };
4025    return {
4026      ...result,
4027      [outerHTML]: {
4028        ...details,
4029        elements: [...details.elements, element]
4030      }
4031    };
4032  }, {});
4033  get trackedElementSignature() {
4034    return Object.keys(this.detailsByOuterHTML).filter((outerHTML) => this.detailsByOuterHTML[outerHTML].tracked).join("");
4035  }
4036  getScriptElementsNotInSnapshot(snapshot) {
4037    return this.getElementsMatchingTypeNotInSnapshot("script", snapshot);
4038  }
4039  getStylesheetElementsNotInSnapshot(snapshot) {
4040    return this.getElementsMatchingTypeNotInSnapshot("stylesheet", snapshot);
4041  }
4042  getElementsMatchingTypeNotInSnapshot(matchedType, snapshot) {
4043    return Object.keys(this.detailsByOuterHTML).filter((outerHTML) => !(outerHTML in snapshot.detailsByOuterHTML)).map((outerHTML) => this.detailsByOuterHTML[outerHTML]).filter(({ type }) => type == matchedType).map(({ elements: [element] }) => element);
4044  }
4045  get provisionalElements() {
4046    return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {
4047      const { type, tracked, elements } = this.detailsByOuterHTML[outerHTML];
4048      if (type == null && !tracked) {
4049        return [...result, ...elements];
4050      } else if (elements.length > 1) {
4051        return [...result, ...elements.slice(1)];
4052      } else {
4053        return result;
4054      }
4055    }, []);
4056  }
4057  getMetaValue(name) {
4058    const element = this.findMetaElementByName(name);
4059    return element ? element.getAttribute("content") : null;
4060  }
4061  findMetaElementByName(name) {
4062    return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {
4063      const {
4064        elements: [element]
4065      } = this.detailsByOuterHTML[outerHTML];
4066      return elementIsMetaElementWithName(element, name) ? element : result;
4067    }, void 0 | void 0);
4068  }
4069};
4070function elementType(element) {
4071  if (elementIsScript(element)) {
4072    return "script";
4073  } else if (elementIsStylesheet(element)) {
4074    return "stylesheet";
4075  }
4076}
4077function elementIsTracked(element) {
4078  return element.getAttribute("data-turbo-track") == "reload";
4079}
4080function elementIsScript(element) {
4081  const tagName = element.localName;
4082  return tagName == "script";
4083}
4084function elementIsNoscript(element) {
4085  const tagName = element.localName;
4086  return tagName == "noscript";
4087}
4088function elementIsStylesheet(element) {
4089  const tagName = element.localName;
4090  return tagName == "style" || tagName == "link" && element.getAttribute("rel") == "stylesheet";
4091}
4092function elementIsMetaElementWithName(element, name) {
4093  const tagName = element.localName;
4094  return tagName == "meta" && element.getAttribute("name") == name;
4095}
4096function elementWithoutNonce(element) {
4097  if (element.hasAttribute("nonce")) {
4098    element.setAttribute("nonce", "");
4099  }
4100  return element;
4101}
4102var PageSnapshot = class _PageSnapshot extends Snapshot {
4103  static fromHTMLString(html = "") {
4104    return this.fromDocument(parseHTMLDocument(html));
4105  }
4106  static fromElement(element) {
4107    return this.fromDocument(element.ownerDocument);
4108  }
4109  static fromDocument({ documentElement, body, head }) {
4110    return new this(documentElement, body, new HeadSnapshot(head));
4111  }
4112  constructor(documentElement, body, headSnapshot) {
4113    super(body);
4114    this.documentElement = documentElement;
4115    this.headSnapshot = headSnapshot;
4116  }
4117  clone() {
4118    const clonedElement = this.element.cloneNode(true);
4119    const selectElements = this.element.querySelectorAll("select");
4120    const clonedSelectElements = clonedElement.querySelectorAll("select");
4121    for (const [index, source] of selectElements.entries()) {
4122      const clone = clonedSelectElements[index];
4123      for (const option of clone.selectedOptions) option.selected = false;
4124      for (const option of source.selectedOptions) clone.options[option.index].selected = true;
4125    }
4126    for (const clonedPasswordInput of clonedElement.querySelectorAll('input[type="password"]')) {
4127      clonedPasswordInput.value = "";
4128    }
4129    return new _PageSnapshot(this.documentElement, clonedElement, this.headSnapshot);
4130  }
4131  get lang() {
4132    return this.documentElement.getAttribute("lang");
4133  }
4134  get headElement() {
4135    return this.headSnapshot.element;
4136  }
4137  get rootLocation() {
4138    const root = this.getSetting("root") ?? "/";
4139    return expandURL(root);
4140  }
4141  get cacheControlValue() {
4142    return this.getSetting("cache-control");
4143  }
4144  get isPreviewable() {
4145    return this.cacheControlValue != "no-preview";
4146  }
4147  get isCacheable() {
4148    return this.cacheControlValue != "no-cache";
4149  }
4150  get isVisitable() {
4151    return this.getSetting("visit-control") != "reload";
4152  }
4153  get prefersViewTransitions() {
4154    return this.headSnapshot.getMetaValue("view-transition") === "same-origin";
4155  }
4156  get shouldMorphPage() {
4157    return this.getSetting("refresh-method") === "morph";
4158  }
4159  get shouldPreserveScrollPosition() {
4160    return this.getSetting("refresh-scroll") === "preserve";
4161  }
4162  // Private
4163  getSetting(name) {
4164    return this.headSnapshot.getMetaValue(`turbo-${name}`);
4165  }
4166};
4167var ViewTransitioner = class {
4168  #viewTransitionStarted = false;
4169  #lastOperation = Promise.resolve();
4170  renderChange(useViewTransition, render) {
4171    if (useViewTransition && this.viewTransitionsAvailable && !this.#viewTransitionStarted) {
4172      this.#viewTransitionStarted = true;
4173      this.#lastOperation = this.#lastOperation.then(async () => {
4174        await document.startViewTransition(render).finished;
4175      });
4176    } else {
4177      this.#lastOperation = this.#lastOperation.then(render);
4178    }
4179    return this.#lastOperation;
4180  }
4181  get viewTransitionsAvailable() {
4182    return document.startViewTransition;
4183  }
4184};
4185var defaultOptions = {
4186  action: "advance",
4187  historyChanged: false,
4188  visitCachedSnapshot: () => {
4189  },
4190  willRender: true,
4191  updateHistory: true,
4192  shouldCacheSnapshot: true,
4193  acceptsStreamResponse: false
4194};
4195var TimingMetric = {
4196  visitStart: "visitStart",
4197  requestStart: "requestStart",
4198  requestEnd: "requestEnd",
4199  visitEnd: "visitEnd"
4200};
4201var VisitState = {
4202  initialized: "initialized",
4203  started: "started",
4204  canceled: "canceled",
4205  failed: "failed",
4206  completed: "completed"
4207};
4208var SystemStatusCode = {
4209  networkFailure: 0,
4210  timeoutFailure: -1,
4211  contentTypeMismatch: -2
4212};
4213var Direction = {
4214  advance: "forward",
4215  restore: "back",
4216  replace: "none"
4217};
4218var Visit = class {
4219  identifier = uuid();
4220  // Required by turbo-ios
4221  timingMetrics = {};
4222  followedRedirect = false;
4223  historyChanged = false;
4224  scrolled = false;
4225  shouldCacheSnapshot = true;
4226  acceptsStreamResponse = false;
4227  snapshotCached = false;
4228  state = VisitState.initialized;
4229  viewTransitioner = new ViewTransitioner();
4230  constructor(delegate, location2, restorationIdentifier, options = {}) {
4231    this.delegate = delegate;
4232    this.location = location2;
4233    this.restorationIdentifier = restorationIdentifier || uuid();
4234    const {
4235      action,
4236      historyChanged,
4237      referrer,
4238      snapshot,
4239      snapshotHTML,
4240      response,
4241      visitCachedSnapshot,
4242      willRender,
4243      updateHistory,
4244      shouldCacheSnapshot,
4245      acceptsStreamResponse,
4246      direction
4247    } = {
4248      ...defaultOptions,
4249      ...options
4250    };
4251    this.action = action;
4252    this.historyChanged = historyChanged;
4253    this.referrer = referrer;
4254    this.snapshot = snapshot;
4255    this.snapshotHTML = snapshotHTML;
4256    this.response = response;
4257    this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action);
4258    this.isPageRefresh = this.view.isPageRefresh(this);
4259    this.visitCachedSnapshot = visitCachedSnapshot;
4260    this.willRender = willRender;
4261    this.updateHistory = updateHistory;
4262    this.scrolled = !willRender;
4263    this.shouldCacheSnapshot = shouldCacheSnapshot;
4264    this.acceptsStreamResponse = acceptsStreamResponse;
4265    this.direction = direction || Direction[action];
4266  }
4267  get adapter() {
4268    return this.delegate.adapter;
4269  }
4270  get view() {
4271    return this.delegate.view;
4272  }
4273  get history() {
4274    return this.delegate.history;
4275  }
4276  get restorationData() {
4277    return this.history.getRestorationDataForIdentifier(this.restorationIdentifier);
4278  }
4279  get silent() {
4280    return this.isSamePage;
4281  }
4282  start() {
4283    if (this.state == VisitState.initialized) {
4284      this.recordTimingMetric(TimingMetric.visitStart);
4285      this.state = VisitState.started;
4286      this.adapter.visitStarted(this);
4287      this.delegate.visitStarted(this);
4288    }
4289  }
4290  cancel() {
4291    if (this.state == VisitState.started) {
4292      if (this.request) {
4293        this.request.cancel();
4294      }
4295      this.cancelRender();
4296      this.state = VisitState.canceled;
4297    }
4298  }
4299  complete() {
4300    if (this.state == VisitState.started) {
4301      this.recordTimingMetric(TimingMetric.visitEnd);
4302      this.adapter.visitCompleted(this);
4303      this.state = VisitState.completed;
4304      this.followRedirect();
4305      if (!this.followedRedirect) {
4306        this.delegate.visitCompleted(this);
4307      }
4308    }
4309  }
4310  fail() {
4311    if (this.state == VisitState.started) {
4312      this.state = VisitState.failed;
4313      this.adapter.visitFailed(this);
4314      this.delegate.visitCompleted(this);
4315    }
4316  }
4317  changeHistory() {
4318    if (!this.historyChanged && this.updateHistory) {
4319      const actionForHistory = this.location.href === this.referrer?.href ? "replace" : this.action;
4320      const method = getHistoryMethodForAction(actionForHistory);
4321      this.history.update(method, this.location, this.restorationIdentifier);
4322      this.historyChanged = true;
4323    }
4324  }
4325  issueRequest() {
4326    if (this.hasPreloadedResponse()) {
4327      this.simulateRequest();
4328    } else if (this.shouldIssueRequest() && !this.request) {
4329      this.request = new FetchRequest(this, FetchMethod.get, this.location);
4330      this.request.perform();
4331    }
4332  }
4333  simulateRequest() {
4334    if (this.response) {
4335      this.startRequest();
4336      this.recordResponse();
4337      this.finishRequest();
4338    }
4339  }
4340  startRequest() {
4341    this.recordTimingMetric(TimingMetric.requestStart);
4342    this.adapter.visitRequestStarted(this);
4343  }
4344  recordResponse(response = this.response) {
4345    this.response = response;
4346    if (response) {
4347      const { statusCode } = response;
4348      if (isSuccessful(statusCode)) {
4349        this.adapter.visitRequestCompleted(this);
4350      } else {
4351        this.adapter.visitRequestFailedWithStatusCode(this, statusCode);
4352      }
4353    }
4354  }
4355  finishRequest() {
4356    this.recordTimingMetric(TimingMetric.requestEnd);
4357    this.adapter.visitRequestFinished(this);
4358  }
4359  loadResponse() {
4360    if (this.response) {
4361      const { statusCode, responseHTML } = this.response;
4362      this.render(async () => {
4363        if (this.shouldCacheSnapshot) this.cacheSnapshot();
4364        if (this.view.renderPromise) await this.view.renderPromise;
4365        if (isSuccessful(statusCode) && responseHTML != null) {
4366          const snapshot = PageSnapshot.fromHTMLString(responseHTML);
4367          await this.renderPageSnapshot(snapshot, false);
4368          this.adapter.visitRendered(this);
4369          this.complete();
4370        } else {
4371          await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML), this);
4372          this.adapter.visitRendered(this);
4373          this.fail();
4374        }
4375      });
4376    }
4377  }
4378  getCachedSnapshot() {
4379    const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot();
4380    if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) {
4381      if (this.action == "restore" || snapshot.isPreviewable) {
4382        return snapshot;
4383      }
4384    }
4385  }
4386  getPreloadedSnapshot() {
4387    if (this.snapshotHTML) {
4388      return PageSnapshot.fromHTMLString(this.snapshotHTML);
4389    }
4390  }
4391  hasCachedSnapshot() {
4392    return this.getCachedSnapshot() != null;
4393  }
4394  loadCachedSnapshot() {
4395    const snapshot = this.getCachedSnapshot();
4396    if (snapshot) {
4397      const isPreview = this.shouldIssueRequest();
4398      this.render(async () => {
4399        this.cacheSnapshot();
4400        if (this.isSamePage || this.isPageRefresh) {
4401          this.adapter.visitRendered(this);
4402        } else {
4403          if (this.view.renderPromise) await this.view.renderPromise;
4404          await this.renderPageSnapshot(snapshot, isPreview);
4405          this.adapter.visitRendered(this);
4406          if (!isPreview) {
4407            this.complete();
4408          }
4409        }
4410      });
4411    }
4412  }
4413  followRedirect() {
4414    if (this.redirectedToLocation && !this.followedRedirect && this.response?.redirected) {
4415      this.adapter.visitProposedToLocation(this.redirectedToLocation, {
4416        action: "replace",
4417        response: this.response,
4418        shouldCacheSnapshot: false,
4419        willRender: false
4420      });
4421      this.followedRedirect = true;
4422    }
4423  }
4424  goToSamePageAnchor() {
4425    if (this.isSamePage) {
4426      this.render(async () => {
4427        this.cacheSnapshot();
4428        this.performScroll();
4429        this.changeHistory();
4430        this.adapter.visitRendered(this);
4431      });
4432    }
4433  }
4434  // Fetch request delegate
4435  prepareRequest(request) {
4436    if (this.acceptsStreamResponse) {
4437      request.acceptResponseType(StreamMessage.contentType);
4438    }
4439  }
4440  requestStarted() {
4441    this.startRequest();
4442  }
4443  requestPreventedHandlingResponse(_request, _response) {
4444  }
4445  async requestSucceededWithResponse(request, response) {
4446    const responseHTML = await response.responseHTML;
4447    const { redirected, statusCode } = response;
4448    if (responseHTML == void 0) {
4449      this.recordResponse({
4450        statusCode: SystemStatusCode.contentTypeMismatch,
4451        redirected
4452      });
4453    } else {
4454      this.redirectedToLocation = response.redirected ? response.location : void 0;
4455      this.recordResponse({ statusCode, responseHTML, redirected });
4456    }
4457  }
4458  async requestFailedWithResponse(request, response) {
4459    const responseHTML = await response.responseHTML;
4460    const { redirected, statusCode } = response;
4461    if (responseHTML == void 0) {
4462      this.recordResponse({
4463        statusCode: SystemStatusCode.contentTypeMismatch,
4464        redirected
4465      });
4466    } else {
4467      this.recordResponse({ statusCode, responseHTML, redirected });
4468    }
4469  }
4470  requestErrored(_request, _error) {
4471    this.recordResponse({
4472      statusCode: SystemStatusCode.networkFailure,
4473      redirected: false
4474    });
4475  }
4476  requestFinished() {
4477    this.finishRequest();
4478  }
4479  // Scrolling
4480  performScroll() {
4481    if (!this.scrolled && !this.view.forceReloaded && !this.view.shouldPreserveScrollPosition(this)) {
4482      if (this.action == "restore") {
4483        this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop();
4484      } else {
4485        this.scrollToAnchor() || this.view.scrollToTop();
4486      }
4487      if (this.isSamePage) {
4488        this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation, this.location);
4489      }
4490      this.scrolled = true;
4491    }
4492  }
4493  scrollToRestoredPosition() {
4494    const { scrollPosition } = this.restorationData;
4495    if (scrollPosition) {
4496      this.view.scrollToPosition(scrollPosition);
4497      return true;
4498    }
4499  }
4500  scrollToAnchor() {
4501    const anchor = getAnchor(this.location);
4502    if (anchor != null) {
4503      this.view.scrollToAnchor(anchor);
4504      return true;
4505    }
4506  }
4507  // Instrumentation
4508  recordTimingMetric(metric) {
4509    this.timingMetrics[metric] = (/* @__PURE__ */ new Date()).getTime();
4510  }
4511  getTimingMetrics() {
4512    return { ...this.timingMetrics };
4513  }
4514  // Private
4515  getHistoryMethodForAction(action) {
4516    switch (action) {
4517      case "replace":
4518        return history.replaceState;
4519      case "advance":
4520      case "restore":
4521        return history.pushState;
4522    }
4523  }
4524  hasPreloadedResponse() {
4525    return typeof this.response == "object";
4526  }
4527  shouldIssueRequest() {
4528    if (this.isSamePage) {
4529      return false;
4530    } else if (this.action == "restore") {
4531      return !this.hasCachedSnapshot();
4532    } else {
4533      return this.willRender;
4534    }
4535  }
4536  cacheSnapshot() {
4537    if (!this.snapshotCached) {
4538      this.view.cacheSnapshot(this.snapshot).then((snapshot) => snapshot && this.visitCachedSnapshot(snapshot));
4539      this.snapshotCached = true;
4540    }
4541  }
4542  async render(callback) {
4543    this.cancelRender();
4544    await new Promise((resolve) => {
4545      this.frame = document.visibilityState === "hidden" ? setTimeout(() => resolve(), 0) : requestAnimationFrame(() => resolve());
4546    });
4547    await callback();
4548    delete this.frame;
4549  }
4550  async renderPageSnapshot(snapshot, isPreview) {
4551    await this.viewTransitioner.renderChange(this.view.shouldTransitionTo(snapshot), async () => {
4552      await this.view.renderPage(snapshot, isPreview, this.willRender, this);
4553      this.performScroll();
4554    });
4555  }
4556  cancelRender() {
4557    if (this.frame) {
4558      cancelAnimationFrame(this.frame);
4559      delete this.frame;
4560    }
4561  }
4562};
4563function isSuccessful(statusCode) {
4564  return statusCode >= 200 && statusCode < 300;
4565}
4566var BrowserAdapter = class {
4567  progressBar = new ProgressBar();
4568  constructor(session2) {
4569    this.session = session2;
4570  }
4571  visitProposedToLocation(location2, options) {
4572    if (locationIsVisitable(location2, this.navigator.rootLocation)) {
4573      this.navigator.startVisit(location2, options?.restorationIdentifier || uuid(), options);
4574    } else {
4575      window.location.href = location2.toString();
4576    }
4577  }
4578  visitStarted(visit2) {
4579    this.location = visit2.location;
4580    visit2.loadCachedSnapshot();
4581    visit2.issueRequest();
4582    visit2.goToSamePageAnchor();
4583  }
4584  visitRequestStarted(visit2) {
4585    this.progressBar.setValue(0);
4586    if (visit2.hasCachedSnapshot() || visit2.action != "restore") {
4587      this.showVisitProgressBarAfterDelay();
4588    } else {
4589      this.showProgressBar();
4590    }
4591  }
4592  visitRequestCompleted(visit2) {
4593    visit2.loadResponse();
4594  }
4595  visitRequestFailedWithStatusCode(visit2, statusCode) {
4596    switch (statusCode) {
4597      case SystemStatusCode.networkFailure:
4598      case SystemStatusCode.timeoutFailure:
4599      case SystemStatusCode.contentTypeMismatch:
4600        return this.reload({
4601          reason: "request_failed",
4602          context: {
4603            statusCode
4604          }
4605        });
4606      default:
4607        return visit2.loadResponse();
4608    }
4609  }
4610  visitRequestFinished(_visit) {
4611  }
4612  visitCompleted(_visit) {
4613    this.progressBar.setValue(1);
4614    this.hideVisitProgressBar();
4615  }
4616  pageInvalidated(reason) {
4617    this.reload(reason);
4618  }
4619  visitFailed(_visit) {
4620    this.progressBar.setValue(1);
4621    this.hideVisitProgressBar();
4622  }
4623  visitRendered(_visit) {
4624  }
4625  // Form Submission Delegate
4626  formSubmissionStarted(_formSubmission) {
4627    this.progressBar.setValue(0);
4628    this.showFormProgressBarAfterDelay();
4629  }
4630  formSubmissionFinished(_formSubmission) {
4631    this.progressBar.setValue(1);
4632    this.hideFormProgressBar();
4633  }
4634  // Private
4635  showVisitProgressBarAfterDelay() {
4636    this.visitProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);
4637  }
4638  hideVisitProgressBar() {
4639    this.progressBar.hide();
4640    if (this.visitProgressBarTimeout != null) {
4641      window.clearTimeout(this.visitProgressBarTimeout);
4642      delete this.visitProgressBarTimeout;
4643    }
4644  }
4645  showFormProgressBarAfterDelay() {
4646    if (this.formProgressBarTimeout == null) {
4647      this.formProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);
4648    }
4649  }
4650  hideFormProgressBar() {
4651    this.progressBar.hide();
4652    if (this.formProgressBarTimeout != null) {
4653      window.clearTimeout(this.formProgressBarTimeout);
4654      delete this.formProgressBarTimeout;
4655    }
4656  }
4657  showProgressBar = () => {
4658    this.progressBar.show();
4659  };
4660  reload(reason) {
4661    dispatch("turbo:reload", { detail: reason });
4662    window.location.href = this.location?.toString() || window.location.href;
4663  }
4664  get navigator() {
4665    return this.session.navigator;
4666  }
4667};
4668var CacheObserver = class {
4669  selector = "[data-turbo-temporary]";
4670  deprecatedSelector = "[data-turbo-cache=false]";
4671  started = false;
4672  start() {
4673    if (!this.started) {
4674      this.started = true;
4675      addEventListener("turbo:before-cache", this.removeTemporaryElements, false);
4676    }
4677  }
4678  stop() {
4679    if (this.started) {
4680      this.started = false;
4681      removeEventListener("turbo:before-cache", this.removeTemporaryElements, false);
4682    }
4683  }
4684  removeTemporaryElements = (_event) => {
4685    for (const element of this.temporaryElements) {
4686      element.remove();
4687    }
4688  };
4689  get temporaryElements() {
4690    return [...document.querySelectorAll(this.selector), ...this.temporaryElementsWithDeprecation];
4691  }
4692  get temporaryElementsWithDeprecation() {
4693    const elements = document.querySelectorAll(this.deprecatedSelector);
4694    if (elements.length) {
4695      console.warn(
4696        `The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.`
4697      );
4698    }
4699    return [...elements];
4700  }
4701};
4702var FrameRedirector = class {
4703  constructor(session2, element) {
4704    this.session = session2;
4705    this.element = element;
4706    this.linkInterceptor = new LinkInterceptor(this, element);
4707    this.formSubmitObserver = new FormSubmitObserver(this, element);
4708  }
4709  start() {
4710    this.linkInterceptor.start();
4711    this.formSubmitObserver.start();
4712  }
4713  stop() {
4714    this.linkInterceptor.stop();
4715    this.formSubmitObserver.stop();
4716  }
4717  // Link interceptor delegate
4718  shouldInterceptLinkClick(element, _location, _event) {
4719    return this.#shouldRedirect(element);
4720  }
4721  linkClickIntercepted(element, url, event) {
4722    const frame = this.#findFrameElement(element);
4723    if (frame) {
4724      frame.delegate.linkClickIntercepted(element, url, event);
4725    }
4726  }
4727  // Form submit observer delegate
4728  willSubmitForm(element, submitter2) {
4729    return element.closest("turbo-frame") == null && this.#shouldSubmit(element, submitter2) && this.#shouldRedirect(element, submitter2);
4730  }
4731  formSubmitted(element, submitter2) {
4732    const frame = this.#findFrameElement(element, submitter2);
4733    if (frame) {
4734      frame.delegate.formSubmitted(element, submitter2);
4735    }
4736  }
4737  #shouldSubmit(form, submitter2) {
4738    const action = getAction$1(form, submitter2);
4739    const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`);
4740    const rootLocation = expandURL(meta?.content ?? "/");
4741    return this.#shouldRedirect(form, submitter2) && locationIsVisitable(action, rootLocation);
4742  }
4743  #shouldRedirect(element, submitter2) {
4744    const isNavigatable = element instanceof HTMLFormElement ? this.session.submissionIsNavigatable(element, submitter2) : this.session.elementIsNavigatable(element);
4745    if (isNavigatable) {
4746      const frame = this.#findFrameElement(element, submitter2);
4747      return frame ? frame != element.closest("turbo-frame") : false;
4748    } else {
4749      return false;
4750    }
4751  }
4752  #findFrameElement(element, submitter2) {
4753    const id = submitter2?.getAttribute("data-turbo-frame") || element.getAttribute("data-turbo-frame");
4754    if (id && id != "_top") {
4755      const frame = this.element.querySelector(`#${id}:not([disabled])`);
4756      if (frame instanceof FrameElement) {
4757        return frame;
4758      }
4759    }
4760  }
4761};
4762var History = class {
4763  location;
4764  restorationIdentifier = uuid();
4765  restorationData = {};
4766  started = false;
4767  pageLoaded = false;
4768  currentIndex = 0;
4769  constructor(delegate) {
4770    this.delegate = delegate;
4771  }
4772  start() {
4773    if (!this.started) {
4774      addEventListener("popstate", this.onPopState, false);
4775      addEventListener("load", this.onPageLoad, false);
4776      this.currentIndex = history.state?.turbo?.restorationIndex || 0;
4777      this.started = true;
4778      this.replace(new URL(window.location.href));
4779    }
4780  }
4781  stop() {
4782    if (this.started) {
4783      removeEventListener("popstate", this.onPopState, false);
4784      removeEventListener("load", this.onPageLoad, false);
4785      this.started = false;
4786    }
4787  }
4788  push(location2, restorationIdentifier) {
4789    this.update(history.pushState, location2, restorationIdentifier);
4790  }
4791  replace(location2, restorationIdentifier) {
4792    this.update(history.replaceState, location2, restorationIdentifier);
4793  }
4794  update(method, location2, restorationIdentifier = uuid()) {
4795    if (method === history.pushState) ++this.currentIndex;
4796    const state = { turbo: { restorationIdentifier, restorationIndex: this.currentIndex } };
4797    method.call(history, state, "", location2.href);
4798    this.location = location2;
4799    this.restorationIdentifier = restorationIdentifier;
4800  }
4801  // Restoration data
4802  getRestorationDataForIdentifier(restorationIdentifier) {
4803    return this.restorationData[restorationIdentifier] || {};
4804  }
4805  updateRestorationData(additionalData) {
4806    const { restorationIdentifier } = this;
4807    const restorationData = this.restorationData[restorationIdentifier];
4808    this.restorationData[restorationIdentifier] = {
4809      ...restorationData,
4810      ...additionalData
4811    };
4812  }
4813  // Scroll restoration
4814  assumeControlOfScrollRestoration() {
4815    if (!this.previousScrollRestoration) {
4816      this.previousScrollRestoration = history.scrollRestoration ?? "auto";
4817      history.scrollRestoration = "manual";
4818    }
4819  }
4820  relinquishControlOfScrollRestoration() {
4821    if (this.previousScrollRestoration) {
4822      history.scrollRestoration = this.previousScrollRestoration;
4823      delete this.previousScrollRestoration;
4824    }
4825  }
4826  // Event handlers
4827  onPopState = (event) => {
4828    if (this.shouldHandlePopState()) {
4829      const { turbo } = event.state || {};
4830      if (turbo) {
4831        this.location = new URL(window.location.href);
4832        const { restorationIdentifier, restorationIndex } = turbo;
4833        this.restorationIdentifier = restorationIdentifier;
4834        const direction = restorationIndex > this.currentIndex ? "forward" : "back";
4835        this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location, restorationIdentifier, direction);
4836        this.currentIndex = restorationIndex;
4837      }
4838    }
4839  };
4840  onPageLoad = async (_event) => {
4841    await nextMicrotask();
4842    this.pageLoaded = true;
4843  };
4844  // Private
4845  shouldHandlePopState() {
4846    return this.pageIsLoaded();
4847  }
4848  pageIsLoaded() {
4849    return this.pageLoaded || document.readyState == "complete";
4850  }
4851};
4852var LinkPrefetchObserver = class {
4853  started = false;
4854  #prefetchedLink = null;
4855  constructor(delegate, eventTarget) {
4856    this.delegate = delegate;
4857    this.eventTarget = eventTarget;
4858  }
4859  start() {
4860    if (this.started) return;
4861    if (this.eventTarget.readyState === "loading") {
4862      this.eventTarget.addEventListener("DOMContentLoaded", this.#enable, { once: true });
4863    } else {
4864      this.#enable();
4865    }
4866  }
4867  stop() {
4868    if (!this.started) return;
4869    this.eventTarget.removeEventListener("mouseenter", this.#tryToPrefetchRequest, {
4870      capture: true,
4871      passive: true
4872    });
4873    this.eventTarget.removeEventListener("mouseleave", this.#cancelRequestIfObsolete, {
4874      capture: true,
4875      passive: true
4876    });
4877    this.eventTarget.removeEventListener("turbo:before-fetch-request", this.#tryToUsePrefetchedRequest, true);
4878    this.started = false;
4879  }
4880  #enable = () => {
4881    this.eventTarget.addEventListener("mouseenter", this.#tryToPrefetchRequest, {
4882      capture: true,
4883      passive: true
4884    });
4885    this.eventTarget.addEventListener("mouseleave", this.#cancelRequestIfObsolete, {
4886      capture: true,
4887      passive: true
4888    });
4889    this.eventTarget.addEventListener("turbo:before-fetch-request", this.#tryToUsePrefetchedRequest, true);
4890    this.started = true;
4891  };
4892  #tryToPrefetchRequest = (event) => {
4893    if (getMetaContent("turbo-prefetch") === "false") return;
4894    const target = event.target;
4895    const isLink = target.matches && target.matches("a[href]:not([target^=_]):not([download])");
4896    if (isLink && this.#isPrefetchable(target)) {
4897      const link = target;
4898      const location2 = getLocationForLink(link);
4899      if (this.delegate.canPrefetchRequestToLocation(link, location2)) {
4900        this.#prefetchedLink = link;
4901        const fetchRequest = new FetchRequest(
4902          this,
4903          FetchMethod.get,
4904          location2,
4905          new URLSearchParams(),
4906          target
4907        );
4908        prefetchCache.setLater(location2.toString(), fetchRequest, this.#cacheTtl);
4909      }
4910    }
4911  };
4912  #cancelRequestIfObsolete = (event) => {
4913    if (event.target === this.#prefetchedLink) this.#cancelPrefetchRequest();
4914  };
4915  #cancelPrefetchRequest = () => {
4916    prefetchCache.clear();
4917    this.#prefetchedLink = null;
4918  };
4919  #tryToUsePrefetchedRequest = (event) => {
4920    if (event.target.tagName !== "FORM" && event.detail.fetchOptions.method === "GET") {
4921      const cached = prefetchCache.get(event.detail.url.toString());
4922      if (cached) {
4923        event.detail.fetchRequest = cached;
4924      }
4925      prefetchCache.clear();
4926    }
4927  };
4928  prepareRequest(request) {
4929    const link = request.target;
4930    request.headers["X-Sec-Purpose"] = "prefetch";
4931    const turboFrame = link.closest("turbo-frame");
4932    const turboFrameTarget = link.getAttribute("data-turbo-frame") || turboFrame?.getAttribute("target") || turboFrame?.id;
4933    if (turboFrameTarget && turboFrameTarget !== "_top") {
4934      request.headers["Turbo-Frame"] = turboFrameTarget;
4935    }
4936  }
4937  // Fetch request interface
4938  requestSucceededWithResponse() {
4939  }
4940  requestStarted(fetchRequest) {
4941  }
4942  requestErrored(fetchRequest) {
4943  }
4944  requestFinished(fetchRequest) {
4945  }
4946  requestPreventedHandlingResponse(fetchRequest, fetchResponse) {
4947  }
4948  requestFailedWithResponse(fetchRequest, fetchResponse) {
4949  }
4950  get #cacheTtl() {
4951    return Number(getMetaContent("turbo-prefetch-cache-time")) || cacheTtl;
4952  }
4953  #isPrefetchable(link) {
4954    const href = link.getAttribute("href");
4955    if (!href) return false;
4956    if (unfetchableLink(link)) return false;
4957    if (linkToTheSamePage(link)) return false;
4958    if (linkOptsOut(link)) return false;
4959    if (nonSafeLink(link)) return false;
4960    if (eventPrevented(link)) return false;
4961    return true;
4962  }
4963};
4964var unfetchableLink = (link) => {
4965  return link.origin !== document.location.origin || !["http:", "https:"].includes(link.protocol) || link.hasAttribute("target");
4966};
4967var linkToTheSamePage = (link) => {
4968  return link.pathname + link.search === document.location.pathname + document.location.search || link.href.startsWith("#");
4969};
4970var linkOptsOut = (link) => {
4971  if (link.getAttribute("data-turbo-prefetch") === "false") return true;
4972  if (link.getAttribute("data-turbo") === "false") return true;
4973  const turboPrefetchParent = findClosestRecursively(link, "[data-turbo-prefetch]");
4974  if (turboPrefetchParent && turboPrefetchParent.getAttribute("data-turbo-prefetch") === "false") return true;
4975  return false;
4976};
4977var nonSafeLink = (link) => {
4978  const turboMethod = link.getAttribute("data-turbo-method");
4979  if (turboMethod && turboMethod.toLowerCase() !== "get") return true;
4980  if (isUJS(link)) return true;
4981  if (link.hasAttribute("data-turbo-confirm")) return true;
4982  if (link.hasAttribute("data-turbo-stream")) return true;
4983  return false;
4984};
4985var isUJS = (link) => {
4986  return link.hasAttribute("data-remote") || link.hasAttribute("data-behavior") || link.hasAttribute("data-confirm") || link.hasAttribute("data-method");
4987};
4988var eventPrevented = (link) => {
4989  const event = dispatch("turbo:before-prefetch", { target: link, cancelable: true });
4990  return event.defaultPrevented;
4991};
4992var Navigator = class {
4993  constructor(delegate) {
4994    this.delegate = delegate;
4995  }
4996  proposeVisit(location2, options = {}) {
4997    if (this.delegate.allowsVisitingLocationWithAction(location2, options.action)) {
4998      this.delegate.visitProposedToLocation(location2, options);
4999    }
5000  }
5001  startVisit(locatable, restorationIdentifier, options = {}) {
5002    this.stop();
5003    this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, {
5004      referrer: this.location,
5005      ...options
5006    });
5007    this.currentVisit.start();
5008  }
5009  submitForm(form, submitter2) {
5010    this.stop();
5011    this.formSubmission = new FormSubmission(this, form, submitter2, true);
5012    this.formSubmission.start();
5013  }
5014  stop() {
5015    if (this.formSubmission) {
5016      this.formSubmission.stop();
5017      delete this.formSubmission;
5018    }
5019    if (this.currentVisit) {
5020      this.currentVisit.cancel();
5021      delete this.currentVisit;
5022    }
5023  }
5024  get adapter() {
5025    return this.delegate.adapter;
5026  }
5027  get view() {
5028    return this.delegate.view;
5029  }
5030  get rootLocation() {
5031    return this.view.snapshot.rootLocation;
5032  }
5033  get history() {
5034    return this.delegate.history;
5035  }
5036  // Form submission delegate
5037  formSubmissionStarted(formSubmission) {
5038    if (typeof this.adapter.formSubmissionStarted === "function") {
5039      this.adapter.formSubmissionStarted(formSubmission);
5040    }
5041  }
5042  async formSubmissionSucceededWithResponse(formSubmission, fetchResponse) {
5043    if (formSubmission == this.formSubmission) {
5044      const responseHTML = await fetchResponse.responseHTML;
5045      if (responseHTML) {
5046        const shouldCacheSnapshot = formSubmission.isSafe;
5047        if (!shouldCacheSnapshot) {
5048          this.view.clearSnapshotCache();
5049        }
5050        const { statusCode, redirected } = fetchResponse;
5051        const action = this.#getActionForFormSubmission(formSubmission, fetchResponse);
5052        const visitOptions = {
5053          action,
5054          shouldCacheSnapshot,
5055          response: { statusCode, responseHTML, redirected }
5056        };
5057        this.proposeVisit(fetchResponse.location, visitOptions);
5058      }
5059    }
5060  }
5061  async formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
5062    const responseHTML = await fetchResponse.responseHTML;
5063    if (responseHTML) {
5064      const snapshot = PageSnapshot.fromHTMLString(responseHTML);
5065      if (fetchResponse.serverError) {
5066        await this.view.renderError(snapshot, this.currentVisit);
5067      } else {
5068        await this.view.renderPage(snapshot, false, true, this.currentVisit);
5069      }
5070      if (!snapshot.shouldPreserveScrollPosition) {
5071        this.view.scrollToTop();
5072      }
5073      this.view.clearSnapshotCache();
5074    }
5075  }
5076  formSubmissionErrored(formSubmission, error2) {
5077    console.error(error2);
5078  }
5079  formSubmissionFinished(formSubmission) {
5080    if (typeof this.adapter.formSubmissionFinished === "function") {
5081      this.adapter.formSubmissionFinished(formSubmission);
5082    }
5083  }
5084  // Visit delegate
5085  visitStarted(visit2) {
5086    this.delegate.visitStarted(visit2);
5087  }
5088  visitCompleted(visit2) {
5089    this.delegate.visitCompleted(visit2);
5090    delete this.currentVisit;
5091  }
5092  locationWithActionIsSamePage(location2, action) {
5093    const anchor = getAnchor(location2);
5094    const currentAnchor = getAnchor(this.view.lastRenderedLocation);
5095    const isRestorationToTop = action === "restore" && typeof anchor === "undefined";
5096    return action !== "replace" && getRequestURL(location2) === getRequestURL(this.view.lastRenderedLocation) && (isRestorationToTop || anchor != null && anchor !== currentAnchor);
5097  }
5098  visitScrolledToSamePageLocation(oldURL, newURL) {
5099    this.delegate.visitScrolledToSamePageLocation(oldURL, newURL);
5100  }
5101  // Visits
5102  get location() {
5103    return this.history.location;
5104  }
5105  get restorationIdentifier() {
5106    return this.history.restorationIdentifier;
5107  }
5108  #getActionForFormSubmission(formSubmission, fetchResponse) {
5109    const { submitter: submitter2, formElement } = formSubmission;
5110    return getVisitAction(submitter2, formElement) || this.#getDefaultAction(fetchResponse);
5111  }
5112  #getDefaultAction(fetchResponse) {
5113    const sameLocationRedirect = fetchResponse.redirected && fetchResponse.location.href === this.location?.href;
5114    return sameLocationRedirect ? "replace" : "advance";
5115  }
5116};
5117var PageStage = {
5118  initial: 0,
5119  loading: 1,
5120  interactive: 2,
5121  complete: 3
5122};
5123var PageObserver = class {
5124  stage = PageStage.initial;
5125  started = false;
5126  constructor(delegate) {
5127    this.delegate = delegate;
5128  }
5129  start() {
5130    if (!this.started) {
5131      if (this.stage == PageStage.initial) {
5132        this.stage = PageStage.loading;
5133      }
5134      document.addEventListener("readystatechange", this.interpretReadyState, false);
5135      addEventListener("pagehide", this.pageWillUnload, false);
5136      this.started = true;
5137    }
5138  }
5139  stop() {
5140    if (this.started) {
5141      document.removeEventListener("readystatechange", this.interpretReadyState, false);
5142      removeEventListener("pagehide", this.pageWillUnload, false);
5143      this.started = false;
5144    }
5145  }
5146  interpretReadyState = () => {
5147    const { readyState } = this;
5148    if (readyState == "interactive") {
5149      this.pageIsInteractive();
5150    } else if (readyState == "complete") {
5151      this.pageIsComplete();
5152    }
5153  };
5154  pageIsInteractive() {
5155    if (this.stage == PageStage.loading) {
5156      this.stage = PageStage.interactive;
5157      this.delegate.pageBecameInteractive();
5158    }
5159  }
5160  pageIsComplete() {
5161    this.pageIsInteractive();
5162    if (this.stage == PageStage.interactive) {
5163      this.stage = PageStage.complete;
5164      this.delegate.pageLoaded();
5165    }
5166  }
5167  pageWillUnload = () => {
5168    this.delegate.pageWillUnload();
5169  };
5170  get readyState() {
5171    return document.readyState;
5172  }
5173};
5174var ScrollObserver = class {
5175  started = false;
5176  constructor(delegate) {
5177    this.delegate = delegate;
5178  }
5179  start() {
5180    if (!this.started) {
5181      addEventListener("scroll", this.onScroll, false);
5182      this.onScroll();
5183      this.started = true;
5184    }
5185  }
5186  stop() {
5187    if (this.started) {
5188      removeEventListener("scroll", this.onScroll, false);
5189      this.started = false;
5190    }
5191  }
5192  onScroll = () => {
5193    this.updatePosition({ x: window.pageXOffset, y: window.pageYOffset });
5194  };
5195  // Private
5196  updatePosition(position) {
5197    this.delegate.scrollPositionChanged(position);
5198  }
5199};
5200var StreamMessageRenderer = class {
5201  render({ fragment }) {
5202    Bardo.preservingPermanentElements(this, getPermanentElementMapForFragment(fragment), () => {
5203      withAutofocusFromFragment(fragment, () => {
5204        withPreservedFocus(() => {
5205          document.documentElement.appendChild(fragment);
5206        });
5207      });
5208    });
5209  }
5210  // Bardo delegate
5211  enteringBardo(currentPermanentElement, newPermanentElement) {
5212    newPermanentElement.replaceWith(currentPermanentElement.cloneNode(true));
5213  }
5214  leavingBardo() {
5215  }
5216};
5217function getPermanentElementMapForFragment(fragment) {
5218  const permanentElementsInDocument = queryPermanentElementsAll(document.documentElement);
5219  const permanentElementMap = {};
5220  for (const permanentElementInDocument of permanentElementsInDocument) {
5221    const { id } = permanentElementInDocument;
5222    for (const streamElement of fragment.querySelectorAll("turbo-stream")) {
5223      const elementInStream = getPermanentElementById(streamElement.templateElement.content, id);
5224      if (elementInStream) {
5225        permanentElementMap[id] = [permanentElementInDocument, elementInStream];
5226      }
5227    }
5228  }
5229  return permanentElementMap;
5230}
5231async function withAutofocusFromFragment(fragment, callback) {
5232  const generatedID = `turbo-stream-autofocus-${uuid()}`;
5233  const turboStreams = fragment.querySelectorAll("turbo-stream");
5234  const elementWithAutofocus = firstAutofocusableElementInStreams(turboStreams);
5235  let willAutofocusId = null;
5236  if (elementWithAutofocus) {
5237    if (elementWithAutofocus.id) {
5238      willAutofocusId = elementWithAutofocus.id;
5239    } else {
5240      willAutofocusId = generatedID;
5241    }
5242    elementWithAutofocus.id = willAutofocusId;
5243  }
5244  callback();
5245  await nextRepaint();
5246  const hasNoActiveElement = document.activeElement == null || document.activeElement == document.body;
5247  if (hasNoActiveElement && willAutofocusId) {
5248    const elementToAutofocus = document.getElementById(willAutofocusId);
5249    if (elementIsFocusable(elementToAutofocus)) {
5250      elementToAutofocus.focus();
5251    }
5252    if (elementToAutofocus && elementToAutofocus.id == generatedID) {
5253      elementToAutofocus.removeAttribute("id");
5254    }
5255  }
5256}
5257async function withPreservedFocus(callback) {
5258  const [activeElementBeforeRender, activeElementAfterRender] = await around(callback, () => document.activeElement);
5259  const restoreFocusTo = activeElementBeforeRender && activeElementBeforeRender.id;
5260  if (restoreFocusTo) {
5261    const elementToFocus = document.getElementById(restoreFocusTo);
5262    if (elementIsFocusable(elementToFocus) && elementToFocus != activeElementAfterRender) {
5263      elementToFocus.focus();
5264    }
5265  }
5266}
5267function firstAutofocusableElementInStreams(nodeListOfStreamElements) {
5268  for (const streamElement of nodeListOfStreamElements) {
5269    const elementWithAutofocus = queryAutofocusableElement(streamElement.templateElement.content);
5270    if (elementWithAutofocus) return elementWithAutofocus;
5271  }
5272  return null;
5273}
5274var StreamObserver = class {
5275  sources = /* @__PURE__ */ new Set();
5276  #started = false;
5277  constructor(delegate) {
5278    this.delegate = delegate;
5279  }
5280  start() {
5281    if (!this.#started) {
5282      this.#started = true;
5283      addEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false);
5284    }
5285  }
5286  stop() {
5287    if (this.#started) {
5288      this.#started = false;
5289      removeEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false);
5290    }
5291  }
5292  connectStreamSource(source) {
5293    if (!this.streamSourceIsConnected(source)) {
5294      this.sources.add(source);
5295      source.addEventListener("message", this.receiveMessageEvent, false);
5296    }
5297  }
5298  disconnectStreamSource(source) {
5299    if (this.streamSourceIsConnected(source)) {
5300      this.sources.delete(source);
5301      source.removeEventListener("message", this.receiveMessageEvent, false);
5302    }
5303  }
5304  streamSourceIsConnected(source) {
5305    return this.sources.has(source);
5306  }
5307  inspectFetchResponse = (event) => {
5308    const response = fetchResponseFromEvent(event);
5309    if (response && fetchResponseIsStream(response)) {
5310      event.preventDefault();
5311      this.receiveMessageResponse(response);
5312    }
5313  };
5314  receiveMessageEvent = (event) => {
5315    if (this.#started && typeof event.data == "string") {
5316      this.receiveMessageHTML(event.data);
5317    }
5318  };
5319  async receiveMessageResponse(response) {
5320    const html = await response.responseHTML;
5321    if (html) {
5322      this.receiveMessageHTML(html);
5323    }
5324  }
5325  receiveMessageHTML(html) {
5326    this.delegate.receivedMessageFromStream(StreamMessage.wrap(html));
5327  }
5328};
5329function fetchResponseFromEvent(event) {
5330  const fetchResponse = event.detail?.fetchResponse;
5331  if (fetchResponse instanceof FetchResponse) {
5332    return fetchResponse;
5333  }
5334}
5335function fetchResponseIsStream(response) {
5336  const contentType = response.contentType ?? "";
5337  return contentType.startsWith(StreamMessage.contentType);
5338}
5339var ErrorRenderer = class extends Renderer {
5340  static renderElement(currentElement, newElement) {
5341    const { documentElement, body } = document;
5342    documentElement.replaceChild(newElement, body);
5343  }
5344  async render() {
5345    this.replaceHeadAndBody();
5346    this.activateScriptElements();
5347  }
5348  replaceHeadAndBody() {
5349    const { documentElement, head } = document;
5350    documentElement.replaceChild(this.newHead, head);
5351    this.renderElement(this.currentElement, this.newElement);
5352  }
5353  activateScriptElements() {
5354    for (const replaceableElement of this.scriptElements) {
5355      const parentNode = replaceableElement.parentNode;
5356      if (parentNode) {
5357        const element = activateScriptElement(replaceableElement);
5358        parentNode.replaceChild(element, replaceableElement);
5359      }
5360    }
5361  }
5362  get newHead() {
5363    return this.newSnapshot.headSnapshot.element;
5364  }
5365  get scriptElements() {
5366    return document.documentElement.querySelectorAll("script");
5367  }
5368};
5369var PageRenderer = class extends Renderer {
5370  static renderElement(currentElement, newElement) {
5371    if (document.body && newElement instanceof HTMLBodyElement) {
5372      document.body.replaceWith(newElement);
5373    } else {
5374      document.documentElement.appendChild(newElement);
5375    }
5376  }
5377  get shouldRender() {
5378    return this.newSnapshot.isVisitable && this.trackedElementsAreIdentical;
5379  }
5380  get reloadReason() {
5381    if (!this.newSnapshot.isVisitable) {
5382      return {
5383        reason: "turbo_visit_control_is_reload"
5384      };
5385    }
5386    if (!this.trackedElementsAreIdentical) {
5387      return {
5388        reason: "tracked_element_mismatch"
5389      };
5390    }
5391  }
5392  async prepareToRender() {
5393    this.#setLanguage();
5394    await this.mergeHead();
5395  }
5396  async render() {
5397    if (this.willRender) {
5398      await this.replaceBody();
5399    }
5400  }
5401  finishRendering() {
5402    super.finishRendering();
5403    if (!this.isPreview) {
5404      this.focusFirstAutofocusableElement();
5405    }
5406  }
5407  get currentHeadSnapshot() {
5408    return this.currentSnapshot.headSnapshot;
5409  }
5410  get newHeadSnapshot() {
5411    return this.newSnapshot.headSnapshot;
5412  }
5413  get newElement() {
5414    return this.newSnapshot.element;
5415  }
5416  #setLanguage() {
5417    const { documentElement } = this.currentSnapshot;
5418    const { lang } = this.newSnapshot;
5419    if (lang) {
5420      documentElement.setAttribute("lang", lang);
5421    } else {
5422      documentElement.removeAttribute("lang");
5423    }
5424  }
5425  async mergeHead() {
5426    const mergedHeadElements = this.mergeProvisionalElements();
5427    const newStylesheetElements = this.copyNewHeadStylesheetElements();
5428    this.copyNewHeadScriptElements();
5429    await mergedHeadElements;
5430    await newStylesheetElements;
5431    if (this.willRender) {
5432      this.removeUnusedDynamicStylesheetElements();
5433    }
5434  }
5435  async replaceBody() {
5436    await this.preservingPermanentElements(async () => {
5437      this.activateNewBody();
5438      await this.assignNewBody();
5439    });
5440  }
5441  get trackedElementsAreIdentical() {
5442    return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature;
5443  }
5444  async copyNewHeadStylesheetElements() {
5445    const loadingElements = [];
5446    for (const element of this.newHeadStylesheetElements) {
5447      loadingElements.push(waitForLoad(element));
5448      document.head.appendChild(element);
5449    }
5450    await Promise.all(loadingElements);
5451  }
5452  copyNewHeadScriptElements() {
5453    for (const element of this.newHeadScriptElements) {
5454      document.head.appendChild(activateScriptElement(element));
5455    }
5456  }
5457  removeUnusedDynamicStylesheetElements() {
5458    for (const element of this.unusedDynamicStylesheetElements) {
5459      document.head.removeChild(element);
5460    }
5461  }
5462  async mergeProvisionalElements() {
5463    const newHeadElements = [...this.newHeadProvisionalElements];
5464    for (const element of this.currentHeadProvisionalElements) {
5465      if (!this.isCurrentElementInElementList(element, newHeadElements)) {
5466        document.head.removeChild(element);
5467      }
5468    }
5469    for (const element of newHeadElements) {
5470      document.head.appendChild(element);
5471    }
5472  }
5473  isCurrentElementInElementList(element, elementList) {
5474    for (const [index, newElement] of elementList.entries()) {
5475      if (element.tagName == "TITLE") {
5476        if (newElement.tagName != "TITLE") {
5477          continue;
5478        }
5479        if (element.innerHTML == newElement.innerHTML) {
5480          elementList.splice(index, 1);
5481          return true;
5482        }
5483      }
5484      if (newElement.isEqualNode(element)) {
5485        elementList.splice(index, 1);
5486        return true;
5487      }
5488    }
5489    return false;
5490  }
5491  removeCurrentHeadProvisionalElements() {
5492    for (const element of this.currentHeadProvisionalElements) {
5493      document.head.removeChild(element);
5494    }
5495  }
5496  copyNewHeadProvisionalElements() {
5497    for (const element of this.newHeadProvisionalElements) {
5498      document.head.appendChild(element);
5499    }
5500  }
5501  activateNewBody() {
5502    document.adoptNode(this.newElement);
5503    this.activateNewBodyScriptElements();
5504  }
5505  activateNewBodyScriptElements() {
5506    for (const inertScriptElement of this.newBodyScriptElements) {
5507      const activatedScriptElement = activateScriptElement(inertScriptElement);
5508      inertScriptElement.replaceWith(activatedScriptElement);
5509    }
5510  }
5511  async assignNewBody() {
5512    await this.renderElement(this.currentElement, this.newElement);
5513  }
5514  get unusedDynamicStylesheetElements() {
5515    return this.oldHeadStylesheetElements.filter((element) => {
5516      return element.getAttribute("data-turbo-track") === "dynamic";
5517    });
5518  }
5519  get oldHeadStylesheetElements() {
5520    return this.currentHeadSnapshot.getStylesheetElementsNotInSnapshot(this.newHeadSnapshot);
5521  }
5522  get newHeadStylesheetElements() {
5523    return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot);
5524  }
5525  get newHeadScriptElements() {
5526    return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot);
5527  }
5528  get currentHeadProvisionalElements() {
5529    return this.currentHeadSnapshot.provisionalElements;
5530  }
5531  get newHeadProvisionalElements() {
5532    return this.newHeadSnapshot.provisionalElements;
5533  }
5534  get newBodyScriptElements() {
5535    return this.newElement.querySelectorAll("script");
5536  }
5537};
5538var MorphingPageRenderer = class extends PageRenderer {
5539  static renderElement(currentElement, newElement) {
5540    morphElements(currentElement, newElement, {
5541      callbacks: {
5542        beforeNodeMorphed: (element) => !canRefreshFrame(element)
5543      }
5544    });
5545    for (const frame of currentElement.querySelectorAll("turbo-frame")) {
5546      if (canRefreshFrame(frame)) frame.reload();
5547    }
5548    dispatch("turbo:morph", { detail: { currentElement, newElement } });
5549  }
5550  async preservingPermanentElements(callback) {
5551    return await callback();
5552  }
5553  get renderMethod() {
5554    return "morph";
5555  }
5556  get shouldAutofocus() {
5557    return false;
5558  }
5559};
5560function canRefreshFrame(frame) {
5561  return frame instanceof FrameElement && frame.src && frame.refresh === "morph" && !frame.closest("[data-turbo-permanent]");
5562}
5563var SnapshotCache = class {
5564  keys = [];
5565  snapshots = {};
5566  constructor(size) {
5567    this.size = size;
5568  }
5569  has(location2) {
5570    return toCacheKey(location2) in this.snapshots;
5571  }
5572  get(location2) {
5573    if (this.has(location2)) {
5574      const snapshot = this.read(location2);
5575      this.touch(location2);
5576      return snapshot;
5577    }
5578  }
5579  put(location2, snapshot) {
5580    this.write(location2, snapshot);
5581    this.touch(location2);
5582    return snapshot;
5583  }
5584  clear() {
5585    this.snapshots = {};
5586  }
5587  // Private
5588  read(location2) {
5589    return this.snapshots[toCacheKey(location2)];
5590  }
5591  write(location2, snapshot) {
5592    this.snapshots[toCacheKey(location2)] = snapshot;
5593  }
5594  touch(location2) {
5595    const key = toCacheKey(location2);
5596    const index = this.keys.indexOf(key);
5597    if (index > -1) this.keys.splice(index, 1);
5598    this.keys.unshift(key);
5599    this.trim();
5600  }
5601  trim() {
5602    for (const key of this.keys.splice(this.size)) {
5603      delete this.snapshots[key];
5604    }
5605  }
5606};
5607var PageView = class extends View {
5608  snapshotCache = new SnapshotCache(10);
5609  lastRenderedLocation = new URL(location.href);
5610  forceReloaded = false;
5611  shouldTransitionTo(newSnapshot) {
5612    return this.snapshot.prefersViewTransitions && newSnapshot.prefersViewTransitions;
5613  }
5614  renderPage(snapshot, isPreview = false, willRender = true, visit2) {
5615    const shouldMorphPage = this.isPageRefresh(visit2) && this.snapshot.shouldMorphPage;
5616    const rendererClass = shouldMorphPage ? MorphingPageRenderer : PageRenderer;
5617    const renderer = new rendererClass(this.snapshot, snapshot, isPreview, willRender);
5618    if (!renderer.shouldRender) {
5619      this.forceReloaded = true;
5620    } else {
5621      visit2?.changeHistory();
5622    }
5623    return this.render(renderer);
5624  }
5625  renderError(snapshot, visit2) {
5626    visit2?.changeHistory();
5627    const renderer = new ErrorRenderer(this.snapshot, snapshot, false);
5628    return this.render(renderer);
5629  }
5630  clearSnapshotCache() {
5631    this.snapshotCache.clear();
5632  }
5633  async cacheSnapshot(snapshot = this.snapshot) {
5634    if (snapshot.isCacheable) {
5635      this.delegate.viewWillCacheSnapshot();
5636      const { lastRenderedLocation: location2 } = this;
5637      await nextEventLoopTick();
5638      const cachedSnapshot = snapshot.clone();
5639      this.snapshotCache.put(location2, cachedSnapshot);
5640      return cachedSnapshot;
5641    }
5642  }
5643  getCachedSnapshotForLocation(location2) {
5644    return this.snapshotCache.get(location2);
5645  }
5646  isPageRefresh(visit2) {
5647    return !visit2 || this.lastRenderedLocation.pathname === visit2.location.pathname && visit2.action === "replace";
5648  }
5649  shouldPreserveScrollPosition(visit2) {
5650    return this.isPageRefresh(visit2) && this.snapshot.shouldPreserveScrollPosition;
5651  }
5652  get snapshot() {
5653    return PageSnapshot.fromElement(this.element);
5654  }
5655};
5656var Preloader = class {
5657  selector = "a[data-turbo-preload]";
5658  constructor(delegate, snapshotCache) {
5659    this.delegate = delegate;
5660    this.snapshotCache = snapshotCache;
5661  }
5662  start() {
5663    if (document.readyState === "loading") {
5664      document.addEventListener("DOMContentLoaded", this.#preloadAll);
5665    } else {
5666      this.preloadOnLoadLinksForView(document.body);
5667    }
5668  }
5669  stop() {
5670    document.removeEventListener("DOMContentLoaded", this.#preloadAll);
5671  }
5672  preloadOnLoadLinksForView(element) {
5673    for (const link of element.querySelectorAll(this.selector)) {
5674      if (this.delegate.shouldPreloadLink(link)) {
5675        this.preloadURL(link);
5676      }
5677    }
5678  }
5679  async preloadURL(link) {
5680    const location2 = new URL(link.href);
5681    if (this.snapshotCache.has(location2)) {
5682      return;
5683    }
5684    const fetchRequest = new FetchRequest(this, FetchMethod.get, location2, new URLSearchParams(), link);
5685    await fetchRequest.perform();
5686  }
5687  // Fetch request delegate
5688  prepareRequest(fetchRequest) {
5689    fetchRequest.headers["X-Sec-Purpose"] = "prefetch";
5690  }
5691  async requestSucceededWithResponse(fetchRequest, fetchResponse) {
5692    try {
5693      const responseHTML = await fetchResponse.responseHTML;
5694      const snapshot = PageSnapshot.fromHTMLString(responseHTML);
5695      this.snapshotCache.put(fetchRequest.url, snapshot);
5696    } catch (_) {
5697    }
5698  }
5699  requestStarted(fetchRequest) {
5700  }
5701  requestErrored(fetchRequest) {
5702  }
5703  requestFinished(fetchRequest) {
5704  }
5705  requestPreventedHandlingResponse(fetchRequest, fetchResponse) {
5706  }
5707  requestFailedWithResponse(fetchRequest, fetchResponse) {
5708  }
5709  #preloadAll = () => {
5710    this.preloadOnLoadLinksForView(document.body);
5711  };
5712};
5713var Cache = class {
5714  constructor(session2) {
5715    this.session = session2;
5716  }
5717  clear() {
5718    this.session.clearCache();
5719  }
5720  resetCacheControl() {
5721    this.#setCacheControl("");
5722  }
5723  exemptPageFromCache() {
5724    this.#setCacheControl("no-cache");
5725  }
5726  exemptPageFromPreview() {
5727    this.#setCacheControl("no-preview");
5728  }
5729  #setCacheControl(value) {
5730    setMetaContent("turbo-cache-control", value);
5731  }
5732};
5733var Session = class {
5734  navigator = new Navigator(this);
5735  history = new History(this);
5736  view = new PageView(this, document.documentElement);
5737  adapter = new BrowserAdapter(this);
5738  pageObserver = new PageObserver(this);
5739  cacheObserver = new CacheObserver();
5740  linkPrefetchObserver = new LinkPrefetchObserver(this, document);
5741  linkClickObserver = new LinkClickObserver(this, window);
5742  formSubmitObserver = new FormSubmitObserver(this, document);
5743  scrollObserver = new ScrollObserver(this);
5744  streamObserver = new StreamObserver(this);
5745  formLinkClickObserver = new FormLinkClickObserver(this, document.documentElement);
5746  frameRedirector = new FrameRedirector(this, document.documentElement);
5747  streamMessageRenderer = new StreamMessageRenderer();
5748  cache = new Cache(this);
5749  enabled = true;
5750  started = false;
5751  #pageRefreshDebouncePeriod = 150;
5752  constructor(recentRequests2) {
5753    this.recentRequests = recentRequests2;
5754    this.preloader = new Preloader(this, this.view.snapshotCache);
5755    this.debouncedRefresh = this.refresh;
5756    this.pageRefreshDebouncePeriod = this.pageRefreshDebouncePeriod;
5757  }
5758  start() {
5759    if (!this.started) {
5760      this.pageObserver.start();
5761      this.cacheObserver.start();
5762      this.linkPrefetchObserver.start();
5763      this.formLinkClickObserver.start();
5764      this.linkClickObserver.start();
5765      this.formSubmitObserver.start();
5766      this.scrollObserver.start();
5767      this.streamObserver.start();
5768      this.frameRedirector.start();
5769      this.history.start();
5770      this.preloader.start();
5771      this.started = true;
5772      this.enabled = true;
5773    }
5774  }
5775  disable() {
5776    this.enabled = false;
5777  }
5778  stop() {
5779    if (this.started) {
5780      this.pageObserver.stop();
5781      this.cacheObserver.stop();
5782      this.linkPrefetchObserver.stop();
5783      this.formLinkClickObserver.stop();
5784      this.linkClickObserver.stop();
5785      this.formSubmitObserver.stop();
5786      this.scrollObserver.stop();
5787      this.streamObserver.stop();
5788      this.frameRedirector.stop();
5789      this.history.stop();
5790      this.preloader.stop();
5791      this.started = false;
5792    }
5793  }
5794  registerAdapter(adapter) {
5795    this.adapter = adapter;
5796  }
5797  visit(location2, options = {}) {
5798    const frameElement = options.frame ? document.getElementById(options.frame) : null;
5799    if (frameElement instanceof FrameElement) {
5800      const action = options.action || getVisitAction(frameElement);
5801      frameElement.delegate.proposeVisitIfNavigatedWithAction(frameElement, action);
5802      frameElement.src = location2.toString();
5803    } else {
5804      this.navigator.proposeVisit(expandURL(location2), options);
5805    }
5806  }
5807  refresh(url, requestId) {
5808    const isRecentRequest = requestId && this.recentRequests.has(requestId);
5809    if (!isRecentRequest && !this.navigator.currentVisit) {
5810      this.visit(url, { action: "replace", shouldCacheSnapshot: false });
5811    }
5812  }
5813  connectStreamSource(source) {
5814    this.streamObserver.connectStreamSource(source);
5815  }
5816  disconnectStreamSource(source) {
5817    this.streamObserver.disconnectStreamSource(source);
5818  }
5819  renderStreamMessage(message) {
5820    this.streamMessageRenderer.render(StreamMessage.wrap(message));
5821  }
5822  clearCache() {
5823    this.view.clearSnapshotCache();
5824  }
5825  setProgressBarDelay(delay) {
5826    console.warn(
5827      "Please replace `session.setProgressBarDelay(delay)` with `session.progressBarDelay = delay`. The function is deprecated and will be removed in a future version of Turbo.`"
5828    );
5829    this.progressBarDelay = delay;
5830  }
5831  set progressBarDelay(delay) {
5832    config.drive.progressBarDelay = delay;
5833  }
5834  get progressBarDelay() {
5835    return config.drive.progressBarDelay;
5836  }
5837  set drive(value) {
5838    config.drive.enabled = value;
5839  }
5840  get drive() {
5841    return config.drive.enabled;
5842  }
5843  set formMode(value) {
5844    config.forms.mode = value;
5845  }
5846  get formMode() {
5847    return config.forms.mode;
5848  }
5849  get location() {
5850    return this.history.location;
5851  }
5852  get restorationIdentifier() {
5853    return this.history.restorationIdentifier;
5854  }
5855  get pageRefreshDebouncePeriod() {
5856    return this.#pageRefreshDebouncePeriod;
5857  }
5858  set pageRefreshDebouncePeriod(value) {
5859    this.refresh = debounce(this.debouncedRefresh.bind(this), value);
5860    this.#pageRefreshDebouncePeriod = value;
5861  }
5862  // Preloader delegate
5863  shouldPreloadLink(element) {
5864    const isUnsafe = element.hasAttribute("data-turbo-method");
5865    const isStream = element.hasAttribute("data-turbo-stream");
5866    const frameTarget = element.getAttribute("data-turbo-frame");
5867    const frame = frameTarget == "_top" ? null : document.getElementById(frameTarget) || findClosestRecursively(element, "turbo-frame:not([disabled])");
5868    if (isUnsafe || isStream || frame instanceof FrameElement) {
5869      return false;
5870    } else {
5871      const location2 = new URL(element.href);
5872      return this.elementIsNavigatable(element) && locationIsVisitable(location2, this.snapshot.rootLocation);
5873    }
5874  }
5875  // History delegate
5876  historyPoppedToLocationWithRestorationIdentifierAndDirection(location2, restorationIdentifier, direction) {
5877    if (this.enabled) {
5878      this.navigator.startVisit(location2, restorationIdentifier, {
5879        action: "restore",
5880        historyChanged: true,
5881        direction
5882      });
5883    } else {
5884      this.adapter.pageInvalidated({
5885        reason: "turbo_disabled"
5886      });
5887    }
5888  }
5889  // Scroll observer delegate
5890  scrollPositionChanged(position) {
5891    this.history.updateRestorationData({ scrollPosition: position });
5892  }
5893  // Form click observer delegate
5894  willSubmitFormLinkToLocation(link, location2) {
5895    return this.elementIsNavigatable(link) && locationIsVisitable(location2, this.snapshot.rootLocation);
5896  }
5897  submittedFormLinkToLocation() {
5898  }
5899  // Link hover observer delegate
5900  canPrefetchRequestToLocation(link, location2) {
5901    return this.elementIsNavigatable(link) && locationIsVisitable(location2, this.snapshot.rootLocation);
5902  }
5903  // Link click observer delegate
5904  willFollowLinkToLocation(link, location2, event) {
5905    return this.elementIsNavigatable(link) && locationIsVisitable(location2, this.snapshot.rootLocation) && this.applicationAllowsFollowingLinkToLocation(link, location2, event);
5906  }
5907  followedLinkToLocation(link, location2) {
5908    const action = this.getActionForLink(link);
5909    const acceptsStreamResponse = link.hasAttribute("data-turbo-stream");
5910    this.visit(location2.href, { action, acceptsStreamResponse });
5911  }
5912  // Navigator delegate
5913  allowsVisitingLocationWithAction(location2, action) {
5914    return this.locationWithActionIsSamePage(location2, action) || this.applicationAllowsVisitingLocation(location2);
5915  }
5916  visitProposedToLocation(location2, options) {
5917    extendURLWithDeprecatedProperties(location2);
5918    this.adapter.visitProposedToLocation(location2, options);
5919  }
5920  // Visit delegate
5921  visitStarted(visit2) {
5922    if (!visit2.acceptsStreamResponse) {
5923      markAsBusy(document.documentElement);
5924      this.view.markVisitDirection(visit2.direction);
5925    }
5926    extendURLWithDeprecatedProperties(visit2.location);
5927    if (!visit2.silent) {
5928      this.notifyApplicationAfterVisitingLocation(visit2.location, visit2.action);
5929    }
5930  }
5931  visitCompleted(visit2) {
5932    this.view.unmarkVisitDirection();
5933    clearBusyState(document.documentElement);
5934    this.notifyApplicationAfterPageLoad(visit2.getTimingMetrics());
5935  }
5936  locationWithActionIsSamePage(location2, action) {
5937    return this.navigator.locationWithActionIsSamePage(location2, action);
5938  }
5939  visitScrolledToSamePageLocation(oldURL, newURL) {
5940    this.notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL);
5941  }
5942  // Form submit observer delegate
5943  willSubmitForm(form, submitter2) {
5944    const action = getAction$1(form, submitter2);
5945    return this.submissionIsNavigatable(form, submitter2) && locationIsVisitable(expandURL(action), this.snapshot.rootLocation);
5946  }
5947  formSubmitted(form, submitter2) {
5948    this.navigator.submitForm(form, submitter2);
5949  }
5950  // Page observer delegate
5951  pageBecameInteractive() {
5952    this.view.lastRenderedLocation = this.location;
5953    this.notifyApplicationAfterPageLoad();
5954  }
5955  pageLoaded() {
5956    this.history.assumeControlOfScrollRestoration();
5957  }
5958  pageWillUnload() {
5959    this.history.relinquishControlOfScrollRestoration();
5960  }
5961  // Stream observer delegate
5962  receivedMessageFromStream(message) {
5963    this.renderStreamMessage(message);
5964  }
5965  // Page view delegate
5966  viewWillCacheSnapshot() {
5967    if (!this.navigator.currentVisit?.silent) {
5968      this.notifyApplicationBeforeCachingSnapshot();
5969    }
5970  }
5971  allowsImmediateRender({ element }, options) {
5972    const event = this.notifyApplicationBeforeRender(element, options);
5973    const {
5974      defaultPrevented,
5975      detail: { render }
5976    } = event;
5977    if (this.view.renderer && render) {
5978      this.view.renderer.renderElement = render;
5979    }
5980    return !defaultPrevented;
5981  }
5982  viewRenderedSnapshot(_snapshot, _isPreview, renderMethod) {
5983    this.view.lastRenderedLocation = this.history.location;
5984    this.notifyApplicationAfterRender(renderMethod);
5985  }
5986  preloadOnLoadLinksForView(element) {
5987    this.preloader.preloadOnLoadLinksForView(element);
5988  }
5989  viewInvalidated(reason) {
5990    this.adapter.pageInvalidated(reason);
5991  }
5992  // Frame element
5993  frameLoaded(frame) {
5994    this.notifyApplicationAfterFrameLoad(frame);
5995  }
5996  frameRendered(fetchResponse, frame) {
5997    this.notifyApplicationAfterFrameRender(fetchResponse, frame);
5998  }
5999  // Application events
6000  applicationAllowsFollowingLinkToLocation(link, location2, ev) {
6001    const event = this.notifyApplicationAfterClickingLinkToLocation(link, location2, ev);
6002    return !event.defaultPrevented;
6003  }
6004  applicationAllowsVisitingLocation(location2) {
6005    const event = this.notifyApplicationBeforeVisitingLocation(location2);
6006    return !event.defaultPrevented;
6007  }
6008  notifyApplicationAfterClickingLinkToLocation(link, location2, event) {
6009    return dispatch("turbo:click", {
6010      target: link,
6011      detail: { url: location2.href, originalEvent: event },
6012      cancelable: true
6013    });
6014  }
6015  notifyApplicationBeforeVisitingLocation(location2) {
6016    return dispatch("turbo:before-visit", {
6017      detail: { url: location2.href },
6018      cancelable: true
6019    });
6020  }
6021  notifyApplicationAfterVisitingLocation(location2, action) {
6022    return dispatch("turbo:visit", { detail: { url: location2.href, action } });
6023  }
6024  notifyApplicationBeforeCachingSnapshot() {
6025    return dispatch("turbo:before-cache");
6026  }
6027  notifyApplicationBeforeRender(newBody, options) {
6028    return dispatch("turbo:before-render", {
6029      detail: { newBody, ...options },
6030      cancelable: true
6031    });
6032  }
6033  notifyApplicationAfterRender(renderMethod) {
6034    return dispatch("turbo:render", { detail: { renderMethod } });
6035  }
6036  notifyApplicationAfterPageLoad(timing = {}) {
6037    return dispatch("turbo:load", {
6038      detail: { url: this.location.href, timing }
6039    });
6040  }
6041  notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL) {
6042    dispatchEvent(
6043      new HashChangeEvent("hashchange", {
6044        oldURL: oldURL.toString(),
6045        newURL: newURL.toString()
6046      })
6047    );
6048  }
6049  notifyApplicationAfterFrameLoad(frame) {
6050    return dispatch("turbo:frame-load", { target: frame });
6051  }
6052  notifyApplicationAfterFrameRender(fetchResponse, frame) {
6053    return dispatch("turbo:frame-render", {
6054      detail: { fetchResponse },
6055      target: frame,
6056      cancelable: true
6057    });
6058  }
6059  // Helpers
6060  submissionIsNavigatable(form, submitter2) {
6061    if (config.forms.mode == "off") {
6062      return false;
6063    } else {
6064      const submitterIsNavigatable = submitter2 ? this.elementIsNavigatable(submitter2) : true;
6065      if (config.forms.mode == "optin") {
6066        return submitterIsNavigatable && form.closest('[data-turbo="true"]') != null;
6067      } else {
6068        return submitterIsNavigatable && this.elementIsNavigatable(form);
6069      }
6070    }
6071  }
6072  elementIsNavigatable(element) {
6073    const container = findClosestRecursively(element, "[data-turbo]");
6074    const withinFrame = findClosestRecursively(element, "turbo-frame");
6075    if (config.drive.enabled || withinFrame) {
6076      if (container) {
6077        return container.getAttribute("data-turbo") != "false";
6078      } else {
6079        return true;
6080      }
6081    } else {
6082      if (container) {
6083        return container.getAttribute("data-turbo") == "true";
6084      } else {
6085        return false;
6086      }
6087    }
6088  }
6089  // Private
6090  getActionForLink(link) {
6091    return getVisitAction(link) || "advance";
6092  }
6093  get snapshot() {
6094    return this.view.snapshot;
6095  }
6096};
6097function extendURLWithDeprecatedProperties(url) {
6098  Object.defineProperties(url, deprecatedLocationPropertyDescriptors);
6099}
6100var deprecatedLocationPropertyDescriptors = {
6101  absoluteURL: {
6102    get() {
6103      return this.toString();
6104    }
6105  }
6106};
6107var session = new Session(recentRequests);
6108var { cache, navigator: navigator$1 } = session;
6109function start() {
6110  session.start();
6111}
6112function registerAdapter(adapter) {
6113  session.registerAdapter(adapter);
6114}
6115function visit(location2, options) {
6116  session.visit(location2, options);
6117}
6118function connectStreamSource(source) {
6119  session.connectStreamSource(source);
6120}
6121function disconnectStreamSource(source) {
6122  session.disconnectStreamSource(source);
6123}
6124function renderStreamMessage(message) {
6125  session.renderStreamMessage(message);
6126}
6127function clearCache() {
6128  console.warn(
6129    "Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`"
6130  );
6131  session.clearCache();
6132}
6133function setProgressBarDelay(delay) {
6134  console.warn(
6135    "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.`"
6136  );
6137  config.drive.progressBarDelay = delay;
6138}
6139function setConfirmMethod(confirmMethod) {
6140  console.warn(
6141    "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.`"
6142  );
6143  config.forms.confirm = confirmMethod;
6144}
6145function setFormMode(mode) {
6146  console.warn(
6147    "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.`"
6148  );
6149  config.forms.mode = mode;
6150}
6151var Turbo2 = /* @__PURE__ */ Object.freeze({
6152  __proto__: null,
6153  navigator: navigator$1,
6154  session,
6155  cache,
6156  PageRenderer,
6157  PageSnapshot,
6158  FrameRenderer,
6159  fetch: fetchWithTurboHeaders,
6160  config,
6161  start,
6162  registerAdapter,
6163  visit,
6164  connectStreamSource,
6165  disconnectStreamSource,
6166  renderStreamMessage,
6167  clearCache,
6168  setProgressBarDelay,
6169  setConfirmMethod,
6170  setFormMode
6171});
6172var TurboFrameMissingError = class extends Error {
6173};
6174var FrameController = class {
6175  fetchResponseLoaded = (_fetchResponse) => Promise.resolve();
6176  #currentFetchRequest = null;
6177  #resolveVisitPromise = () => {
6178  };
6179  #connected = false;
6180  #hasBeenLoaded = false;
6181  #ignoredAttributes = /* @__PURE__ */ new Set();
6182  #shouldMorphFrame = false;
6183  action = null;
6184  constructor(element) {
6185    this.element = element;
6186    this.view = new FrameView(this, this.element);
6187    this.appearanceObserver = new AppearanceObserver(this, this.element);
6188    this.formLinkClickObserver = new FormLinkClickObserver(this, this.element);
6189    this.linkInterceptor = new LinkInterceptor(this, this.element);
6190    this.restorationIdentifier = uuid();
6191    this.formSubmitObserver = new FormSubmitObserver(this, this.element);
6192  }
6193  // Frame delegate
6194  connect() {
6195    if (!this.#connected) {
6196      this.#connected = true;
6197      if (this.loadingStyle == FrameLoadingStyle.lazy) {
6198        this.appearanceObserver.start();
6199      } else {
6200        this.#loadSourceURL();
6201      }
6202      this.formLinkClickObserver.start();
6203      this.linkInterceptor.start();
6204      this.formSubmitObserver.start();
6205    }
6206  }
6207  disconnect() {
6208    if (this.#connected) {
6209      this.#connected = false;
6210      this.appearanceObserver.stop();
6211      this.formLinkClickObserver.stop();
6212      this.linkInterceptor.stop();
6213      this.formSubmitObserver.stop();
6214    }
6215  }
6216  disabledChanged() {
6217    if (this.loadingStyle == FrameLoadingStyle.eager) {
6218      this.#loadSourceURL();
6219    }
6220  }
6221  sourceURLChanged() {
6222    if (this.#isIgnoringChangesTo("src")) return;
6223    if (this.element.isConnected) {
6224      this.complete = false;
6225    }
6226    if (this.loadingStyle == FrameLoadingStyle.eager || this.#hasBeenLoaded) {
6227      this.#loadSourceURL();
6228    }
6229  }
6230  sourceURLReloaded() {
6231    const { refresh, src } = this.element;
6232    this.#shouldMorphFrame = src && refresh === "morph";
6233    this.element.removeAttribute("complete");
6234    this.element.src = null;
6235    this.element.src = src;
6236    return this.element.loaded;
6237  }
6238  loadingStyleChanged() {
6239    if (this.loadingStyle == FrameLoadingStyle.lazy) {
6240      this.appearanceObserver.start();
6241    } else {
6242      this.appearanceObserver.stop();
6243      this.#loadSourceURL();
6244    }
6245  }
6246  async #loadSourceURL() {
6247    if (this.enabled && this.isActive && !this.complete && this.sourceURL) {
6248      this.element.loaded = this.#visit(expandURL(this.sourceURL));
6249      this.appearanceObserver.stop();
6250      await this.element.loaded;
6251      this.#hasBeenLoaded = true;
6252    }
6253  }
6254  async loadResponse(fetchResponse) {
6255    if (fetchResponse.redirected || fetchResponse.succeeded && fetchResponse.isHTML) {
6256      this.sourceURL = fetchResponse.response.url;
6257    }
6258    try {
6259      const html = await fetchResponse.responseHTML;
6260      if (html) {
6261        const document2 = parseHTMLDocument(html);
6262        const pageSnapshot = PageSnapshot.fromDocument(document2);
6263        if (pageSnapshot.isVisitable) {
6264          await this.#loadFrameResponse(fetchResponse, document2);
6265        } else {
6266          await this.#handleUnvisitableFrameResponse(fetchResponse);
6267        }
6268      }
6269    } finally {
6270      this.#shouldMorphFrame = false;
6271      this.fetchResponseLoaded = () => Promise.resolve();
6272    }
6273  }
6274  // Appearance observer delegate
6275  elementAppearedInViewport(element) {
6276    this.proposeVisitIfNavigatedWithAction(element, getVisitAction(element));
6277    this.#loadSourceURL();
6278  }
6279  // Form link click observer delegate
6280  willSubmitFormLinkToLocation(link) {
6281    return this.#shouldInterceptNavigation(link);
6282  }
6283  submittedFormLinkToLocation(link, _location, form) {
6284    const frame = this.#findFrameElement(link);
6285    if (frame) form.setAttribute("data-turbo-frame", frame.id);
6286  }
6287  // Link interceptor delegate
6288  shouldInterceptLinkClick(element, _location, _event) {
6289    return this.#shouldInterceptNavigation(element);
6290  }
6291  linkClickIntercepted(element, location2) {
6292    this.#navigateFrame(element, location2);
6293  }
6294  // Form submit observer delegate
6295  willSubmitForm(element, submitter2) {
6296    return element.closest("turbo-frame") == this.element && this.#shouldInterceptNavigation(element, submitter2);
6297  }
6298  formSubmitted(element, submitter2) {
6299    if (this.formSubmission) {
6300      this.formSubmission.stop();
6301    }
6302    this.formSubmission = new FormSubmission(this, element, submitter2);
6303    const { fetchRequest } = this.formSubmission;
6304    this.prepareRequest(fetchRequest);
6305    this.formSubmission.start();
6306  }
6307  // Fetch request delegate
6308  prepareRequest(request) {
6309    request.headers["Turbo-Frame"] = this.id;
6310    if (this.currentNavigationElement?.hasAttribute("data-turbo-stream")) {
6311      request.acceptResponseType(StreamMessage.contentType);
6312    }
6313  }
6314  requestStarted(_request) {
6315    markAsBusy(this.element);
6316  }
6317  requestPreventedHandlingResponse(_request, _response) {
6318    this.#resolveVisitPromise();
6319  }
6320  async requestSucceededWithResponse(request, response) {
6321    await this.loadResponse(response);
6322    this.#resolveVisitPromise();
6323  }
6324  async requestFailedWithResponse(request, response) {
6325    await this.loadResponse(response);
6326    this.#resolveVisitPromise();
6327  }
6328  requestErrored(request, error2) {
6329    console.error(error2);
6330    this.#resolveVisitPromise();
6331  }
6332  requestFinished(_request) {
6333    clearBusyState(this.element);
6334  }
6335  // Form submission delegate
6336  formSubmissionStarted({ formElement }) {
6337    markAsBusy(formElement, this.#findFrameElement(formElement));
6338  }
6339  formSubmissionSucceededWithResponse(formSubmission, response) {
6340    const frame = this.#findFrameElement(formSubmission.formElement, formSubmission.submitter);
6341    frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(formSubmission.submitter, formSubmission.formElement, frame));
6342    frame.delegate.loadResponse(response);
6343    if (!formSubmission.isSafe) {
6344      session.clearCache();
6345    }
6346  }
6347  formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
6348    this.element.delegate.loadResponse(fetchResponse);
6349    session.clearCache();
6350  }
6351  formSubmissionErrored(formSubmission, error2) {
6352    console.error(error2);
6353  }
6354  formSubmissionFinished({ formElement }) {
6355    clearBusyState(formElement, this.#findFrameElement(formElement));
6356  }
6357  // View delegate
6358  allowsImmediateRender({ element: newFrame }, options) {
6359    const event = dispatch("turbo:before-frame-render", {
6360      target: this.element,
6361      detail: { newFrame, ...options },
6362      cancelable: true
6363    });
6364    const {
6365      defaultPrevented,
6366      detail: { render }
6367    } = event;
6368    if (this.view.renderer && render) {
6369      this.view.renderer.renderElement = render;
6370    }
6371    return !defaultPrevented;
6372  }
6373  viewRenderedSnapshot(_snapshot, _isPreview, _renderMethod) {
6374  }
6375  preloadOnLoadLinksForView(element) {
6376    session.preloadOnLoadLinksForView(element);
6377  }
6378  viewInvalidated() {
6379  }
6380  // Frame renderer delegate
6381  willRenderFrame(currentElement, _newElement) {
6382    this.previousFrameElement = currentElement.cloneNode(true);
6383  }
6384  visitCachedSnapshot = ({ element }) => {
6385    const frame = element.querySelector("#" + this.element.id);
6386    if (frame && this.previousFrameElement) {
6387      frame.replaceChildren(...this.previousFrameElement.children);
6388    }
6389    delete this.previousFrameElement;
6390  };
6391  // Private
6392  async #loadFrameResponse(fetchResponse, document2) {
6393    const newFrameElement = await this.extractForeignFrameElement(document2.body);
6394    const rendererClass = this.#shouldMorphFrame ? MorphingFrameRenderer : FrameRenderer;
6395    if (newFrameElement) {
6396      const snapshot = new Snapshot(newFrameElement);
6397      const renderer = new rendererClass(this, this.view.snapshot, snapshot, false, false);
6398      if (this.view.renderPromise) await this.view.renderPromise;
6399      this.changeHistory();
6400      await this.view.render(renderer);
6401      this.complete = true;
6402      session.frameRendered(fetchResponse, this.element);
6403      session.frameLoaded(this.element);
6404      await this.fetchResponseLoaded(fetchResponse);
6405    } else if (this.#willHandleFrameMissingFromResponse(fetchResponse)) {
6406      this.#handleFrameMissingFromResponse(fetchResponse);
6407    }
6408  }
6409  async #visit(url) {
6410    const request = new FetchRequest(this, FetchMethod.get, url, new URLSearchParams(), this.element);
6411    this.#currentFetchRequest?.cancel();
6412    this.#currentFetchRequest = request;
6413    return new Promise((resolve) => {
6414      this.#resolveVisitPromise = () => {
6415        this.#resolveVisitPromise = () => {
6416        };
6417        this.#currentFetchRequest = null;
6418        resolve();
6419      };
6420      request.perform();
6421    });
6422  }
6423  #navigateFrame(element, url, submitter2) {
6424    const frame = this.#findFrameElement(element, submitter2);
6425    frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(submitter2, element, frame));
6426    this.#withCurrentNavigationElement(element, () => {
6427      frame.src = url;
6428    });
6429  }
6430  proposeVisitIfNavigatedWithAction(frame, action = null) {
6431    this.action = action;
6432    if (this.action) {
6433      const pageSnapshot = PageSnapshot.fromElement(frame).clone();
6434      const { visitCachedSnapshot } = frame.delegate;
6435      frame.delegate.fetchResponseLoaded = async (fetchResponse) => {
6436        if (frame.src) {
6437          const { statusCode, redirected } = fetchResponse;
6438          const responseHTML = await fetchResponse.responseHTML;
6439          const response = { statusCode, redirected, responseHTML };
6440          const options = {
6441            response,
6442            visitCachedSnapshot,
6443            willRender: false,
6444            updateHistory: false,
6445            restorationIdentifier: this.restorationIdentifier,
6446            snapshot: pageSnapshot
6447          };
6448          if (this.action) options.action = this.action;
6449          session.visit(frame.src, options);
6450        }
6451      };
6452    }
6453  }
6454  changeHistory() {
6455    if (this.action) {
6456      const method = getHistoryMethodForAction(this.action);
6457      session.history.update(method, expandURL(this.element.src || ""), this.restorationIdentifier);
6458    }
6459  }
6460  async #handleUnvisitableFrameResponse(fetchResponse) {
6461    console.warn(
6462      `The response (${fetchResponse.statusCode}) from <turbo-frame id="${this.element.id}"> is performing a full page visit due to turbo-visit-control.`
6463    );
6464    await this.#visitResponse(fetchResponse.response);
6465  }
6466  #willHandleFrameMissingFromResponse(fetchResponse) {
6467    this.element.setAttribute("complete", "");
6468    const response = fetchResponse.response;
6469    const visit2 = async (url, options) => {
6470      if (url instanceof Response) {
6471        this.#visitResponse(url);
6472      } else {
6473        session.visit(url, options);
6474      }
6475    };
6476    const event = dispatch("turbo:frame-missing", {
6477      target: this.element,
6478      detail: { response, visit: visit2 },
6479      cancelable: true
6480    });
6481    return !event.defaultPrevented;
6482  }
6483  #handleFrameMissingFromResponse(fetchResponse) {
6484    this.view.missing();
6485    this.#throwFrameMissingError(fetchResponse);
6486  }
6487  #throwFrameMissingError(fetchResponse) {
6488    const message = `The response (${fetchResponse.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.`;
6489    throw new TurboFrameMissingError(message);
6490  }
6491  async #visitResponse(response) {
6492    const wrapped = new FetchResponse(response);
6493    const responseHTML = await wrapped.responseHTML;
6494    const { location: location2, redirected, statusCode } = wrapped;
6495    return session.visit(location2, { response: { redirected, statusCode, responseHTML } });
6496  }
6497  #findFrameElement(element, submitter2) {
6498    const id = getAttribute("data-turbo-frame", submitter2, element) || this.element.getAttribute("target");
6499    return getFrameElementById(id) ?? this.element;
6500  }
6501  async extractForeignFrameElement(container) {
6502    let element;
6503    const id = CSS.escape(this.id);
6504    try {
6505      element = activateElement(container.querySelector(`turbo-frame#${id}`), this.sourceURL);
6506      if (element) {
6507        return element;
6508      }
6509      element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.sourceURL);
6510      if (element) {
6511        await element.loaded;
6512        return await this.extractForeignFrameElement(element);
6513      }
6514    } catch (error2) {
6515      console.error(error2);
6516      return new FrameElement();
6517    }
6518    return null;
6519  }
6520  #formActionIsVisitable(form, submitter2) {
6521    const action = getAction$1(form, submitter2);
6522    return locationIsVisitable(expandURL(action), this.rootLocation);
6523  }
6524  #shouldInterceptNavigation(element, submitter2) {
6525    const id = getAttribute("data-turbo-frame", submitter2, element) || this.element.getAttribute("target");
6526    if (element instanceof HTMLFormElement && !this.#formActionIsVisitable(element, submitter2)) {
6527      return false;
6528    }
6529    if (!this.enabled || id == "_top") {
6530      return false;
6531    }
6532    if (id) {
6533      const frameElement = getFrameElementById(id);
6534      if (frameElement) {
6535        return !frameElement.disabled;
6536      }
6537    }
6538    if (!session.elementIsNavigatable(element)) {
6539      return false;
6540    }
6541    if (submitter2 && !session.elementIsNavigatable(submitter2)) {
6542      return false;
6543    }
6544    return true;
6545  }
6546  // Computed properties
6547  get id() {
6548    return this.element.id;
6549  }
6550  get enabled() {
6551    return !this.element.disabled;
6552  }
6553  get sourceURL() {
6554    if (this.element.src) {
6555      return this.element.src;
6556    }
6557  }
6558  set sourceURL(sourceURL) {
6559    this.#ignoringChangesToAttribute("src", () => {
6560      this.element.src = sourceURL ?? null;
6561    });
6562  }
6563  get loadingStyle() {
6564    return this.element.loading;
6565  }
6566  get isLoading() {
6567    return this.formSubmission !== void 0 || this.#resolveVisitPromise() !== void 0;
6568  }
6569  get complete() {
6570    return this.element.hasAttribute("complete");
6571  }
6572  set complete(value) {
6573    if (value) {
6574      this.element.setAttribute("complete", "");
6575    } else {
6576      this.element.removeAttribute("complete");
6577    }
6578  }
6579  get isActive() {
6580    return this.element.isActive && this.#connected;
6581  }
6582  get rootLocation() {
6583    const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`);
6584    const root = meta?.content ?? "/";
6585    return expandURL(root);
6586  }
6587  #isIgnoringChangesTo(attributeName) {
6588    return this.#ignoredAttributes.has(attributeName);
6589  }
6590  #ignoringChangesToAttribute(attributeName, callback) {
6591    this.#ignoredAttributes.add(attributeName);
6592    callback();
6593    this.#ignoredAttributes.delete(attributeName);
6594  }
6595  #withCurrentNavigationElement(element, callback) {
6596    this.currentNavigationElement = element;
6597    callback();
6598    delete this.currentNavigationElement;
6599  }
6600};
6601function getFrameElementById(id) {
6602  if (id != null) {
6603    const element = document.getElementById(id);
6604    if (element instanceof FrameElement) {
6605      return element;
6606    }
6607  }
6608}
6609function activateElement(element, currentURL) {
6610  if (element) {
6611    const src = element.getAttribute("src");
6612    if (src != null && currentURL != null && urlsAreEqual(src, currentURL)) {
6613      throw new Error(`Matching <turbo-frame id="${element.id}"> element has a source URL which references itself`);
6614    }
6615    if (element.ownerDocument !== document) {
6616      element = document.importNode(element, true);
6617    }
6618    if (element instanceof FrameElement) {
6619      element.connectedCallback();
6620      element.disconnectedCallback();
6621      return element;
6622    }
6623  }
6624}
6625var StreamActions = {
6626  after() {
6627    this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e.nextSibling));
6628  },
6629  append() {
6630    this.removeDuplicateTargetChildren();
6631    this.targetElements.forEach((e) => e.append(this.templateContent));
6632  },
6633  before() {
6634    this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e));
6635  },
6636  prepend() {
6637    this.removeDuplicateTargetChildren();
6638    this.targetElements.forEach((e) => e.prepend(this.templateContent));
6639  },
6640  remove() {
6641    this.targetElements.forEach((e) => e.remove());
6642  },
6643  replace() {
6644    const method = this.getAttribute("method");
6645    this.targetElements.forEach((targetElement) => {
6646      if (method === "morph") {
6647        morphElements(targetElement, this.templateContent);
6648      } else {
6649        targetElement.replaceWith(this.templateContent);
6650      }
6651    });
6652  },
6653  update() {
6654    const method = this.getAttribute("method");
6655    this.targetElements.forEach((targetElement) => {
6656      if (method === "morph") {
6657        morphChildren(targetElement, this.templateContent);
6658      } else {
6659        targetElement.innerHTML = "";
6660        targetElement.append(this.templateContent);
6661      }
6662    });
6663  },
6664  refresh() {
6665    session.refresh(this.baseURI, this.requestId);
6666  }
6667};
6668var StreamElement = class _StreamElement extends HTMLElement {
6669  static async renderElement(newElement) {
6670    await newElement.performAction();
6671  }
6672  async connectedCallback() {
6673    try {
6674      await this.render();
6675    } catch (error2) {
6676      console.error(error2);
6677    } finally {
6678      this.disconnect();
6679    }
6680  }
6681  async render() {
6682    return this.renderPromise ??= (async () => {
6683      const event = this.beforeRenderEvent;
6684      if (this.dispatchEvent(event)) {
6685        await nextRepaint();
6686        await event.detail.render(this);
6687      }
6688    })();
6689  }
6690  disconnect() {
6691    try {
6692      this.remove();
6693    } catch {
6694    }
6695  }
6696  /**
6697   * Removes duplicate children (by ID)
6698   */
6699  removeDuplicateTargetChildren() {
6700    this.duplicateChildren.forEach((c) => c.remove());
6701  }
6702  /**
6703   * Gets the list of duplicate children (i.e. those with the same ID)
6704   */
6705  get duplicateChildren() {
6706    const existingChildren = this.targetElements.flatMap((e) => [...e.children]).filter((c) => !!c.id);
6707    const newChildrenIds = [...this.templateContent?.children || []].filter((c) => !!c.id).map((c) => c.id);
6708    return existingChildren.filter((c) => newChildrenIds.includes(c.id));
6709  }
6710  /**
6711   * Gets the action function to be performed.
6712   */
6713  get performAction() {
6714    if (this.action) {
6715      const actionFunction = StreamActions[this.action];
6716      if (actionFunction) {
6717        return actionFunction;
6718      }
6719      this.#raise("unknown action");
6720    }
6721    this.#raise("action attribute is missing");
6722  }
6723  /**
6724   * Gets the target elements which the template will be rendered to.
6725   */
6726  get targetElements() {
6727    if (this.target) {
6728      return this.targetElementsById;
6729    } else if (this.targets) {
6730      return this.targetElementsByQuery;
6731    } else {
6732      this.#raise("target or targets attribute is missing");
6733    }
6734  }
6735  /**
6736   * Gets the contents of the main `<template>`.
6737   */
6738  get templateContent() {
6739    return this.templateElement.content.cloneNode(true);
6740  }
6741  /**
6742   * Gets the main `<template>` used for rendering
6743   */
6744  get templateElement() {
6745    if (this.firstElementChild === null) {
6746      const template = this.ownerDocument.createElement("template");
6747      this.appendChild(template);
6748      return template;
6749    } else if (this.firstElementChild instanceof HTMLTemplateElement) {
6750      return this.firstElementChild;
6751    }
6752    this.#raise("first child element must be a <template> element");
6753  }
6754  /**
6755   * Gets the current action.
6756   */
6757  get action() {
6758    return this.getAttribute("action");
6759  }
6760  /**
6761   * Gets the current target (an element ID) to which the result will
6762   * be rendered.
6763   */
6764  get target() {
6765    return this.getAttribute("target");
6766  }
6767  /**
6768   * Gets the current "targets" selector (a CSS selector)
6769   */
6770  get targets() {
6771    return this.getAttribute("targets");
6772  }
6773  /**
6774   * Reads the request-id attribute
6775   */
6776  get requestId() {
6777    return this.getAttribute("request-id");
6778  }
6779  #raise(message) {
6780    throw new Error(`${this.description}: ${message}`);
6781  }
6782  get description() {
6783    return (this.outerHTML.match(/<[^>]+>/) ?? [])[0] ?? "<turbo-stream>";
6784  }
6785  get beforeRenderEvent() {
6786    return new CustomEvent("turbo:before-stream-render", {
6787      bubbles: true,
6788      cancelable: true,
6789      detail: { newStream: this, render: _StreamElement.renderElement }
6790    });
6791  }
6792  get targetElementsById() {
6793    const element = this.ownerDocument?.getElementById(this.target);
6794    if (element !== null) {
6795      return [element];
6796    } else {
6797      return [];
6798    }
6799  }
6800  get targetElementsByQuery() {
6801    const elements = this.ownerDocument?.querySelectorAll(this.targets);
6802    if (elements.length !== 0) {
6803      return Array.prototype.slice.call(elements);
6804    } else {
6805      return [];
6806    }
6807  }
6808};
6809var StreamSourceElement = class extends HTMLElement {
6810  streamSource = null;
6811  connectedCallback() {
6812    this.streamSource = this.src.match(/^ws{1,2}:/) ? new WebSocket(this.src) : new EventSource(this.src);
6813    connectStreamSource(this.streamSource);
6814  }
6815  disconnectedCallback() {
6816    if (this.streamSource) {
6817      this.streamSource.close();
6818      disconnectStreamSource(this.streamSource);
6819    }
6820  }
6821  get src() {
6822    return this.getAttribute("src") || "";
6823  }
6824};
6825FrameElement.delegateConstructor = FrameController;
6826if (customElements.get("turbo-frame") === void 0) {
6827  customElements.define("turbo-frame", FrameElement);
6828}
6829if (customElements.get("turbo-stream") === void 0) {
6830  customElements.define("turbo-stream", StreamElement);
6831}
6832if (customElements.get("turbo-stream-source") === void 0) {
6833  customElements.define("turbo-stream-source", StreamSourceElement);
6834}
6835(() => {
6836  let element = document.currentScript;
6837  if (!element) return;
6838  if (element.hasAttribute("data-turbo-suppress-warning")) return;
6839  element = element.parentElement;
6840  while (element) {
6841    if (element == document.body) {
6842      return console.warn(
6843        unindent`
6844        You are loading Turbo from a <script> element inside the <body> element. This is probably not what you meant to do!
6845
6846        Load your application’s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.
6847
6848        For more information, see: https://turbo.hotwired.dev/handbook/building#working-with-script-elements
6849
6850        ——
6851        Suppress this warning by adding a "data-turbo-suppress-warning" attribute to: %s
6852      `,
6853        element.outerHTML
6854      );
6855    }
6856    element = element.parentElement;
6857  }
6858})();
6859window.Turbo = { ...Turbo2, StreamActions };
6860start();
6861
vendor: 575 bytes, lines 6862-6878
6862// node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable.js
6863var consumer;
6864async function getConsumer() {
6865  return consumer || setConsumer(createConsumer2().then(setConsumer));
6866}
6867function setConsumer(newConsumer) {
6868  return consumer = newConsumer;
6869}
6870async function createConsumer2() {
6871  const { createConsumer: createConsumer3 } = await Promise.resolve().then(() => (init_src(), src_exports));
6872  return createConsumer3();
6873}
6874async function subscribeTo(channel, mixin) {
6875  const { subscriptions } = await getConsumer();
6876  return subscriptions.create(channel, mixin);
6877}
6878
vendor: 505 bytes, lines 6879-6892
6879// node_modules/@hotwired/turbo-rails/app/javascript/turbo/snakeize.js
6880function walk(obj) {
6881  if (!obj || typeof obj !== "object") return obj;
6882  if (obj instanceof Date || obj instanceof RegExp) return obj;
6883  if (Array.isArray(obj)) return obj.map(walk);
6884  return Object.keys(obj).reduce(function(acc, key) {
6885    var camel = key[0].toLowerCase() + key.slice(1).replace(/([A-Z]+)/g, function(m, x) {
6886      return "_" + x.toLowerCase();
6887    });
6888    acc[camel] = walk(obj[key]);
6889    return acc;
6890  }, {});
6891}
6892
vendor: 1,471 bytes, lines 6893-6934
6893// node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable_stream_source_element.js
6894var TurboCableStreamSourceElement = class extends HTMLElement {
6895  static observedAttributes = ["channel", "signed-stream-name"];
6896  async connectedCallback() {
6897    connectStreamSource(this);
6898    this.subscription = await subscribeTo(this.channel, {
6899      received: this.dispatchMessageEvent.bind(this),
6900      connected: this.subscriptionConnected.bind(this),
6901      disconnected: this.subscriptionDisconnected.bind(this)
6902    });
6903  }
6904  disconnectedCallback() {
6905    disconnectStreamSource(this);
6906    if (this.subscription) this.subscription.unsubscribe();
6907    this.subscriptionDisconnected();
6908  }
6909  attributeChangedCallback() {
6910    if (this.subscription) {
6911      this.disconnectedCallback();
6912      this.connectedCallback();
6913    }
6914  }
6915  dispatchMessageEvent(data) {
6916    const event = new MessageEvent("message", { data });
6917    return this.dispatchEvent(event);
6918  }
6919  subscriptionConnected() {
6920    this.setAttribute("connected", "");
6921  }
6922  subscriptionDisconnected() {
6923    this.removeAttribute("connected");
6924  }
6925  get channel() {
6926    const channel = this.getAttribute("channel");
6927    const signed_stream_name = this.getAttribute("signed-stream-name");
6928    return { channel, signed_stream_name, ...walk({ ...this.dataset }) };
6929  }
6930};
6931if (customElements.get("turbo-cable-stream-source") === void 0) {
6932  customElements.define("turbo-cable-stream-source", TurboCableStreamSourceElement);
6933}
6934
vendor: 1,611 bytes, lines 6935-6981
6935// node_modules/@hotwired/turbo-rails/app/javascript/turbo/fetch_requests.js
6936function encodeMethodIntoRequestBody(event) {
6937  if (event.target instanceof HTMLFormElement) {
6938    const { target: form, detail: { fetchOptions } } = event;
6939    form.addEventListener("turbo:submit-start", ({ detail: { formSubmission: { submitter: submitter2 } } }) => {
6940      const body = isBodyInit(fetchOptions.body) ? fetchOptions.body : new URLSearchParams();
6941      const method = determineFetchMethod(submitter2, body, form);
6942      if (!/get/i.test(method)) {
6943        if (/post/i.test(method)) {
6944          body.delete("_method");
6945        } else {
6946          body.set("_method", method);
6947        }
6948        fetchOptions.method = "post";
6949      }
6950    }, { once: true });
6951  }
6952}
6953function determineFetchMethod(submitter2, body, form) {
6954  const formMethod = determineFormMethod(submitter2);
6955  const overrideMethod = body.get("_method");
6956  const method = form.getAttribute("method") || "get";
6957  if (typeof formMethod == "string") {
6958    return formMethod;
6959  } else if (typeof overrideMethod == "string") {
6960    return overrideMethod;
6961  } else {
6962    return method;
6963  }
6964}
6965function determineFormMethod(submitter2) {
6966  if (submitter2 instanceof HTMLButtonElement || submitter2 instanceof HTMLInputElement) {
6967    if (submitter2.name === "_method") {
6968      return submitter2.value;
6969    } else if (submitter2.hasAttribute("formmethod")) {
6970      return submitter2.formMethod;
6971    } else {
6972      return null;
6973    }
6974  } else {
6975    return null;
6976  }
6977}
6978function isBodyInit(body) {
6979  return body instanceof FormData || body instanceof URLSearchParams;
6980}
6981
vendor: 187 bytes, lines 6982-6985
6982// node_modules/@hotwired/turbo-rails/app/javascript/turbo/index.js
6983window.Turbo = turbo_es2017_esm_exports;
6984addEventListener("turbo:before-fetch-request", encodeMethodIntoRequestBody);
6985
vendor: 79,408 bytes, lines 6986-9433
6986// node_modules/@hotwired/stimulus/dist/stimulus.js
6987var EventListener = class {
6988  constructor(eventTarget, eventName, eventOptions) {
6989    this.eventTarget = eventTarget;
6990    this.eventName = eventName;
6991    this.eventOptions = eventOptions;
6992    this.unorderedBindings = /* @__PURE__ */ new Set();
6993  }
6994  connect() {
6995    this.eventTarget.addEventListener(this.eventName, this, this.eventOptions);
6996  }
6997  disconnect() {
6998    this.eventTarget.removeEventListener(this.eventName, this, this.eventOptions);
6999  }
7000  bindingConnected(binding) {
7001    this.unorderedBindings.add(binding);
7002  }
7003  bindingDisconnected(binding) {
7004    this.unorderedBindings.delete(binding);
7005  }
7006  handleEvent(event) {
7007    const extendedEvent = extendEvent(event);
7008    for (const binding of this.bindings) {
7009      if (extendedEvent.immediatePropagationStopped) {
7010        break;
7011      } else {
7012        binding.handleEvent(extendedEvent);
7013      }
7014    }
7015  }
7016  hasBindings() {
7017    return this.unorderedBindings.size > 0;
7018  }
7019  get bindings() {
7020    return Array.from(this.unorderedBindings).sort((left, right) => {
7021      const leftIndex = left.index, rightIndex = right.index;
7022      return leftIndex < rightIndex ? -1 : leftIndex > rightIndex ? 1 : 0;
7023    });
7024  }
7025};
7026function extendEvent(event) {
7027  if ("immediatePropagationStopped" in event) {
7028    return event;
7029  } else {
7030    const { stopImmediatePropagation } = event;
7031    return Object.assign(event, {
7032      immediatePropagationStopped: false,
7033      stopImmediatePropagation() {
7034        this.immediatePropagationStopped = true;
7035        stopImmediatePropagation.call(this);
7036      }
7037    });
7038  }
7039}
7040var Dispatcher = class {
7041  constructor(application2) {
7042    this.application = application2;
7043    this.eventListenerMaps = /* @__PURE__ */ new Map();
7044    this.started = false;
7045  }
7046  start() {
7047    if (!this.started) {
7048      this.started = true;
7049      this.eventListeners.forEach((eventListener) => eventListener.connect());
7050    }
7051  }
7052  stop() {
7053    if (this.started) {
7054      this.started = false;
7055      this.eventListeners.forEach((eventListener) => eventListener.disconnect());
7056    }
7057  }
7058  get eventListeners() {
7059    return Array.from(this.eventListenerMaps.values()).reduce((listeners, map) => listeners.concat(Array.from(map.values())), []);
7060  }
7061  bindingConnected(binding) {
7062    this.fetchEventListenerForBinding(binding).bindingConnected(binding);
7063  }
7064  bindingDisconnected(binding, clearEventListeners = false) {
7065    this.fetchEventListenerForBinding(binding).bindingDisconnected(binding);
7066    if (clearEventListeners)
7067      this.clearEventListenersForBinding(binding);
7068  }
7069  handleError(error2, message, detail = {}) {
7070    this.application.handleError(error2, `Error ${message}`, detail);
7071  }
7072  clearEventListenersForBinding(binding) {
7073    const eventListener = this.fetchEventListenerForBinding(binding);
7074    if (!eventListener.hasBindings()) {
7075      eventListener.disconnect();
7076      this.removeMappedEventListenerFor(binding);
7077    }
7078  }
7079  removeMappedEventListenerFor(binding) {
7080    const { eventTarget, eventName, eventOptions } = binding;
7081    const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);
7082    const cacheKey = this.cacheKey(eventName, eventOptions);
7083    eventListenerMap.delete(cacheKey);
7084    if (eventListenerMap.size == 0)
7085      this.eventListenerMaps.delete(eventTarget);
7086  }
7087  fetchEventListenerForBinding(binding) {
7088    const { eventTarget, eventName, eventOptions } = binding;
7089    return this.fetchEventListener(eventTarget, eventName, eventOptions);
7090  }
7091  fetchEventListener(eventTarget, eventName, eventOptions) {
7092    const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);
7093    const cacheKey = this.cacheKey(eventName, eventOptions);
7094    let eventListener = eventListenerMap.get(cacheKey);
7095    if (!eventListener) {
7096      eventListener = this.createEventListener(eventTarget, eventName, eventOptions);
7097      eventListenerMap.set(cacheKey, eventListener);
7098    }
7099    return eventListener;
7100  }
7101  createEventListener(eventTarget, eventName, eventOptions) {
7102    const eventListener = new EventListener(eventTarget, eventName, eventOptions);
7103    if (this.started) {
7104      eventListener.connect();
7105    }
7106    return eventListener;
7107  }
7108  fetchEventListenerMapForEventTarget(eventTarget) {
7109    let eventListenerMap = this.eventListenerMaps.get(eventTarget);
7110    if (!eventListenerMap) {
7111      eventListenerMap = /* @__PURE__ */ new Map();
7112      this.eventListenerMaps.set(eventTarget, eventListenerMap);
7113    }
7114    return eventListenerMap;
7115  }
7116  cacheKey(eventName, eventOptions) {
7117    const parts = [eventName];
7118    Object.keys(eventOptions).sort().forEach((key) => {
7119      parts.push(`${eventOptions[key] ? "" : "!"}${key}`);
7120    });
7121    return parts.join(":");
7122  }
7123};
7124var defaultActionDescriptorFilters = {
7125  stop({ event, value }) {
7126    if (value)
7127      event.stopPropagation();
7128    return true;
7129  },
7130  prevent({ event, value }) {
7131    if (value)
7132      event.preventDefault();
7133    return true;
7134  },
7135  self({ event, value, element }) {
7136    if (value) {
7137      return element === event.target;
7138    } else {
7139      return true;
7140    }
7141  }
7142};
7143var descriptorPattern = /^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;
7144function parseActionDescriptorString(descriptorString) {
7145  const source = descriptorString.trim();
7146  const matches = source.match(descriptorPattern) || [];
7147  let eventName = matches[2];
7148  let keyFilter = matches[3];
7149  if (keyFilter && !["keydown", "keyup", "keypress"].includes(eventName)) {
7150    eventName += `.${keyFilter}`;
7151    keyFilter = "";
7152  }
7153  return {
7154    eventTarget: parseEventTarget(matches[4]),
7155    eventName,
7156    eventOptions: matches[7] ? parseEventOptions(matches[7]) : {},
7157    identifier: matches[5],
7158    methodName: matches[6],
7159    keyFilter: matches[1] || keyFilter
7160  };
7161}
7162function parseEventTarget(eventTargetName) {
7163  if (eventTargetName == "window") {
7164    return window;
7165  } else if (eventTargetName == "document") {
7166    return document;
7167  }
7168}
7169function parseEventOptions(eventOptions) {
7170  return eventOptions.split(":").reduce((options, token) => Object.assign(options, { [token.replace(/^!/, "")]: !/^!/.test(token) }), {});
7171}
7172function stringifyEventTarget(eventTarget) {
7173  if (eventTarget == window) {
7174    return "window";
7175  } else if (eventTarget == document) {
7176    return "document";
7177  }
7178}
7179function camelize(value) {
7180  return value.replace(/(?:[_-])([a-z0-9])/g, (_, char) => char.toUpperCase());
7181}
7182function namespaceCamelize(value) {
7183  return camelize(value.replace(/--/g, "-").replace(/__/g, "_"));
7184}
7185function capitalize(value) {
7186  return value.charAt(0).toUpperCase() + value.slice(1);
7187}
7188function dasherize(value) {
7189  return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`);
7190}
7191function tokenize(value) {
7192  return value.match(/[^\s]+/g) || [];
7193}
7194function isSomething(object) {
7195  return object !== null && object !== void 0;
7196}
7197function hasProperty(object, property) {
7198  return Object.prototype.hasOwnProperty.call(object, property);
7199}
7200var allModifiers = ["meta", "ctrl", "alt", "shift"];
7201var Action = class {
7202  constructor(element, index, descriptor, schema) {
7203    this.element = element;
7204    this.index = index;
7205    this.eventTarget = descriptor.eventTarget || element;
7206    this.eventName = descriptor.eventName || getDefaultEventNameForElement(element) || error("missing event name");
7207    this.eventOptions = descriptor.eventOptions || {};
7208    this.identifier = descriptor.identifier || error("missing identifier");
7209    this.methodName = descriptor.methodName || error("missing method name");
7210    this.keyFilter = descriptor.keyFilter || "";
7211    this.schema = schema;
7212  }
7213  static forToken(token, schema) {
7214    return new this(token.element, token.index, parseActionDescriptorString(token.content), schema);
7215  }
7216  toString() {
7217    const eventFilter = this.keyFilter ? `.${this.keyFilter}` : "";
7218    const eventTarget = this.eventTargetName ? `@${this.eventTargetName}` : "";
7219    return `${this.eventName}${eventFilter}${eventTarget}->${this.identifier}#${this.methodName}`;
7220  }
7221  shouldIgnoreKeyboardEvent(event) {
7222    if (!this.keyFilter) {
7223      return false;
7224    }
7225    const filters = this.keyFilter.split("+");
7226    if (this.keyFilterDissatisfied(event, filters)) {
7227      return true;
7228    }
7229    const standardFilter = filters.filter((key) => !allModifiers.includes(key))[0];
7230    if (!standardFilter) {
7231      return false;
7232    }
7233    if (!hasProperty(this.keyMappings, standardFilter)) {
7234      error(`contains unknown key filter: ${this.keyFilter}`);
7235    }
7236    return this.keyMappings[standardFilter].toLowerCase() !== event.key.toLowerCase();
7237  }
7238  shouldIgnoreMouseEvent(event) {
7239    if (!this.keyFilter) {
7240      return false;
7241    }
7242    const filters = [this.keyFilter];
7243    if (this.keyFilterDissatisfied(event, filters)) {
7244      return true;
7245    }
7246    return false;
7247  }
7248  get params() {
7249    const params = {};
7250    const pattern = new RegExp(`^data-${this.identifier}-(.+)-param$`, "i");
7251    for (const { name, value } of Array.from(this.element.attributes)) {
7252      const match = name.match(pattern);
7253      const key = match && match[1];
7254      if (key) {
7255        params[camelize(key)] = typecast(value);
7256      }
7257    }
7258    return params;
7259  }
7260  get eventTargetName() {
7261    return stringifyEventTarget(this.eventTarget);
7262  }
7263  get keyMappings() {
7264    return this.schema.keyMappings;
7265  }
7266  keyFilterDissatisfied(event, filters) {
7267    const [meta, ctrl, alt, shift] = allModifiers.map((modifier) => filters.includes(modifier));
7268    return event.metaKey !== meta || event.ctrlKey !== ctrl || event.altKey !== alt || event.shiftKey !== shift;
7269  }
7270};
7271var defaultEventNames = {
7272  a: () => "click",
7273  button: () => "click",
7274  form: () => "submit",
7275  details: () => "toggle",
7276  input: (e) => e.getAttribute("type") == "submit" ? "click" : "input",
7277  select: () => "change",
7278  textarea: () => "input"
7279};
7280function getDefaultEventNameForElement(element) {
7281  const tagName = element.tagName.toLowerCase();
7282  if (tagName in defaultEventNames) {
7283    return defaultEventNames[tagName](element);
7284  }
7285}
7286function error(message) {
7287  throw new Error(message);
7288}
7289function typecast(value) {
7290  try {
7291    return JSON.parse(value);
7292  } catch (o_O) {
7293    return value;
7294  }
7295}
7296var Binding = class {
7297  constructor(context, action) {
7298    this.context = context;
7299    this.action = action;
7300  }
7301  get index() {
7302    return this.action.index;
7303  }
7304  get eventTarget() {
7305    return this.action.eventTarget;
7306  }
7307  get eventOptions() {
7308    return this.action.eventOptions;
7309  }
7310  get identifier() {
7311    return this.context.identifier;
7312  }
7313  handleEvent(event) {
7314    const actionEvent = this.prepareActionEvent(event);
7315    if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(actionEvent)) {
7316      this.invokeWithEvent(actionEvent);
7317    }
7318  }
7319  get eventName() {
7320    return this.action.eventName;
7321  }
7322  get method() {
7323    const method = this.controller[this.methodName];
7324    if (typeof method == "function") {
7325      return method;
7326    }
7327    throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`);
7328  }
7329  applyEventModifiers(event) {
7330    const { element } = this.action;
7331    const { actionDescriptorFilters } = this.context.application;
7332    const { controller } = this.context;
7333    let passes = true;
7334    for (const [name, value] of Object.entries(this.eventOptions)) {
7335      if (name in actionDescriptorFilters) {
7336        const filter = actionDescriptorFilters[name];
7337        passes = passes && filter({ name, value, event, element, controller });
7338      } else {
7339        continue;
7340      }
7341    }
7342    return passes;
7343  }
7344  prepareActionEvent(event) {
7345    return Object.assign(event, { params: this.action.params });
7346  }
7347  invokeWithEvent(event) {
7348    const { target, currentTarget } = event;
7349    try {
7350      this.method.call(this.controller, event);
7351      this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName });
7352    } catch (error2) {
7353      const { identifier, controller, element, index } = this;
7354      const detail = { identifier, controller, element, index, event };
7355      this.context.handleError(error2, `invoking action "${this.action}"`, detail);
7356    }
7357  }
7358  willBeInvokedByEvent(event) {
7359    const eventTarget = event.target;
7360    if (event instanceof KeyboardEvent && this.action.shouldIgnoreKeyboardEvent(event)) {
7361      return false;
7362    }
7363    if (event instanceof MouseEvent && this.action.shouldIgnoreMouseEvent(event)) {
7364      return false;
7365    }
7366    if (this.element === eventTarget) {
7367      return true;
7368    } else if (eventTarget instanceof Element && this.element.contains(eventTarget)) {
7369      return this.scope.containsElement(eventTarget);
7370    } else {
7371      return this.scope.containsElement(this.action.element);
7372    }
7373  }
7374  get controller() {
7375    return this.context.controller;
7376  }
7377  get methodName() {
7378    return this.action.methodName;
7379  }
7380  get element() {
7381    return this.scope.element;
7382  }
7383  get scope() {
7384    return this.context.scope;
7385  }
7386};
7387var ElementObserver = class {
7388  constructor(element, delegate) {
7389    this.mutationObserverInit = { attributes: true, childList: true, subtree: true };
7390    this.element = element;
7391    this.started = false;
7392    this.delegate = delegate;
7393    this.elements = /* @__PURE__ */ new Set();
7394    this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));
7395  }
7396  start() {
7397    if (!this.started) {
7398      this.started = true;
7399      this.mutationObserver.observe(this.element, this.mutationObserverInit);
7400      this.refresh();
7401    }
7402  }
7403  pause(callback) {
7404    if (this.started) {
7405      this.mutationObserver.disconnect();
7406      this.started = false;
7407    }
7408    callback();
7409    if (!this.started) {
7410      this.mutationObserver.observe(this.element, this.mutationObserverInit);
7411      this.started = true;
7412    }
7413  }
7414  stop() {
7415    if (this.started) {
7416      this.mutationObserver.takeRecords();
7417      this.mutationObserver.disconnect();
7418      this.started = false;
7419    }
7420  }
7421  refresh() {
7422    if (this.started) {
7423      const matches = new Set(this.matchElementsInTree());
7424      for (const element of Array.from(this.elements)) {
7425        if (!matches.has(element)) {
7426          this.removeElement(element);
7427        }
7428      }
7429      for (const element of Array.from(matches)) {
7430        this.addElement(element);
7431      }
7432    }
7433  }
7434  processMutations(mutations) {
7435    if (this.started) {
7436      for (const mutation of mutations) {
7437        this.processMutation(mutation);
7438      }
7439    }
7440  }
7441  processMutation(mutation) {
7442    if (mutation.type == "attributes") {
7443      this.processAttributeChange(mutation.target, mutation.attributeName);
7444    } else if (mutation.type == "childList") {
7445      this.processRemovedNodes(mutation.removedNodes);
7446      this.processAddedNodes(mutation.addedNodes);
7447    }
7448  }
7449  processAttributeChange(element, attributeName) {
7450    if (this.elements.has(element)) {
7451      if (this.delegate.elementAttributeChanged && this.matchElement(element)) {
7452        this.delegate.elementAttributeChanged(element, attributeName);
7453      } else {
7454        this.removeElement(element);
7455      }
7456    } else if (this.matchElement(element)) {
7457      this.addElement(element);
7458    }
7459  }
7460  processRemovedNodes(nodes) {
7461    for (const node of Array.from(nodes)) {
7462      const element = this.elementFromNode(node);
7463      if (element) {
7464        this.processTree(element, this.removeElement);
7465      }
7466    }
7467  }
7468  processAddedNodes(nodes) {
7469    for (const node of Array.from(nodes)) {
7470      const element = this.elementFromNode(node);
7471      if (element && this.elementIsActive(element)) {
7472        this.processTree(element, this.addElement);
7473      }
7474    }
7475  }
7476  matchElement(element) {
7477    return this.delegate.matchElement(element);
7478  }
7479  matchElementsInTree(tree = this.element) {
7480    return this.delegate.matchElementsInTree(tree);
7481  }
7482  processTree(tree, processor) {
7483    for (const element of this.matchElementsInTree(tree)) {
7484      processor.call(this, element);
7485    }
7486  }
7487  elementFromNode(node) {
7488    if (node.nodeType == Node.ELEMENT_NODE) {
7489      return node;
7490    }
7491  }
7492  elementIsActive(element) {
7493    if (element.isConnected != this.element.isConnected) {
7494      return false;
7495    } else {
7496      return this.element.contains(element);
7497    }
7498  }
7499  addElement(element) {
7500    if (!this.elements.has(element)) {
7501      if (this.elementIsActive(element)) {
7502        this.elements.add(element);
7503        if (this.delegate.elementMatched) {
7504          this.delegate.elementMatched(element);
7505        }
7506      }
7507    }
7508  }
7509  removeElement(element) {
7510    if (this.elements.has(element)) {
7511      this.elements.delete(element);
7512      if (this.delegate.elementUnmatched) {
7513        this.delegate.elementUnmatched(element);
7514      }
7515    }
7516  }
7517};
7518var AttributeObserver = class {
7519  constructor(element, attributeName, delegate) {
7520    this.attributeName = attributeName;
7521    this.delegate = delegate;
7522    this.elementObserver = new ElementObserver(element, this);
7523  }
7524  get element() {
7525    return this.elementObserver.element;
7526  }
7527  get selector() {
7528    return `[${this.attributeName}]`;
7529  }
7530  start() {
7531    this.elementObserver.start();
7532  }
7533  pause(callback) {
7534    this.elementObserver.pause(callback);
7535  }
7536  stop() {
7537    this.elementObserver.stop();
7538  }
7539  refresh() {
7540    this.elementObserver.refresh();
7541  }
7542  get started() {
7543    return this.elementObserver.started;
7544  }
7545  matchElement(element) {
7546    return element.hasAttribute(this.attributeName);
7547  }
7548  matchElementsInTree(tree) {
7549    const match = this.matchElement(tree) ? [tree] : [];
7550    const matches = Array.from(tree.querySelectorAll(this.selector));
7551    return match.concat(matches);
7552  }
7553  elementMatched(element) {
7554    if (this.delegate.elementMatchedAttribute) {
7555      this.delegate.elementMatchedAttribute(element, this.attributeName);
7556    }
7557  }
7558  elementUnmatched(element) {
7559    if (this.delegate.elementUnmatchedAttribute) {
7560      this.delegate.elementUnmatchedAttribute(element, this.attributeName);
7561    }
7562  }
7563  elementAttributeChanged(element, attributeName) {
7564    if (this.delegate.elementAttributeValueChanged && this.attributeName == attributeName) {
7565      this.delegate.elementAttributeValueChanged(element, attributeName);
7566    }
7567  }
7568};
7569function add(map, key, value) {
7570  fetch2(map, key).add(value);
7571}
7572function del(map, key, value) {
7573  fetch2(map, key).delete(value);
7574  prune(map, key);
7575}
7576function fetch2(map, key) {
7577  let values = map.get(key);
7578  if (!values) {
7579    values = /* @__PURE__ */ new Set();
7580    map.set(key, values);
7581  }
7582  return values;
7583}
7584function prune(map, key) {
7585  const values = map.get(key);
7586  if (values != null && values.size == 0) {
7587    map.delete(key);
7588  }
7589}
7590var Multimap = class {
7591  constructor() {
7592    this.valuesByKey = /* @__PURE__ */ new Map();
7593  }
7594  get keys() {
7595    return Array.from(this.valuesByKey.keys());
7596  }
7597  get values() {
7598    const sets = Array.from(this.valuesByKey.values());
7599    return sets.reduce((values, set) => values.concat(Array.from(set)), []);
7600  }
7601  get size() {
7602    const sets = Array.from(this.valuesByKey.values());
7603    return sets.reduce((size, set) => size + set.size, 0);
7604  }
7605  add(key, value) {
7606    add(this.valuesByKey, key, value);
7607  }
7608  delete(key, value) {
7609    del(this.valuesByKey, key, value);
7610  }
7611  has(key, value) {
7612    const values = this.valuesByKey.get(key);
7613    return values != null && values.has(value);
7614  }
7615  hasKey(key) {
7616    return this.valuesByKey.has(key);
7617  }
7618  hasValue(value) {
7619    const sets = Array.from(this.valuesByKey.values());
7620    return sets.some((set) => set.has(value));
7621  }
7622  getValuesForKey(key) {
7623    const values = this.valuesByKey.get(key);
7624    return values ? Array.from(values) : [];
7625  }
7626  getKeysForValue(value) {
7627    return Array.from(this.valuesByKey).filter(([_key, values]) => values.has(value)).map(([key, _values]) => key);
7628  }
7629};
7630var SelectorObserver = class {
7631  constructor(element, selector, delegate, details) {
7632    this._selector = selector;
7633    this.details = details;
7634    this.elementObserver = new ElementObserver(element, this);
7635    this.delegate = delegate;
7636    this.matchesByElement = new Multimap();
7637  }
7638  get started() {
7639    return this.elementObserver.started;
7640  }
7641  get selector() {
7642    return this._selector;
7643  }
7644  set selector(selector) {
7645    this._selector = selector;
7646    this.refresh();
7647  }
7648  start() {
7649    this.elementObserver.start();
7650  }
7651  pause(callback) {
7652    this.elementObserver.pause(callback);
7653  }
7654  stop() {
7655    this.elementObserver.stop();
7656  }
7657  refresh() {
7658    this.elementObserver.refresh();
7659  }
7660  get element() {
7661    return this.elementObserver.element;
7662  }
7663  matchElement(element) {
7664    const { selector } = this;
7665    if (selector) {
7666      const matches = element.matches(selector);
7667      if (this.delegate.selectorMatchElement) {
7668        return matches && this.delegate.selectorMatchElement(element, this.details);
7669      }
7670      return matches;
7671    } else {
7672      return false;
7673    }
7674  }
7675  matchElementsInTree(tree) {
7676    const { selector } = this;
7677    if (selector) {
7678      const match = this.matchElement(tree) ? [tree] : [];
7679      const matches = Array.from(tree.querySelectorAll(selector)).filter((match2) => this.matchElement(match2));
7680      return match.concat(matches);
7681    } else {
7682      return [];
7683    }
7684  }
7685  elementMatched(element) {
7686    const { selector } = this;
7687    if (selector) {
7688      this.selectorMatched(element, selector);
7689    }
7690  }
7691  elementUnmatched(element) {
7692    const selectors = this.matchesByElement.getKeysForValue(element);
7693    for (const selector of selectors) {
7694      this.selectorUnmatched(element, selector);
7695    }
7696  }
7697  elementAttributeChanged(element, _attributeName) {
7698    const { selector } = this;
7699    if (selector) {
7700      const matches = this.matchElement(element);
7701      const matchedBefore = this.matchesByElement.has(selector, element);
7702      if (matches && !matchedBefore) {
7703        this.selectorMatched(element, selector);
7704      } else if (!matches && matchedBefore) {
7705        this.selectorUnmatched(element, selector);
7706      }
7707    }
7708  }
7709  selectorMatched(element, selector) {
7710    this.delegate.selectorMatched(element, selector, this.details);
7711    this.matchesByElement.add(selector, element);
7712  }
7713  selectorUnmatched(element, selector) {
7714    this.delegate.selectorUnmatched(element, selector, this.details);
7715    this.matchesByElement.delete(selector, element);
7716  }
7717};
7718var StringMapObserver = class {
7719  constructor(element, delegate) {
7720    this.element = element;
7721    this.delegate = delegate;
7722    this.started = false;
7723    this.stringMap = /* @__PURE__ */ new Map();
7724    this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));
7725  }
7726  start() {
7727    if (!this.started) {
7728      this.started = true;
7729      this.mutationObserver.observe(this.element, { attributes: true, attributeOldValue: true });
7730      this.refresh();
7731    }
7732  }
7733  stop() {
7734    if (this.started) {
7735      this.mutationObserver.takeRecords();
7736      this.mutationObserver.disconnect();
7737      this.started = false;
7738    }
7739  }
7740  refresh() {
7741    if (this.started) {
7742      for (const attributeName of this.knownAttributeNames) {
7743        this.refreshAttribute(attributeName, null);
7744      }
7745    }
7746  }
7747  processMutations(mutations) {
7748    if (this.started) {
7749      for (const mutation of mutations) {
7750        this.processMutation(mutation);
7751      }
7752    }
7753  }
7754  processMutation(mutation) {
7755    const attributeName = mutation.attributeName;
7756    if (attributeName) {
7757      this.refreshAttribute(attributeName, mutation.oldValue);
7758    }
7759  }
7760  refreshAttribute(attributeName, oldValue) {
7761    const key = this.delegate.getStringMapKeyForAttribute(attributeName);
7762    if (key != null) {
7763      if (!this.stringMap.has(attributeName)) {
7764        this.stringMapKeyAdded(key, attributeName);
7765      }
7766      const value = this.element.getAttribute(attributeName);
7767      if (this.stringMap.get(attributeName) != value) {
7768        this.stringMapValueChanged(value, key, oldValue);
7769      }
7770      if (value == null) {
7771        const oldValue2 = this.stringMap.get(attributeName);
7772        this.stringMap.delete(attributeName);
7773        if (oldValue2)
7774          this.stringMapKeyRemoved(key, attributeName, oldValue2);
7775      } else {
7776        this.stringMap.set(attributeName, value);
7777      }
7778    }
7779  }
7780  stringMapKeyAdded(key, attributeName) {
7781    if (this.delegate.stringMapKeyAdded) {
7782      this.delegate.stringMapKeyAdded(key, attributeName);
7783    }
7784  }
7785  stringMapValueChanged(value, key, oldValue) {
7786    if (this.delegate.stringMapValueChanged) {
7787      this.delegate.stringMapValueChanged(value, key, oldValue);
7788    }
7789  }
7790  stringMapKeyRemoved(key, attributeName, oldValue) {
7791    if (this.delegate.stringMapKeyRemoved) {
7792      this.delegate.stringMapKeyRemoved(key, attributeName, oldValue);
7793    }
7794  }
7795  get knownAttributeNames() {
7796    return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)));
7797  }
7798  get currentAttributeNames() {
7799    return Array.from(this.element.attributes).map((attribute) => attribute.name);
7800  }
7801  get recordedAttributeNames() {
7802    return Array.from(this.stringMap.keys());
7803  }
7804};
7805var TokenListObserver = class {
7806  constructor(element, attributeName, delegate) {
7807    this.attributeObserver = new AttributeObserver(element, attributeName, this);
7808    this.delegate = delegate;
7809    this.tokensByElement = new Multimap();
7810  }
7811  get started() {
7812    return this.attributeObserver.started;
7813  }
7814  start() {
7815    this.attributeObserver.start();
7816  }
7817  pause(callback) {
7818    this.attributeObserver.pause(callback);
7819  }
7820  stop() {
7821    this.attributeObserver.stop();
7822  }
7823  refresh() {
7824    this.attributeObserver.refresh();
7825  }
7826  get element() {
7827    return this.attributeObserver.element;
7828  }
7829  get attributeName() {
7830    return this.attributeObserver.attributeName;
7831  }
7832  elementMatchedAttribute(element) {
7833    this.tokensMatched(this.readTokensForElement(element));
7834  }
7835  elementAttributeValueChanged(element) {
7836    const [unmatchedTokens, matchedTokens] = this.refreshTokensForElement(element);
7837    this.tokensUnmatched(unmatchedTokens);
7838    this.tokensMatched(matchedTokens);
7839  }
7840  elementUnmatchedAttribute(element) {
7841    this.tokensUnmatched(this.tokensByElement.getValuesForKey(element));
7842  }
7843  tokensMatched(tokens) {
7844    tokens.forEach((token) => this.tokenMatched(token));
7845  }
7846  tokensUnmatched(tokens) {
7847    tokens.forEach((token) => this.tokenUnmatched(token));
7848  }
7849  tokenMatched(token) {
7850    this.delegate.tokenMatched(token);
7851    this.tokensByElement.add(token.element, token);
7852  }
7853  tokenUnmatched(token) {
7854    this.delegate.tokenUnmatched(token);
7855    this.tokensByElement.delete(token.element, token);
7856  }
7857  refreshTokensForElement(element) {
7858    const previousTokens = this.tokensByElement.getValuesForKey(element);
7859    const currentTokens = this.readTokensForElement(element);
7860    const firstDifferingIndex = zip(previousTokens, currentTokens).findIndex(([previousToken, currentToken]) => !tokensAreEqual(previousToken, currentToken));
7861    if (firstDifferingIndex == -1) {
7862      return [[], []];
7863    } else {
7864      return [previousTokens.slice(firstDifferingIndex), currentTokens.slice(firstDifferingIndex)];
7865    }
7866  }
7867  readTokensForElement(element) {
7868    const attributeName = this.attributeName;
7869    const tokenString = element.getAttribute(attributeName) || "";
7870    return parseTokenString(tokenString, element, attributeName);
7871  }
7872};
7873function parseTokenString(tokenString, element, attributeName) {
7874  return tokenString.trim().split(/\s+/).filter((content) => content.length).map((content, index) => ({ element, attributeName, content, index }));
7875}
7876function zip(left, right) {
7877  const length = Math.max(left.length, right.length);
7878  return Array.from({ length }, (_, index) => [left[index], right[index]]);
7879}
7880function tokensAreEqual(left, right) {
7881  return left && right && left.index == right.index && left.content == right.content;
7882}
7883var ValueListObserver = class {
7884  constructor(element, attributeName, delegate) {
7885    this.tokenListObserver = new TokenListObserver(element, attributeName, this);
7886    this.delegate = delegate;
7887    this.parseResultsByToken = /* @__PURE__ */ new WeakMap();
7888    this.valuesByTokenByElement = /* @__PURE__ */ new WeakMap();
7889  }
7890  get started() {
7891    return this.tokenListObserver.started;
7892  }
7893  start() {
7894    this.tokenListObserver.start();
7895  }
7896  stop() {
7897    this.tokenListObserver.stop();
7898  }
7899  refresh() {
7900    this.tokenListObserver.refresh();
7901  }
7902  get element() {
7903    return this.tokenListObserver.element;
7904  }
7905  get attributeName() {
7906    return this.tokenListObserver.attributeName;
7907  }
7908  tokenMatched(token) {
7909    const { element } = token;
7910    const { value } = this.fetchParseResultForToken(token);
7911    if (value) {
7912      this.fetchValuesByTokenForElement(element).set(token, value);
7913      this.delegate.elementMatchedValue(element, value);
7914    }
7915  }
7916  tokenUnmatched(token) {
7917    const { element } = token;
7918    const { value } = this.fetchParseResultForToken(token);
7919    if (value) {
7920      this.fetchValuesByTokenForElement(element).delete(token);
7921      this.delegate.elementUnmatchedValue(element, value);
7922    }
7923  }
7924  fetchParseResultForToken(token) {
7925    let parseResult = this.parseResultsByToken.get(token);
7926    if (!parseResult) {
7927      parseResult = this.parseToken(token);
7928      this.parseResultsByToken.set(token, parseResult);
7929    }
7930    return parseResult;
7931  }
7932  fetchValuesByTokenForElement(element) {
7933    let valuesByToken = this.valuesByTokenByElement.get(element);
7934    if (!valuesByToken) {
7935      valuesByToken = /* @__PURE__ */ new Map();
7936      this.valuesByTokenByElement.set(element, valuesByToken);
7937    }
7938    return valuesByToken;
7939  }
7940  parseToken(token) {
7941    try {
7942      const value = this.delegate.parseValueForToken(token);
7943      return { value };
7944    } catch (error2) {
7945      return { error: error2 };
7946    }
7947  }
7948};
7949var BindingObserver = class {
7950  constructor(context, delegate) {
7951    this.context = context;
7952    this.delegate = delegate;
7953    this.bindingsByAction = /* @__PURE__ */ new Map();
7954  }
7955  start() {
7956    if (!this.valueListObserver) {
7957      this.valueListObserver = new ValueListObserver(this.element, this.actionAttribute, this);
7958      this.valueListObserver.start();
7959    }
7960  }
7961  stop() {
7962    if (this.valueListObserver) {
7963      this.valueListObserver.stop();
7964      delete this.valueListObserver;
7965      this.disconnectAllActions();
7966    }
7967  }
7968  get element() {
7969    return this.context.element;
7970  }
7971  get identifier() {
7972    return this.context.identifier;
7973  }
7974  get actionAttribute() {
7975    return this.schema.actionAttribute;
7976  }
7977  get schema() {
7978    return this.context.schema;
7979  }
7980  get bindings() {
7981    return Array.from(this.bindingsByAction.values());
7982  }
7983  connectAction(action) {
7984    const binding = new Binding(this.context, action);
7985    this.bindingsByAction.set(action, binding);
7986    this.delegate.bindingConnected(binding);
7987  }
7988  disconnectAction(action) {
7989    const binding = this.bindingsByAction.get(action);
7990    if (binding) {
7991      this.bindingsByAction.delete(action);
7992      this.delegate.bindingDisconnected(binding);
7993    }
7994  }
7995  disconnectAllActions() {
7996    this.bindings.forEach((binding) => this.delegate.bindingDisconnected(binding, true));
7997    this.bindingsByAction.clear();
7998  }
7999  parseValueForToken(token) {
8000    const action = Action.forToken(token, this.schema);
8001    if (action.identifier == this.identifier) {
8002      return action;
8003    }
8004  }
8005  elementMatchedValue(element, action) {
8006    this.connectAction(action);
8007  }
8008  elementUnmatchedValue(element, action) {
8009    this.disconnectAction(action);
8010  }
8011};
8012var ValueObserver = class {
8013  constructor(context, receiver) {
8014    this.context = context;
8015    this.receiver = receiver;
8016    this.stringMapObserver = new StringMapObserver(this.element, this);
8017    this.valueDescriptorMap = this.controller.valueDescriptorMap;
8018  }
8019  start() {
8020    this.stringMapObserver.start();
8021    this.invokeChangedCallbacksForDefaultValues();
8022  }
8023  stop() {
8024    this.stringMapObserver.stop();
8025  }
8026  get element() {
8027    return this.context.element;
8028  }
8029  get controller() {
8030    return this.context.controller;
8031  }
8032  getStringMapKeyForAttribute(attributeName) {
8033    if (attributeName in this.valueDescriptorMap) {
8034      return this.valueDescriptorMap[attributeName].name;
8035    }
8036  }
8037  stringMapKeyAdded(key, attributeName) {
8038    const descriptor = this.valueDescriptorMap[attributeName];
8039    if (!this.hasValue(key)) {
8040      this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), descriptor.writer(descriptor.defaultValue));
8041    }
8042  }
8043  stringMapValueChanged(value, name, oldValue) {
8044    const descriptor = this.valueDescriptorNameMap[name];
8045    if (value === null)
8046      return;
8047    if (oldValue === null) {
8048      oldValue = descriptor.writer(descriptor.defaultValue);
8049    }
8050    this.invokeChangedCallback(name, value, oldValue);
8051  }
8052  stringMapKeyRemoved(key, attributeName, oldValue) {
8053    const descriptor = this.valueDescriptorNameMap[key];
8054    if (this.hasValue(key)) {
8055      this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), oldValue);
8056    } else {
8057      this.invokeChangedCallback(key, descriptor.writer(descriptor.defaultValue), oldValue);
8058    }
8059  }
8060  invokeChangedCallbacksForDefaultValues() {
8061    for (const { key, name, defaultValue, writer } of this.valueDescriptors) {
8062      if (defaultValue != void 0 && !this.controller.data.has(key)) {
8063        this.invokeChangedCallback(name, writer(defaultValue), void 0);
8064      }
8065    }
8066  }
8067  invokeChangedCallback(name, rawValue, rawOldValue) {
8068    const changedMethodName = `${name}Changed`;
8069    const changedMethod = this.receiver[changedMethodName];
8070    if (typeof changedMethod == "function") {
8071      const descriptor = this.valueDescriptorNameMap[name];
8072      try {
8073        const value = descriptor.reader(rawValue);
8074        let oldValue = rawOldValue;
8075        if (rawOldValue) {
8076          oldValue = descriptor.reader(rawOldValue);
8077        }
8078        changedMethod.call(this.receiver, value, oldValue);
8079      } catch (error2) {
8080        if (error2 instanceof TypeError) {
8081          error2.message = `Stimulus Value "${this.context.identifier}.${descriptor.name}" - ${error2.message}`;
8082        }
8083        throw error2;
8084      }
8085    }
8086  }
8087  get valueDescriptors() {
8088    const { valueDescriptorMap } = this;
8089    return Object.keys(valueDescriptorMap).map((key) => valueDescriptorMap[key]);
8090  }
8091  get valueDescriptorNameMap() {
8092    const descriptors = {};
8093    Object.keys(this.valueDescriptorMap).forEach((key) => {
8094      const descriptor = this.valueDescriptorMap[key];
8095      descriptors[descriptor.name] = descriptor;
8096    });
8097    return descriptors;
8098  }
8099  hasValue(attributeName) {
8100    const descriptor = this.valueDescriptorNameMap[attributeName];
8101    const hasMethodName = `has${capitalize(descriptor.name)}`;
8102    return this.receiver[hasMethodName];
8103  }
8104};
8105var TargetObserver = class {
8106  constructor(context, delegate) {
8107    this.context = context;
8108    this.delegate = delegate;
8109    this.targetsByName = new Multimap();
8110  }
8111  start() {
8112    if (!this.tokenListObserver) {
8113      this.tokenListObserver = new TokenListObserver(this.element, this.attributeName, this);
8114      this.tokenListObserver.start();
8115    }
8116  }
8117  stop() {
8118    if (this.tokenListObserver) {
8119      this.disconnectAllTargets();
8120      this.tokenListObserver.stop();
8121      delete this.tokenListObserver;
8122    }
8123  }
8124  tokenMatched({ element, content: name }) {
8125    if (this.scope.containsElement(element)) {
8126      this.connectTarget(element, name);
8127    }
8128  }
8129  tokenUnmatched({ element, content: name }) {
8130    this.disconnectTarget(element, name);
8131  }
8132  connectTarget(element, name) {
8133    var _a;
8134    if (!this.targetsByName.has(name, element)) {
8135      this.targetsByName.add(name, element);
8136      (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetConnected(element, name));
8137    }
8138  }
8139  disconnectTarget(element, name) {
8140    var _a;
8141    if (this.targetsByName.has(name, element)) {
8142      this.targetsByName.delete(name, element);
8143      (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetDisconnected(element, name));
8144    }
8145  }
8146  disconnectAllTargets() {
8147    for (const name of this.targetsByName.keys) {
8148      for (const element of this.targetsByName.getValuesForKey(name)) {
8149        this.disconnectTarget(element, name);
8150      }
8151    }
8152  }
8153  get attributeName() {
8154    return `data-${this.context.identifier}-target`;
8155  }
8156  get element() {
8157    return this.context.element;
8158  }
8159  get scope() {
8160    return this.context.scope;
8161  }
8162};
8163function readInheritableStaticArrayValues(constructor, propertyName) {
8164  const ancestors = getAncestorsForConstructor(constructor);
8165  return Array.from(ancestors.reduce((values, constructor2) => {
8166    getOwnStaticArrayValues(constructor2, propertyName).forEach((name) => values.add(name));
8167    return values;
8168  }, /* @__PURE__ */ new Set()));
8169}
8170function readInheritableStaticObjectPairs(constructor, propertyName) {
8171  const ancestors = getAncestorsForConstructor(constructor);
8172  return ancestors.reduce((pairs, constructor2) => {
8173    pairs.push(...getOwnStaticObjectPairs(constructor2, propertyName));
8174    return pairs;
8175  }, []);
8176}
8177function getAncestorsForConstructor(constructor) {
8178  const ancestors = [];
8179  while (constructor) {
8180    ancestors.push(constructor);
8181    constructor = Object.getPrototypeOf(constructor);
8182  }
8183  return ancestors.reverse();
8184}
8185function getOwnStaticArrayValues(constructor, propertyName) {
8186  const definition = constructor[propertyName];
8187  return Array.isArray(definition) ? definition : [];
8188}
8189function getOwnStaticObjectPairs(constructor, propertyName) {
8190  const definition = constructor[propertyName];
8191  return definition ? Object.keys(definition).map((key) => [key, definition[key]]) : [];
8192}
8193var OutletObserver = class {
8194  constructor(context, delegate) {
8195    this.started = false;
8196    this.context = context;
8197    this.delegate = delegate;
8198    this.outletsByName = new Multimap();
8199    this.outletElementsByName = new Multimap();
8200    this.selectorObserverMap = /* @__PURE__ */ new Map();
8201    this.attributeObserverMap = /* @__PURE__ */ new Map();
8202  }
8203  start() {
8204    if (!this.started) {
8205      this.outletDefinitions.forEach((outletName) => {
8206        this.setupSelectorObserverForOutlet(outletName);
8207        this.setupAttributeObserverForOutlet(outletName);
8208      });
8209      this.started = true;
8210      this.dependentContexts.forEach((context) => context.refresh());
8211    }
8212  }
8213  refresh() {
8214    this.selectorObserverMap.forEach((observer) => observer.refresh());
8215    this.attributeObserverMap.forEach((observer) => observer.refresh());
8216  }
8217  stop() {
8218    if (this.started) {
8219      this.started = false;
8220      this.disconnectAllOutlets();
8221      this.stopSelectorObservers();
8222      this.stopAttributeObservers();
8223    }
8224  }
8225  stopSelectorObservers() {
8226    if (this.selectorObserverMap.size > 0) {
8227      this.selectorObserverMap.forEach((observer) => observer.stop());
8228      this.selectorObserverMap.clear();
8229    }
8230  }
8231  stopAttributeObservers() {
8232    if (this.attributeObserverMap.size > 0) {
8233      this.attributeObserverMap.forEach((observer) => observer.stop());
8234      this.attributeObserverMap.clear();
8235    }
8236  }
8237  selectorMatched(element, _selector, { outletName }) {
8238    const outlet = this.getOutlet(element, outletName);
8239    if (outlet) {
8240      this.connectOutlet(outlet, element, outletName);
8241    }
8242  }
8243  selectorUnmatched(element, _selector, { outletName }) {
8244    const outlet = this.getOutletFromMap(element, outletName);
8245    if (outlet) {
8246      this.disconnectOutlet(outlet, element, outletName);
8247    }
8248  }
8249  selectorMatchElement(element, { outletName }) {
8250    const selector = this.selector(outletName);
8251    const hasOutlet = this.hasOutlet(element, outletName);
8252    const hasOutletController = element.matches(`[${this.schema.controllerAttribute}~=${outletName}]`);
8253    if (selector) {
8254      return hasOutlet && hasOutletController && element.matches(selector);
8255    } else {
8256      return false;
8257    }
8258  }
8259  elementMatchedAttribute(_element, attributeName) {
8260    const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
8261    if (outletName) {
8262      this.updateSelectorObserverForOutlet(outletName);
8263    }
8264  }
8265  elementAttributeValueChanged(_element, attributeName) {
8266    const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
8267    if (outletName) {
8268      this.updateSelectorObserverForOutlet(outletName);
8269    }
8270  }
8271  elementUnmatchedAttribute(_element, attributeName) {
8272    const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
8273    if (outletName) {
8274      this.updateSelectorObserverForOutlet(outletName);
8275    }
8276  }
8277  connectOutlet(outlet, element, outletName) {
8278    var _a;
8279    if (!this.outletElementsByName.has(outletName, element)) {
8280      this.outletsByName.add(outletName, outlet);
8281      this.outletElementsByName.add(outletName, element);
8282      (_a = this.selectorObserverMap.get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletConnected(outlet, element, outletName));
8283    }
8284  }
8285  disconnectOutlet(outlet, element, outletName) {
8286    var _a;
8287    if (this.outletElementsByName.has(outletName, element)) {
8288      this.outletsByName.delete(outletName, outlet);
8289      this.outletElementsByName.delete(outletName, element);
8290      (_a = this.selectorObserverMap.get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletDisconnected(outlet, element, outletName));
8291    }
8292  }
8293  disconnectAllOutlets() {
8294    for (const outletName of this.outletElementsByName.keys) {
8295      for (const element of this.outletElementsByName.getValuesForKey(outletName)) {
8296        for (const outlet of this.outletsByName.getValuesForKey(outletName)) {
8297          this.disconnectOutlet(outlet, element, outletName);
8298        }
8299      }
8300    }
8301  }
8302  updateSelectorObserverForOutlet(outletName) {
8303    const observer = this.selectorObserverMap.get(outletName);
8304    if (observer) {
8305      observer.selector = this.selector(outletName);
8306    }
8307  }
8308  setupSelectorObserverForOutlet(outletName) {
8309    const selector = this.selector(outletName);
8310    const selectorObserver = new SelectorObserver(document.body, selector, this, { outletName });
8311    this.selectorObserverMap.set(outletName, selectorObserver);
8312    selectorObserver.start();
8313  }
8314  setupAttributeObserverForOutlet(outletName) {
8315    const attributeName = this.attributeNameForOutletName(outletName);
8316    const attributeObserver = new AttributeObserver(this.scope.element, attributeName, this);
8317    this.attributeObserverMap.set(outletName, attributeObserver);
8318    attributeObserver.start();
8319  }
8320  selector(outletName) {
8321    return this.scope.outlets.getSelectorForOutletName(outletName);
8322  }
8323  attributeNameForOutletName(outletName) {
8324    return this.scope.schema.outletAttributeForScope(this.identifier, outletName);
8325  }
8326  getOutletNameFromOutletAttributeName(attributeName) {
8327    return this.outletDefinitions.find((outletName) => this.attributeNameForOutletName(outletName) === attributeName);
8328  }
8329  get outletDependencies() {
8330    const dependencies = new Multimap();
8331    this.router.modules.forEach((module) => {
8332      const constructor = module.definition.controllerConstructor;
8333      const outlets = readInheritableStaticArrayValues(constructor, "outlets");
8334      outlets.forEach((outlet) => dependencies.add(outlet, module.identifier));
8335    });
8336    return dependencies;
8337  }
8338  get outletDefinitions() {
8339    return this.outletDependencies.getKeysForValue(this.identifier);
8340  }
8341  get dependentControllerIdentifiers() {
8342    return this.outletDependencies.getValuesForKey(this.identifier);
8343  }
8344  get dependentContexts() {
8345    const identifiers = this.dependentControllerIdentifiers;
8346    return this.router.contexts.filter((context) => identifiers.includes(context.identifier));
8347  }
8348  hasOutlet(element, outletName) {
8349    return !!this.getOutlet(element, outletName) || !!this.getOutletFromMap(element, outletName);
8350  }
8351  getOutlet(element, outletName) {
8352    return this.application.getControllerForElementAndIdentifier(element, outletName);
8353  }
8354  getOutletFromMap(element, outletName) {
8355    return this.outletsByName.getValuesForKey(outletName).find((outlet) => outlet.element === element);
8356  }
8357  get scope() {
8358    return this.context.scope;
8359  }
8360  get schema() {
8361    return this.context.schema;
8362  }
8363  get identifier() {
8364    return this.context.identifier;
8365  }
8366  get application() {
8367    return this.context.application;
8368  }
8369  get router() {
8370    return this.application.router;
8371  }
8372};
8373var Context = class {
8374  constructor(module, scope) {
8375    this.logDebugActivity = (functionName, detail = {}) => {
8376      const { identifier, controller, element } = this;
8377      detail = Object.assign({ identifier, controller, element }, detail);
8378      this.application.logDebugActivity(this.identifier, functionName, detail);
8379    };
8380    this.module = module;
8381    this.scope = scope;
8382    this.controller = new module.controllerConstructor(this);
8383    this.bindingObserver = new BindingObserver(this, this.dispatcher);
8384    this.valueObserver = new ValueObserver(this, this.controller);
8385    this.targetObserver = new TargetObserver(this, this);
8386    this.outletObserver = new OutletObserver(this, this);
8387    try {
8388      this.controller.initialize();
8389      this.logDebugActivity("initialize");
8390    } catch (error2) {
8391      this.handleError(error2, "initializing controller");
8392    }
8393  }
8394  connect() {
8395    this.bindingObserver.start();
8396    this.valueObserver.start();
8397    this.targetObserver.start();
8398    this.outletObserver.start();
8399    try {
8400      this.controller.connect();
8401      this.logDebugActivity("connect");
8402    } catch (error2) {
8403      this.handleError(error2, "connecting controller");
8404    }
8405  }
8406  refresh() {
8407    this.outletObserver.refresh();
8408  }
8409  disconnect() {
8410    try {
8411      this.controller.disconnect();
8412      this.logDebugActivity("disconnect");
8413    } catch (error2) {
8414      this.handleError(error2, "disconnecting controller");
8415    }
8416    this.outletObserver.stop();
8417    this.targetObserver.stop();
8418    this.valueObserver.stop();
8419    this.bindingObserver.stop();
8420  }
8421  get application() {
8422    return this.module.application;
8423  }
8424  get identifier() {
8425    return this.module.identifier;
8426  }
8427  get schema() {
8428    return this.application.schema;
8429  }
8430  get dispatcher() {
8431    return this.application.dispatcher;
8432  }
8433  get element() {
8434    return this.scope.element;
8435  }
8436  get parentElement() {
8437    return this.element.parentElement;
8438  }
8439  handleError(error2, message, detail = {}) {
8440    const { identifier, controller, element } = this;
8441    detail = Object.assign({ identifier, controller, element }, detail);
8442    this.application.handleError(error2, `Error ${message}`, detail);
8443  }
8444  targetConnected(element, name) {
8445    this.invokeControllerMethod(`${name}TargetConnected`, element);
8446  }
8447  targetDisconnected(element, name) {
8448    this.invokeControllerMethod(`${name}TargetDisconnected`, element);
8449  }
8450  outletConnected(outlet, element, name) {
8451    this.invokeControllerMethod(`${namespaceCamelize(name)}OutletConnected`, outlet, element);
8452  }
8453  outletDisconnected(outlet, element, name) {
8454    this.invokeControllerMethod(`${namespaceCamelize(name)}OutletDisconnected`, outlet, element);
8455  }
8456  invokeControllerMethod(methodName, ...args) {
8457    const controller = this.controller;
8458    if (typeof controller[methodName] == "function") {
8459      controller[methodName](...args);
8460    }
8461  }
8462};
8463function bless(constructor) {
8464  return shadow(constructor, getBlessedProperties(constructor));
8465}
8466function shadow(constructor, properties) {
8467  const shadowConstructor = extend2(constructor);
8468  const shadowProperties = getShadowProperties(constructor.prototype, properties);
8469  Object.defineProperties(shadowConstructor.prototype, shadowProperties);
8470  return shadowConstructor;
8471}
8472function getBlessedProperties(constructor) {
8473  const blessings = readInheritableStaticArrayValues(constructor, "blessings");
8474  return blessings.reduce((blessedProperties, blessing) => {
8475    const properties = blessing(constructor);
8476    for (const key in properties) {
8477      const descriptor = blessedProperties[key] || {};
8478      blessedProperties[key] = Object.assign(descriptor, properties[key]);
8479    }
8480    return blessedProperties;
8481  }, {});
8482}
8483function getShadowProperties(prototype, properties) {
8484  return getOwnKeys(properties).reduce((shadowProperties, key) => {
8485    const descriptor = getShadowedDescriptor(prototype, properties, key);
8486    if (descriptor) {
8487      Object.assign(shadowProperties, { [key]: descriptor });
8488    }
8489    return shadowProperties;
8490  }, {});
8491}
8492function getShadowedDescriptor(prototype, properties, key) {
8493  const shadowingDescriptor = Object.getOwnPropertyDescriptor(prototype, key);
8494  const shadowedByValue = shadowingDescriptor && "value" in shadowingDescriptor;
8495  if (!shadowedByValue) {
8496    const descriptor = Object.getOwnPropertyDescriptor(properties, key).value;
8497    if (shadowingDescriptor) {
8498      descriptor.get = shadowingDescriptor.get || descriptor.get;
8499      descriptor.set = shadowingDescriptor.set || descriptor.set;
8500    }
8501    return descriptor;
8502  }
8503}
8504var getOwnKeys = (() => {
8505  if (typeof Object.getOwnPropertySymbols == "function") {
8506    return (object) => [...Object.getOwnPropertyNames(object), ...Object.getOwnPropertySymbols(object)];
8507  } else {
8508    return Object.getOwnPropertyNames;
8509  }
8510})();
8511var extend2 = (() => {
8512  function extendWithReflect(constructor) {
8513    function extended() {
8514      return Reflect.construct(constructor, arguments, new.target);
8515    }
8516    extended.prototype = Object.create(constructor.prototype, {
8517      constructor: { value: extended }
8518    });
8519    Reflect.setPrototypeOf(extended, constructor);
8520    return extended;
8521  }
8522  function testReflectExtension() {
8523    const a = function() {
8524      this.a.call(this);
8525    };
8526    const b = extendWithReflect(a);
8527    b.prototype.a = function() {
8528    };
8529    return new b();
8530  }
8531  try {
8532    testReflectExtension();
8533    return extendWithReflect;
8534  } catch (error2) {
8535    return (constructor) => class extended extends constructor {
8536    };
8537  }
8538})();
8539function blessDefinition(definition) {
8540  return {
8541    identifier: definition.identifier,
8542    controllerConstructor: bless(definition.controllerConstructor)
8543  };
8544}
8545var Module = class {
8546  constructor(application2, definition) {
8547    this.application = application2;
8548    this.definition = blessDefinition(definition);
8549    this.contextsByScope = /* @__PURE__ */ new WeakMap();
8550    this.connectedContexts = /* @__PURE__ */ new Set();
8551  }
8552  get identifier() {
8553    return this.definition.identifier;
8554  }
8555  get controllerConstructor() {
8556    return this.definition.controllerConstructor;
8557  }
8558  get contexts() {
8559    return Array.from(this.connectedContexts);
8560  }
8561  connectContextForScope(scope) {
8562    const context = this.fetchContextForScope(scope);
8563    this.connectedContexts.add(context);
8564    context.connect();
8565  }
8566  disconnectContextForScope(scope) {
8567    const context = this.contextsByScope.get(scope);
8568    if (context) {
8569      this.connectedContexts.delete(context);
8570      context.disconnect();
8571    }
8572  }
8573  fetchContextForScope(scope) {
8574    let context = this.contextsByScope.get(scope);
8575    if (!context) {
8576      context = new Context(this, scope);
8577      this.contextsByScope.set(scope, context);
8578    }
8579    return context;
8580  }
8581};
8582var ClassMap = class {
8583  constructor(scope) {
8584    this.scope = scope;
8585  }
8586  has(name) {
8587    return this.data.has(this.getDataKey(name));
8588  }
8589  get(name) {
8590    return this.getAll(name)[0];
8591  }
8592  getAll(name) {
8593    const tokenString = this.data.get(this.getDataKey(name)) || "";
8594    return tokenize(tokenString);
8595  }
8596  getAttributeName(name) {
8597    return this.data.getAttributeNameForKey(this.getDataKey(name));
8598  }
8599  getDataKey(name) {
8600    return `${name}-class`;
8601  }
8602  get data() {
8603    return this.scope.data;
8604  }
8605};
8606var DataMap = class {
8607  constructor(scope) {
8608    this.scope = scope;
8609  }
8610  get element() {
8611    return this.scope.element;
8612  }
8613  get identifier() {
8614    return this.scope.identifier;
8615  }
8616  get(key) {
8617    const name = this.getAttributeNameForKey(key);
8618    return this.element.getAttribute(name);
8619  }
8620  set(key, value) {
8621    const name = this.getAttributeNameForKey(key);
8622    this.element.setAttribute(name, value);
8623    return this.get(key);
8624  }
8625  has(key) {
8626    const name = this.getAttributeNameForKey(key);
8627    return this.element.hasAttribute(name);
8628  }
8629  delete(key) {
8630    if (this.has(key)) {
8631      const name = this.getAttributeNameForKey(key);
8632      this.element.removeAttribute(name);
8633      return true;
8634    } else {
8635      return false;
8636    }
8637  }
8638  getAttributeNameForKey(key) {
8639    return `data-${this.identifier}-${dasherize(key)}`;
8640  }
8641};
8642var Guide = class {
8643  constructor(logger) {
8644    this.warnedKeysByObject = /* @__PURE__ */ new WeakMap();
8645    this.logger = logger;
8646  }
8647  warn(object, key, message) {
8648    let warnedKeys = this.warnedKeysByObject.get(object);
8649    if (!warnedKeys) {
8650      warnedKeys = /* @__PURE__ */ new Set();
8651      this.warnedKeysByObject.set(object, warnedKeys);
8652    }
8653    if (!warnedKeys.has(key)) {
8654      warnedKeys.add(key);
8655      this.logger.warn(message, object);
8656    }
8657  }
8658};
8659function attributeValueContainsToken(attributeName, token) {
8660  return `[${attributeName}~="${token}"]`;
8661}
8662var TargetSet = class {
8663  constructor(scope) {
8664    this.scope = scope;
8665  }
8666  get element() {
8667    return this.scope.element;
8668  }
8669  get identifier() {
8670    return this.scope.identifier;
8671  }
8672  get schema() {
8673    return this.scope.schema;
8674  }
8675  has(targetName) {
8676    return this.find(targetName) != null;
8677  }
8678  find(...targetNames) {
8679    return targetNames.reduce((target, targetName) => target || this.findTarget(targetName) || this.findLegacyTarget(targetName), void 0);
8680  }
8681  findAll(...targetNames) {
8682    return targetNames.reduce((targets, targetName) => [
8683      ...targets,
8684      ...this.findAllTargets(targetName),
8685      ...this.findAllLegacyTargets(targetName)
8686    ], []);
8687  }
8688  findTarget(targetName) {
8689    const selector = this.getSelectorForTargetName(targetName);
8690    return this.scope.findElement(selector);
8691  }
8692  findAllTargets(targetName) {
8693    const selector = this.getSelectorForTargetName(targetName);
8694    return this.scope.findAllElements(selector);
8695  }
8696  getSelectorForTargetName(targetName) {
8697    const attributeName = this.schema.targetAttributeForScope(this.identifier);
8698    return attributeValueContainsToken(attributeName, targetName);
8699  }
8700  findLegacyTarget(targetName) {
8701    const selector = this.getLegacySelectorForTargetName(targetName);
8702    return this.deprecate(this.scope.findElement(selector), targetName);
8703  }
8704  findAllLegacyTargets(targetName) {
8705    const selector = this.getLegacySelectorForTargetName(targetName);
8706    return this.scope.findAllElements(selector).map((element) => this.deprecate(element, targetName));
8707  }
8708  getLegacySelectorForTargetName(targetName) {
8709    const targetDescriptor = `${this.identifier}.${targetName}`;
8710    return attributeValueContainsToken(this.schema.targetAttribute, targetDescriptor);
8711  }
8712  deprecate(element, targetName) {
8713    if (element) {
8714      const { identifier } = this;
8715      const attributeName = this.schema.targetAttribute;
8716      const revisedAttributeName = this.schema.targetAttributeForScope(identifier);
8717      this.guide.warn(element, `target:${targetName}`, `Please replace ${attributeName}="${identifier}.${targetName}" with ${revisedAttributeName}="${targetName}". The ${attributeName} attribute is deprecated and will be removed in a future version of Stimulus.`);
8718    }
8719    return element;
8720  }
8721  get guide() {
8722    return this.scope.guide;
8723  }
8724};
8725var OutletSet = class {
8726  constructor(scope, controllerElement) {
8727    this.scope = scope;
8728    this.controllerElement = controllerElement;
8729  }
8730  get element() {
8731    return this.scope.element;
8732  }
8733  get identifier() {
8734    return this.scope.identifier;
8735  }
8736  get schema() {
8737    return this.scope.schema;
8738  }
8739  has(outletName) {
8740    return this.find(outletName) != null;
8741  }
8742  find(...outletNames) {
8743    return outletNames.reduce((outlet, outletName) => outlet || this.findOutlet(outletName), void 0);
8744  }
8745  findAll(...outletNames) {
8746    return outletNames.reduce((outlets, outletName) => [...outlets, ...this.findAllOutlets(outletName)], []);
8747  }
8748  getSelectorForOutletName(outletName) {
8749    const attributeName = this.schema.outletAttributeForScope(this.identifier, outletName);
8750    return this.controllerElement.getAttribute(attributeName);
8751  }
8752  findOutlet(outletName) {
8753    const selector = this.getSelectorForOutletName(outletName);
8754    if (selector)
8755      return this.findElement(selector, outletName);
8756  }
8757  findAllOutlets(outletName) {
8758    const selector = this.getSelectorForOutletName(outletName);
8759    return selector ? this.findAllElements(selector, outletName) : [];
8760  }
8761  findElement(selector, outletName) {
8762    const elements = this.scope.queryElements(selector);
8763    return elements.filter((element) => this.matchesElement(element, selector, outletName))[0];
8764  }
8765  findAllElements(selector, outletName) {
8766    const elements = this.scope.queryElements(selector);
8767    return elements.filter((element) => this.matchesElement(element, selector, outletName));
8768  }
8769  matchesElement(element, selector, outletName) {
8770    const controllerAttribute = element.getAttribute(this.scope.schema.controllerAttribute) || "";
8771    return element.matches(selector) && controllerAttribute.split(" ").includes(outletName);
8772  }
8773};
8774var Scope = class _Scope {
8775  constructor(schema, element, identifier, logger) {
8776    this.targets = new TargetSet(this);
8777    this.classes = new ClassMap(this);
8778    this.data = new DataMap(this);
8779    this.containsElement = (element2) => {
8780      return element2.closest(this.controllerSelector) === this.element;
8781    };
8782    this.schema = schema;
8783    this.element = element;
8784    this.identifier = identifier;
8785    this.guide = new Guide(logger);
8786    this.outlets = new OutletSet(this.documentScope, element);
8787  }
8788  findElement(selector) {
8789    return this.element.matches(selector) ? this.element : this.queryElements(selector).find(this.containsElement);
8790  }
8791  findAllElements(selector) {
8792    return [
8793      ...this.element.matches(selector) ? [this.element] : [],
8794      ...this.queryElements(selector).filter(this.containsElement)
8795    ];
8796  }
8797  queryElements(selector) {
8798    return Array.from(this.element.querySelectorAll(selector));
8799  }
8800  get controllerSelector() {
8801    return attributeValueContainsToken(this.schema.controllerAttribute, this.identifier);
8802  }
8803  get isDocumentScope() {
8804    return this.element === document.documentElement;
8805  }
8806  get documentScope() {
8807    return this.isDocumentScope ? this : new _Scope(this.schema, document.documentElement, this.identifier, this.guide.logger);
8808  }
8809};
8810var ScopeObserver = class {
8811  constructor(element, schema, delegate) {
8812    this.element = element;
8813    this.schema = schema;
8814    this.delegate = delegate;
8815    this.valueListObserver = new ValueListObserver(this.element, this.controllerAttribute, this);
8816    this.scopesByIdentifierByElement = /* @__PURE__ */ new WeakMap();
8817    this.scopeReferenceCounts = /* @__PURE__ */ new WeakMap();
8818  }
8819  start() {
8820    this.valueListObserver.start();
8821  }
8822  stop() {
8823    this.valueListObserver.stop();
8824  }
8825  get controllerAttribute() {
8826    return this.schema.controllerAttribute;
8827  }
8828  parseValueForToken(token) {
8829    const { element, content: identifier } = token;
8830    return this.parseValueForElementAndIdentifier(element, identifier);
8831  }
8832  parseValueForElementAndIdentifier(element, identifier) {
8833    const scopesByIdentifier = this.fetchScopesByIdentifierForElement(element);
8834    let scope = scopesByIdentifier.get(identifier);
8835    if (!scope) {
8836      scope = this.delegate.createScopeForElementAndIdentifier(element, identifier);
8837      scopesByIdentifier.set(identifier, scope);
8838    }
8839    return scope;
8840  }
8841  elementMatchedValue(element, value) {
8842    const referenceCount = (this.scopeReferenceCounts.get(value) || 0) + 1;
8843    this.scopeReferenceCounts.set(value, referenceCount);
8844    if (referenceCount == 1) {
8845      this.delegate.scopeConnected(value);
8846    }
8847  }
8848  elementUnmatchedValue(element, value) {
8849    const referenceCount = this.scopeReferenceCounts.get(value);
8850    if (referenceCount) {
8851      this.scopeReferenceCounts.set(value, referenceCount - 1);
8852      if (referenceCount == 1) {
8853        this.delegate.scopeDisconnected(value);
8854      }
8855    }
8856  }
8857  fetchScopesByIdentifierForElement(element) {
8858    let scopesByIdentifier = this.scopesByIdentifierByElement.get(element);
8859    if (!scopesByIdentifier) {
8860      scopesByIdentifier = /* @__PURE__ */ new Map();
8861      this.scopesByIdentifierByElement.set(element, scopesByIdentifier);
8862    }
8863    return scopesByIdentifier;
8864  }
8865};
8866var Router = class {
8867  constructor(application2) {
8868    this.application = application2;
8869    this.scopeObserver = new ScopeObserver(this.element, this.schema, this);
8870    this.scopesByIdentifier = new Multimap();
8871    this.modulesByIdentifier = /* @__PURE__ */ new Map();
8872  }
8873  get element() {
8874    return this.application.element;
8875  }
8876  get schema() {
8877    return this.application.schema;
8878  }
8879  get logger() {
8880    return this.application.logger;
8881  }
8882  get controllerAttribute() {
8883    return this.schema.controllerAttribute;
8884  }
8885  get modules() {
8886    return Array.from(this.modulesByIdentifier.values());
8887  }
8888  get contexts() {
8889    return this.modules.reduce((contexts, module) => contexts.concat(module.contexts), []);
8890  }
8891  start() {
8892    this.scopeObserver.start();
8893  }
8894  stop() {
8895    this.scopeObserver.stop();
8896  }
8897  loadDefinition(definition) {
8898    this.unloadIdentifier(definition.identifier);
8899    const module = new Module(this.application, definition);
8900    this.connectModule(module);
8901    const afterLoad = definition.controllerConstructor.afterLoad;
8902    if (afterLoad) {
8903      afterLoad.call(definition.controllerConstructor, definition.identifier, this.application);
8904    }
8905  }
8906  unloadIdentifier(identifier) {
8907    const module = this.modulesByIdentifier.get(identifier);
8908    if (module) {
8909      this.disconnectModule(module);
8910    }
8911  }
8912  getContextForElementAndIdentifier(element, identifier) {
8913    const module = this.modulesByIdentifier.get(identifier);
8914    if (module) {
8915      return module.contexts.find((context) => context.element == element);
8916    }
8917  }
8918  proposeToConnectScopeForElementAndIdentifier(element, identifier) {
8919    const scope = this.scopeObserver.parseValueForElementAndIdentifier(element, identifier);
8920    if (scope) {
8921      this.scopeObserver.elementMatchedValue(scope.element, scope);
8922    } else {
8923      console.error(`Couldn't find or create scope for identifier: "${identifier}" and element:`, element);
8924    }
8925  }
8926  handleError(error2, message, detail) {
8927    this.application.handleError(error2, message, detail);
8928  }
8929  createScopeForElementAndIdentifier(element, identifier) {
8930    return new Scope(this.schema, element, identifier, this.logger);
8931  }
8932  scopeConnected(scope) {
8933    this.scopesByIdentifier.add(scope.identifier, scope);
8934    const module = this.modulesByIdentifier.get(scope.identifier);
8935    if (module) {
8936      module.connectContextForScope(scope);
8937    }
8938  }
8939  scopeDisconnected(scope) {
8940    this.scopesByIdentifier.delete(scope.identifier, scope);
8941    const module = this.modulesByIdentifier.get(scope.identifier);
8942    if (module) {
8943      module.disconnectContextForScope(scope);
8944    }
8945  }
8946  connectModule(module) {
8947    this.modulesByIdentifier.set(module.identifier, module);
8948    const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);
8949    scopes.forEach((scope) => module.connectContextForScope(scope));
8950  }
8951  disconnectModule(module) {
8952    this.modulesByIdentifier.delete(module.identifier);
8953    const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);
8954    scopes.forEach((scope) => module.disconnectContextForScope(scope));
8955  }
8956};
8957var defaultSchema = {
8958  controllerAttribute: "data-controller",
8959  actionAttribute: "data-action",
8960  targetAttribute: "data-target",
8961  targetAttributeForScope: (identifier) => `data-${identifier}-target`,
8962  outletAttributeForScope: (identifier, outlet) => `data-${identifier}-${outlet}-outlet`,
8963  keyMappings: Object.assign(Object.assign({ enter: "Enter", tab: "Tab", esc: "Escape", space: " ", up: "ArrowUp", down: "ArrowDown", left: "ArrowLeft", right: "ArrowRight", home: "Home", end: "End", page_up: "PageUp", page_down: "PageDown" }, objectFromEntries("abcdefghijklmnopqrstuvwxyz".split("").map((c) => [c, c]))), objectFromEntries("0123456789".split("").map((n) => [n, n])))
8964};
8965function objectFromEntries(array) {
8966  return array.reduce((memo, [k, v]) => Object.assign(Object.assign({}, memo), { [k]: v }), {});
8967}
8968var Application = class {
8969  constructor(element = document.documentElement, schema = defaultSchema) {
8970    this.logger = console;
8971    this.debug = false;
8972    this.logDebugActivity = (identifier, functionName, detail = {}) => {
8973      if (this.debug) {
8974        this.logFormattedMessage(identifier, functionName, detail);
8975      }
8976    };
8977    this.element = element;
8978    this.schema = schema;
8979    this.dispatcher = new Dispatcher(this);
8980    this.router = new Router(this);
8981    this.actionDescriptorFilters = Object.assign({}, defaultActionDescriptorFilters);
8982  }
8983  static start(element, schema) {
8984    const application2 = new this(element, schema);
8985    application2.start();
8986    return application2;
8987  }
8988  async start() {
8989    await domReady();
8990    this.logDebugActivity("application", "starting");
8991    this.dispatcher.start();
8992    this.router.start();
8993    this.logDebugActivity("application", "start");
8994  }
8995  stop() {
8996    this.logDebugActivity("application", "stopping");
8997    this.dispatcher.stop();
8998    this.router.stop();
8999    this.logDebugActivity("application", "stop");
9000  }
9001  register(identifier, controllerConstructor) {
9002    this.load({ identifier, controllerConstructor });
9003  }
9004  registerActionOption(name, filter) {
9005    this.actionDescriptorFilters[name] = filter;
9006  }
9007  load(head, ...rest) {
9008    const definitions = Array.isArray(head) ? head : [head, ...rest];
9009    definitions.forEach((definition) => {
9010      if (definition.controllerConstructor.shouldLoad) {
9011        this.router.loadDefinition(definition);
9012      }
9013    });
9014  }
9015  unload(head, ...rest) {
9016    const identifiers = Array.isArray(head) ? head : [head, ...rest];
9017    identifiers.forEach((identifier) => this.router.unloadIdentifier(identifier));
9018  }
9019  get controllers() {
9020    return this.router.contexts.map((context) => context.controller);
9021  }
9022  getControllerForElementAndIdentifier(element, identifier) {
9023    const context = this.router.getContextForElementAndIdentifier(element, identifier);
9024    return context ? context.controller : null;
9025  }
9026  handleError(error2, message, detail) {
9027    var _a;
9028    this.logger.error(`%s
9029
9030%o
9031
9032%o`, message, error2, detail);
9033    (_a = window.onerror) === null || _a === void 0 ? void 0 : _a.call(window, message, "", 0, 0, error2);
9034  }
9035  logFormattedMessage(identifier, functionName, detail = {}) {
9036    detail = Object.assign({ application: this }, detail);
9037    this.logger.groupCollapsed(`${identifier} #${functionName}`);
9038    this.logger.log("details:", Object.assign({}, detail));
9039    this.logger.groupEnd();
9040  }
9041};
9042function domReady() {
9043  return new Promise((resolve) => {
9044    if (document.readyState == "loading") {
9045      document.addEventListener("DOMContentLoaded", () => resolve());
9046    } else {
9047      resolve();
9048    }
9049  });
9050}
9051function ClassPropertiesBlessing(constructor) {
9052  const classes = readInheritableStaticArrayValues(constructor, "classes");
9053  return classes.reduce((properties, classDefinition) => {
9054    return Object.assign(properties, propertiesForClassDefinition(classDefinition));
9055  }, {});
9056}
9057function propertiesForClassDefinition(key) {
9058  return {
9059    [`${key}Class`]: {
9060      get() {
9061        const { classes } = this;
9062        if (classes.has(key)) {
9063          return classes.get(key);
9064        } else {
9065          const attribute = classes.getAttributeName(key);
9066          throw new Error(`Missing attribute "${attribute}"`);
9067        }
9068      }
9069    },
9070    [`${key}Classes`]: {
9071      get() {
9072        return this.classes.getAll(key);
9073      }
9074    },
9075    [`has${capitalize(key)}Class`]: {
9076      get() {
9077        return this.classes.has(key);
9078      }
9079    }
9080  };
9081}
9082function OutletPropertiesBlessing(constructor) {
9083  const outlets = readInheritableStaticArrayValues(constructor, "outlets");
9084  return outlets.reduce((properties, outletDefinition) => {
9085    return Object.assign(properties, propertiesForOutletDefinition(outletDefinition));
9086  }, {});
9087}
9088function getOutletController(controller, element, identifier) {
9089  return controller.application.getControllerForElementAndIdentifier(element, identifier);
9090}
9091function getControllerAndEnsureConnectedScope(controller, element, outletName) {
9092  let outletController = getOutletController(controller, element, outletName);
9093  if (outletController)
9094    return outletController;
9095  controller.application.router.proposeToConnectScopeForElementAndIdentifier(element, outletName);
9096  outletController = getOutletController(controller, element, outletName);
9097  if (outletController)
9098    return outletController;
9099}
9100function propertiesForOutletDefinition(name) {
9101  const camelizedName = namespaceCamelize(name);
9102  return {
9103    [`${camelizedName}Outlet`]: {
9104      get() {
9105        const outletElement = this.outlets.find(name);
9106        const selector = this.outlets.getSelectorForOutletName(name);
9107        if (outletElement) {
9108          const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);
9109          if (outletController)
9110            return outletController;
9111          throw new Error(`The provided outlet element is missing an outlet controller "${name}" instance for host controller "${this.identifier}"`);
9112        }
9113        throw new Error(`Missing outlet element "${name}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${selector}".`);
9114      }
9115    },
9116    [`${camelizedName}Outlets`]: {
9117      get() {
9118        const outlets = this.outlets.findAll(name);
9119        if (outlets.length > 0) {
9120          return outlets.map((outletElement) => {
9121            const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);
9122            if (outletController)
9123              return outletController;
9124            console.warn(`The provided outlet element is missing an outlet controller "${name}" instance for host controller "${this.identifier}"`, outletElement);
9125          }).filter((controller) => controller);
9126        }
9127        return [];
9128      }
9129    },
9130    [`${camelizedName}OutletElement`]: {
9131      get() {
9132        const outletElement = this.outlets.find(name);
9133        const selector = this.outlets.getSelectorForOutletName(name);
9134        if (outletElement) {
9135          return outletElement;
9136        } else {
9137          throw new Error(`Missing outlet element "${name}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${selector}".`);
9138        }
9139      }
9140    },
9141    [`${camelizedName}OutletElements`]: {
9142      get() {
9143        return this.outlets.findAll(name);
9144      }
9145    },
9146    [`has${capitalize(camelizedName)}Outlet`]: {
9147      get() {
9148        return this.outlets.has(name);
9149      }
9150    }
9151  };
9152}
9153function TargetPropertiesBlessing(constructor) {
9154  const targets = readInheritableStaticArrayValues(constructor, "targets");
9155  return targets.reduce((properties, targetDefinition) => {
9156    return Object.assign(properties, propertiesForTargetDefinition(targetDefinition));
9157  }, {});
9158}
9159function propertiesForTargetDefinition(name) {
9160  return {
9161    [`${name}Target`]: {
9162      get() {
9163        const target = this.targets.find(name);
9164        if (target) {
9165          return target;
9166        } else {
9167          throw new Error(`Missing target element "${name}" for "${this.identifier}" controller`);
9168        }
9169      }
9170    },
9171    [`${name}Targets`]: {
9172      get() {
9173        return this.targets.findAll(name);
9174      }
9175    },
9176    [`has${capitalize(name)}Target`]: {
9177      get() {
9178        return this.targets.has(name);
9179      }
9180    }
9181  };
9182}
9183function ValuePropertiesBlessing(constructor) {
9184  const valueDefinitionPairs = readInheritableStaticObjectPairs(constructor, "values");
9185  const propertyDescriptorMap = {
9186    valueDescriptorMap: {
9187      get() {
9188        return valueDefinitionPairs.reduce((result, valueDefinitionPair) => {
9189          const valueDescriptor = parseValueDefinitionPair(valueDefinitionPair, this.identifier);
9190          const attributeName = this.data.getAttributeNameForKey(valueDescriptor.key);
9191          return Object.assign(result, { [attributeName]: valueDescriptor });
9192        }, {});
9193      }
9194    }
9195  };
9196  return valueDefinitionPairs.reduce((properties, valueDefinitionPair) => {
9197    return Object.assign(properties, propertiesForValueDefinitionPair(valueDefinitionPair));
9198  }, propertyDescriptorMap);
9199}
9200function propertiesForValueDefinitionPair(valueDefinitionPair, controller) {
9201  const definition = parseValueDefinitionPair(valueDefinitionPair, controller);
9202  const { key, name, reader: read, writer: write } = definition;
9203  return {
9204    [name]: {
9205      get() {
9206        const value = this.data.get(key);
9207        if (value !== null) {
9208          return read(value);
9209        } else {
9210          return definition.defaultValue;
9211        }
9212      },
9213      set(value) {
9214        if (value === void 0) {
9215          this.data.delete(key);
9216        } else {
9217          this.data.set(key, write(value));
9218        }
9219      }
9220    },
9221    [`has${capitalize(name)}`]: {
9222      get() {
9223        return this.data.has(key) || definition.hasCustomDefaultValue;
9224      }
9225    }
9226  };
9227}
9228function parseValueDefinitionPair([token, typeDefinition], controller) {
9229  return valueDescriptorForTokenAndTypeDefinition({
9230    controller,
9231    token,
9232    typeDefinition
9233  });
9234}
9235function parseValueTypeConstant(constant) {
9236  switch (constant) {
9237    case Array:
9238      return "array";
9239    case Boolean:
9240      return "boolean";
9241    case Number:
9242      return "number";
9243    case Object:
9244      return "object";
9245    case String:
9246      return "string";
9247  }
9248}
9249function parseValueTypeDefault(defaultValue) {
9250  switch (typeof defaultValue) {
9251    case "boolean":
9252      return "boolean";
9253    case "number":
9254      return "number";
9255    case "string":
9256      return "string";
9257  }
9258  if (Array.isArray(defaultValue))
9259    return "array";
9260  if (Object.prototype.toString.call(defaultValue) === "[object Object]")
9261    return "object";
9262}
9263function parseValueTypeObject(payload) {
9264  const { controller, token, typeObject } = payload;
9265  const hasType = isSomething(typeObject.type);
9266  const hasDefault = isSomething(typeObject.default);
9267  const fullObject = hasType && hasDefault;
9268  const onlyType = hasType && !hasDefault;
9269  const onlyDefault = !hasType && hasDefault;
9270  const typeFromObject = parseValueTypeConstant(typeObject.type);
9271  const typeFromDefaultValue = parseValueTypeDefault(payload.typeObject.default);
9272  if (onlyType)
9273    return typeFromObject;
9274  if (onlyDefault)
9275    return typeFromDefaultValue;
9276  if (typeFromObject !== typeFromDefaultValue) {
9277    const propertyPath = controller ? `${controller}.${token}` : token;
9278    throw new Error(`The specified default value for the Stimulus Value "${propertyPath}" must match the defined type "${typeFromObject}". The provided default value of "${typeObject.default}" is of type "${typeFromDefaultValue}".`);
9279  }
9280  if (fullObject)
9281    return typeFromObject;
9282}
9283function parseValueTypeDefinition(payload) {
9284  const { controller, token, typeDefinition } = payload;
9285  const typeObject = { controller, token, typeObject: typeDefinition };
9286  const typeFromObject = parseValueTypeObject(typeObject);
9287  const typeFromDefaultValue = parseValueTypeDefault(typeDefinition);
9288  const typeFromConstant = parseValueTypeConstant(typeDefinition);
9289  const type = typeFromObject || typeFromDefaultValue || typeFromConstant;
9290  if (type)
9291    return type;
9292  const propertyPath = controller ? `${controller}.${typeDefinition}` : token;
9293  throw new Error(`Unknown value type "${propertyPath}" for "${token}" value`);
9294}
9295function defaultValueForDefinition(typeDefinition) {
9296  const constant = parseValueTypeConstant(typeDefinition);
9297  if (constant)
9298    return defaultValuesByType[constant];
9299  const hasDefault = hasProperty(typeDefinition, "default");
9300  const hasType = hasProperty(typeDefinition, "type");
9301  const typeObject = typeDefinition;
9302  if (hasDefault)
9303    return typeObject.default;
9304  if (hasType) {
9305    const { type } = typeObject;
9306    const constantFromType = parseValueTypeConstant(type);
9307    if (constantFromType)
9308      return defaultValuesByType[constantFromType];
9309  }
9310  return typeDefinition;
9311}
9312function valueDescriptorForTokenAndTypeDefinition(payload) {
9313  const { token, typeDefinition } = payload;
9314  const key = `${dasherize(token)}-value`;
9315  const type = parseValueTypeDefinition(payload);
9316  return {
9317    type,
9318    key,
9319    name: camelize(key),
9320    get defaultValue() {
9321      return defaultValueForDefinition(typeDefinition);
9322    },
9323    get hasCustomDefaultValue() {
9324      return parseValueTypeDefault(typeDefinition) !== void 0;
9325    },
9326    reader: readers[type],
9327    writer: writers[type] || writers.default
9328  };
9329}
9330var defaultValuesByType = {
9331  get array() {
9332    return [];
9333  },
9334  boolean: false,
9335  number: 0,
9336  get object() {
9337    return {};
9338  },
9339  string: ""
9340};
9341var readers = {
9342  array(value) {
9343    const array = JSON.parse(value);
9344    if (!Array.isArray(array)) {
9345      throw new TypeError(`expected value of type "array" but instead got value "${value}" of type "${parseValueTypeDefault(array)}"`);
9346    }
9347    return array;
9348  },
9349  boolean(value) {
9350    return !(value == "0" || String(value).toLowerCase() == "false");
9351  },
9352  number(value) {
9353    return Number(value.replace(/_/g, ""));
9354  },
9355  object(value) {
9356    const object = JSON.parse(value);
9357    if (object === null || typeof object != "object" || Array.isArray(object)) {
9358      throw new TypeError(`expected value of type "object" but instead got value "${value}" of type "${parseValueTypeDefault(object)}"`);
9359    }
9360    return object;
9361  },
9362  string(value) {
9363    return value;
9364  }
9365};
9366var writers = {
9367  default: writeString,
9368  array: writeJSON,
9369  object: writeJSON
9370};
9371function writeJSON(value) {
9372  return JSON.stringify(value);
9373}
9374function writeString(value) {
9375  return `${value}`;
9376}
9377var Controller = class {
9378  constructor(context) {
9379    this.context = context;
9380  }
9381  static get shouldLoad() {
9382    return true;
9383  }
9384  static afterLoad(_identifier, _application) {
9385    return;
9386  }
9387  get application() {
9388    return this.context.application;
9389  }
9390  get scope() {
9391    return this.context.scope;
9392  }
9393  get element() {
9394    return this.scope.element;
9395  }
9396  get identifier() {
9397    return this.scope.identifier;
9398  }
9399  get targets() {
9400    return this.scope.targets;
9401  }
9402  get outlets() {
9403    return this.scope.outlets;
9404  }
9405  get classes() {
9406    return this.scope.classes;
9407  }
9408  get data() {
9409    return this.scope.data;
9410  }
9411  initialize() {
9412  }
9413  connect() {
9414  }
9415  disconnect() {
9416  }
9417  dispatch(eventName, { target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true } = {}) {
9418    const type = prefix ? `${prefix}:${eventName}` : eventName;
9419    const event = new CustomEvent(type, { detail, bubbles, cancelable });
9420    target.dispatchEvent(event);
9421    return event;
9422  }
9423};
9424Controller.blessings = [
9425  ClassPropertiesBlessing,
9426  TargetPropertiesBlessing,
9427  ValuePropertiesBlessing,
9428  OutletPropertiesBlessing
9429];
9430Controller.targets = [];
9431Controller.outlets = [];
9432Controller.values = {};
9433
9434// app/javascript/controllers/application.js
9435var application = Application.start();
9436application.debug = false;
9437window.Stimulus = application;
9438
9439// app/javascript/controllers/address_controller.js
9440var address_controller_default = class extends Controller {
9441  static targets = ["address", "output"];
9442  setAddress(e) {
9443    const { address } = e.detail;
9444    this.address = address;
9445  }
9446  set address(value) {
9447    this.addressTarget.value = value;
9448  }
9449};
9450
9451// app/javascript/controllers/country-state_controller.js
9452var JAPAN_ID = 145;
9453var country_state_controller_default = class extends Controller {
9454  static targets = [
9455    "countryId",
9456    "countryStateId",
9457    "state",
9458    "stateOption",
9459    "countryStateLabel",
9460    "addressLabel",
9461    "furigana",
9462    "furiganaField",
9463    "output"
9464  ];
9465  countryIdTargetConnected(target) {
9466    const value = target.value;
9467    if (value) {
9468      this.setOptions({ target });
9469    }
9470  }
9471  setOptions(e) {
9472    const options = this.stateOptionTargets.filter((option) => {
9473      return option.dataset.countryId == e.target.value;
9474    });
9475    const selected = this.stateOptionTargets.find((option) => {
9476      return option.selected;
9477    });
9478    if (selected && selected.dataset.countryId != e.target.value) {
9479      this.countryStateIdTarget.value = "";
9480      selected.selected = false;
9481    }
9482    this.stateOptionTargets.forEach((option) => {
9483      option.hidden = true;
9484    });
9485    if (options.length == 0) {
9486      this.stateTarget.hidden = true;
9487    } else {
9488      this.stateTarget.hidden = false;
9489      options.forEach((option) => {
9490        option.hidden = false;
9491      });
9492    }
9493    if (e.target.value != JAPAN_ID) {
9494      this.furiganaTarget.value = "";
9495      this.furiganaFieldTarget.hidden = true;
9496      this.addressLabelTarget.textContent = "\u4F4F\u6240";
9497      this.countryStateLabelTarget.textContent = "\u5DDE\u30FB\u770C\u30FB\u7701";
9498    } else {
9499      this.furiganaFieldTarget.hidden = false;
9500      this.addressLabelTarget.textContent = "\u5E02\u533A\u753A\u6751\u30FB\u756A\u5730";
9501      this.countryStateLabelTarget.textContent = "\u90FD\u9053\u5E9C\u770C";
9502    }
9503  }
9504};
9505
9506// app/javascript/controllers/fincode-card_controller.js
9507var DEFAULT_FORM_WIDTH = 400;
9508var MIN_FORM_WIDTH = 250;
9509var FORM_EXTRA_WIDTH = 30;
9510var IFRAME_HEIGHT_SLACK = 60;
9511var fincode_card_controller_default = class extends Controller {
9512  static targets = ["mount", "submit", "error"];
9513  static values = {
9514    publicKey: String,
9515    jsUrl: String,
9516    checkUrl: String,
9517    cardId: String,
9518    csrf: String,
9519    submittingText: String,
9520    iframeTitle: String
9521  };
9522  connect() {
9523    if (this.hasSubmitTarget) this.defaultSubmitText = this.submitTarget.textContent;
9524    if (this.hasErrorTarget) this.defaultErrorText = this.errorTarget.textContent;
9525    this.loadFincodeJs().then(() => this.initUi()).catch((error2) => {
9526      console.error("fincode WEBUI init failed:", error2);
9527      this.showError();
9528    });
9529  }
9530  loadFincodeJs() {
9531    if (window.Fincode) return Promise.resolve();
9532    return new Promise((resolve, reject) => {
9533      const script = document.createElement("script");
9534      script.src = this.jsUrlValue;
9535      script.onload = () => resolve();
9536      script.onerror = () => reject(new Error("failed to load fincode.js"));
9537      document.head.appendChild(script);
9538    });
9539  }
9540  initUi() {
9541    this.fincode = window.Fincode(this.publicKeyValue);
9542    this.ui = this.fincode.ui({ layout: "vertical" });
9543    this.ui.create("payments", { layout: "vertical" });
9544    this.ui.mount(this.mountTarget.id, this.mountWidth());
9545    this.iframeSizeListener = (event) => this.resizeIframe(event);
9546    window.addEventListener("message", this.iframeSizeListener);
9547  }
9548  disconnect() {
9549    if (this.iframeSizeListener) window.removeEventListener("message", this.iframeSizeListener);
9550  }
9551  resizeIframe(event) {
9552    if (event.origin !== new URL(this.jsUrlValue).origin) return;
9553    if (event.data?.action !== "iframeSize") return;
9554    const iframe = document.getElementById(`${this.mountTarget.id}-ui`);
9555    if (!iframe) return;
9556    if (this.hasIframeTitleValue) iframe.title = this.iframeTitleValue;
9557    const height = parseInt(event.data.size?.height, 10);
9558    if (Number.isFinite(height)) iframe.style.height = `${height + IFRAME_HEIGHT_SLACK}px`;
9559  }
9560  // 固定幅を渡すと狭い画面で横スクロールが出るため、表示領域から逆算する。
9561  mountWidth() {
9562    const available = this.element.clientWidth - FORM_EXTRA_WIDTH;
9563    return String(Math.min(DEFAULT_FORM_WIDTH, Math.max(MIN_FORM_WIDTH, available)));
9564  }
9565  submit(event) {
9566    event.preventDefault();
9567    if (!this.ui) {
9568      this.showError();
9569      return;
9570    }
9571    this.disableSubmit();
9572    this.ui.getFormData().then((formData) => this.run(formData)).catch((e) => {
9573      console.error("getFormData failed:", e);
9574      this.showError();
9575    });
9576  }
9577  async run(formData) {
9578    let check;
9579    try {
9580      const token = await this.tokenizeCard(formData);
9581      check = await this.createCheck(token);
9582    } catch (e) {
9583      console.error("fincode card change failed before 3DS:", e);
9584      this.showError(e.userMessage);
9585      return;
9586    }
9587    this.proceed(check);
9588  }
9589  // fincode.tokens() でカードをトークン化する(PAN は自社サーバに送らない)。
9590  tokenizeCard(formData) {
9591    return new Promise((resolve, reject) => {
9592      this.fincode.tokens(
9593        {
9594          card_no: formData.cardNo,
9595          expire: formData.expire,
9596          security_code: formData.CVC,
9597          holder_name: formData.holderName,
9598          number: "1"
9599        },
9600        (status, response) => {
9601          const token = status === 200 && response.list && response.list[0] && response.list[0].token;
9602          token ? resolve(token) : reject(response);
9603        },
9604        () => reject(new Error("fincode.tokens communication error"))
9605      );
9606    });
9607  }
9608  // colorme-api 経由でカード登録 + CHECK 決済(auto-3DS)を実行する。
9609  // 戻り: { redirect_url(チャレンジ時のみ), complete_url(フリクションレス時の遷移先) }
9610  async createCheck(token) {
9611    const res = await fetch(this.checkUrlValue, {
9612      method: "POST",
9613      headers: {
9614        "Content-Type": "application/json",
9615        Accept: "application/json",
9616        "X-CSRF-Token": this.csrfValue
9617      },
9618      body: JSON.stringify({ token, card_id: this.cardIdValue })
9619    });
9620    if (!res.ok) {
9621      const error2 = new Error(`check create failed: ${res.status}`);
9622      error2.userMessage = await res.json().then((body) => body.error).catch(() => void 0);
9623      throw error2;
9624    }
9625    const data = await res.json();
9626    if (!data.complete_url) throw new Error("invalid check response: missing complete_url");
9627    return data;
9628  }
9629  proceed(check) {
9630    if (check.redirect_url) {
9631      if (this.fincodeUrl(check.redirect_url)) {
9632        window.location.href = check.redirect_url;
9633      } else {
9634        console.error("unexpected 3DS redirect domain:", check.redirect_url);
9635        this.showError();
9636      }
9637    } else {
9638      window.location.href = check.complete_url;
9639    }
9640  }
9641  // fincode(https の *.fincode.jp)配下の URL かどうか。3DS チャレンジ遷移先の検証に使う。
9642  // HTTP へのダウングレードを防ぐため、プロトコルが https であることも検証する。
9643  fincodeUrl(url) {
9644    try {
9645      const parsed = new URL(url);
9646      if (parsed.protocol !== "https:") return false;
9647      const host = parsed.hostname;
9648      return host === "fincode.jp" || host.endsWith(".fincode.jp");
9649    } catch {
9650      return false;
9651    }
9652  }
9653  disableSubmit() {
9654    if (!this.hasSubmitTarget) return;
9655    this.submitTarget.disabled = true;
9656    if (this.hasSubmittingTextValue) this.submitTarget.textContent = this.submittingTextValue;
9657  }
9658  enableSubmit() {
9659    if (!this.hasSubmitTarget) return;
9660    this.submitTarget.disabled = false;
9661    if (this.defaultSubmitText) this.submitTarget.textContent = this.defaultSubmitText;
9662  }
9663  // message が無ければ既定の文言に戻す(前回の制限中の文言などを残さない)。
9664  showError(message) {
9665    if (this.hasErrorTarget) {
9666      this.errorTarget.textContent = message || this.defaultErrorText;
9667      this.errorTarget.hidden = false;
9668    }
9669    this.enableSubmit();
9670  }
9671};
9672
9673// app/javascript/postal-code.js
9674var import_fetch_jsonp = __toESM(require_fetch_jsonp());
9675var JSONDATA = "https://yubinbango.github.io/yubinbango-data/data";
9676var CACHE = {};
9677var PREFMAP = [
9678  "",
9679  "\u5317\u6D77\u9053",
9680  "\u9752\u68EE\u770C",
9681  "\u5CA9\u624B\u770C",
9682  "\u5BAE\u57CE\u770C",
9683  "\u79CB\u7530\u770C",
9684  "\u5C71\u5F62\u770C",
9685  "\u798F\u5CF6\u770C",
9686  "\u8328\u57CE\u770C",
9687  "\u6803\u6728\u770C",
9688  "\u7FA4\u99AC\u770C",
9689  "\u57FC\u7389\u770C",
9690  "\u5343\u8449\u770C",
9691  "\u6771\u4EAC\u90FD",
9692  "\u795E\u5948\u5DDD\u770C",
9693  "\u65B0\u6F5F\u770C",
9694  "\u5BCC\u5C71\u770C",
9695  "\u77F3\u5DDD\u770C",
9696  "\u798F\u4E95\u770C",
9697  "\u5C71\u68A8\u770C",
9698  "\u9577\u91CE\u770C",
9699  "\u5C90\u961C\u770C",
9700  "\u9759\u5CA1\u770C",
9701  "\u611B\u77E5\u770C",
9702  "\u4E09\u91CD\u770C",
9703  "\u6ECB\u8CC0\u770C",
9704  "\u4EAC\u90FD\u5E9C",
9705  "\u5927\u962A\u5E9C",
9706  "\u5175\u5EAB\u770C",
9707  "\u5948\u826F\u770C",
9708  "\u548C\u6B4C\u5C71\u770C",
9709  "\u9CE5\u53D6\u770C",
9710  "\u5CF6\u6839\u770C",
9711  "\u5CA1\u5C71\u770C",
9712  "\u5E83\u5CF6\u770C",
9713  "\u5C71\u53E3\u770C",
9714  "\u5FB3\u5CF6\u770C",
9715  "\u9999\u5DDD\u770C",
9716  "\u611B\u5A9B\u770C",
9717  "\u9AD8\u77E5\u770C",
9718  "\u798F\u5CA1\u770C",
9719  "\u4F50\u8CC0\u770C",
9720  "\u9577\u5D0E\u770C",
9721  "\u718A\u672C\u770C",
9722  "\u5927\u5206\u770C",
9723  "\u5BAE\u5D0E\u770C",
9724  "\u9E7F\u5150\u5CF6\u770C",
9725  "\u6C96\u7E04\u770C"
9726];
9727var getJapanPostalCode = (zip_code, callback) => {
9728  const vzip = zip_code;
9729  if (!vzip) return;
9730  let nzip = "";
9731  for (let i = 0; i < vzip.length; i++) {
9732    const chr = vzip.charCodeAt(i);
9733    if (chr < 48) continue;
9734    if (chr > 57) continue;
9735    nzip += vzip.charAt(i);
9736  }
9737  if (nzip.length < 7) return;
9738  const zip3 = nzip.substr(0, 3);
9739  const data = CACHE[zip3];
9740  if (data) return parse(nzip, data, callback);
9741  fetchRemote(nzip, callback);
9742};
9743var parse = (nzip, data, callback) => {
9744  let array = data[nzip];
9745  const opera = (parseInt(nzip, 10) - 0 + 4278190080).toString();
9746  if (!array && data[opera]) {
9747    array = data[opera];
9748  }
9749  if (!array) {
9750    throw new Error("Failed to parse address data");
9751  }
9752  const prefId = array[0];
9753  if (!prefId) {
9754    throw new Error("Failed to parse address data");
9755  }
9756  const jpref = PREFMAP[prefId];
9757  if (!jpref) {
9758    throw new Error("Failed to parse address data");
9759  }
9760  const prefecture = jpref;
9761  const jcity = array[1] || "";
9762  const jarea = array[2] || "";
9763  const jstrt = array[3] || "";
9764  callback({
9765    prefecture,
9766    address: jcity + jarea + jstrt
9767  });
9768};
9769var fetchRemote = (nzip, callback) => {
9770  const zip3 = nzip.substr(0, 3);
9771  const url = JSONDATA + "/" + zip3 + ".js";
9772  (0, import_fetch_jsonp.default)(url, { jsonpCallbackFunction: "$yubin" }).then((response) => {
9773    return response.json();
9774  }).then((data) => {
9775    CACHE[zip3] = data;
9776    parse(nzip, data, callback);
9777  }).catch(() => {
9778  });
9779};
9780
9781// app/javascript/controllers/postal-code_controller.js
9782var postal_code_controller_default = class extends Controller {
9783  static targets = ["postalCode", "output"];
9784  search() {
9785    getJapanPostalCode(this.postalCode, (data) => {
9786      this.dispatch("search", { detail: data });
9787    });
9788  }
9789  get postalCode() {
9790    return this.postalCodeTarget.value;
9791  }
9792};
9793
9794// app/javascript/controllers/prefecture_controller.js
9795var prefecture_controller_default = class extends Controller {
9796  static targets = ["prefecture", "output"];
9797  setPrefectureId(e) {
9798    const { prefecture } = e.detail;
9799    const prefectureId = Array.from(this.prefectureTarget).find((o) => o.text === prefecture).value;
9800    this.prefecture = prefectureId;
9801  }
9802  set prefecture(value) {
9803    this.prefectureTarget.value = value;
9804  }
9805};
9806
9807// app/javascript/controllers/star_rating_controller.js
9808var star_rating_controller_default = class extends Controller {
9809  static targets = ["star", "input"];
9810  static values = {
9811    unfilledStarUrl: String,
9812    filledStarUrl: String
9813  };
9814  connect() {
9815    this.starNum = null;
9816    this.loadStar(this.inputTarget.value);
9817  }
9818  highlight({ params: { index } }) {
9819    this.updateStars(index);
9820  }
9821  select({ params: { index } }) {
9822    if (this.starNum === index) {
9823      this.starNum = null;
9824      this.inputTarget.value = 0;
9825    } else {
9826      this.starNum = index;
9827      this.inputTarget.value = this.starNum;
9828    }
9829    this.updateStars(this.starNum);
9830  }
9831  reset() {
9832    this.updateStars(this.starNum);
9833  }
9834  loadStar(num) {
9835    this.starNum = num ? parseInt(num) : null;
9836    this.updateStars(this.starNum);
9837  }
9838  updateStars(index) {
9839    this.starTargets.forEach((star, i) => {
9840      if (i < index) {
9841        star.style.backgroundImage = `url(${this.filledStarUrlValue})`;
9842      } else {
9843        star.style.backgroundImage = `url(${this.unfilledStarUrlValue})`;
9844      }
9845    });
9846  }
9847};
9848
9849// app/javascript/controllers/submit_guard_controller.js
9850var submit_guard_controller_default = class extends Controller {
9851  connect() {
9852    this.submitted = false;
9853    this.onPageShow = (event) => {
9854      if (event.persisted) this.reset();
9855    };
9856    window.addEventListener("pageshow", this.onPageShow);
9857  }
9858  disconnect() {
9859    window.removeEventListener("pageshow", this.onPageShow);
9860  }
9861  submit(event) {
9862    if (this.submitted) {
9863      event.preventDefault();
9864      return;
9865    }
9866    this.submitted = true;
9867    requestAnimationFrame(() => {
9868      this.submitButtons().forEach((button) => {
9869        button.disabled = true;
9870      });
9871    });
9872  }
9873  reset() {
9874    this.submitted = false;
9875    this.submitButtons().forEach((button) => {
9876      button.disabled = false;
9877    });
9878  }
9879  submitButtons() {
9880    return this.element.querySelectorAll("[type=submit]");
9881  }
9882};
9883
9884// app/javascript/controllers/index.js
9885application.register("address", address_controller_default);
9886application.register("country-state", country_state_controller_default);
9887application.register("fincode-card", fincode_card_controller_default);
9888application.register("postal-code", postal_code_controller_default);
9889application.register("prefecture", prefecture_controller_default);
9890application.register("star-rating", star_rating_controller_default);
9891application.register("submit-guard", submit_guard_controller_default);
9892
9893// app/javascript/pikaday.js
9894var import_pikaday = __toESM(require_pikaday());
9895function initializePikadayFields() {
9896  const dateInput = document.querySelector(".pikaday");
9897  if (dateInput) {
9898    if (dateInput.pikaday) {
9899      dateInput.pikaday.destroy();
9900    }
9901    const picker = new import_pikaday.default({
9902      field: dateInput,
9903      format: "YYYY-MM-DD",
9904      i18n: {
9905        previousMonth: "\u524D\u6708",
9906        nextMonth: "\u6B21\u6708",
9907        months: ["1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"],
9908        weekdays: ["\u65E5\u66DC\u65E5", "\u6708\u66DC\u65E5", "\u706B\u66DC\u65E5", "\u6C34\u66DC\u65E5", "\u6728\u66DC\u65E5", "\u91D1\u66DC\u65E5", "\u571F\u66DC\u65E5"],
9909        weekdaysShort: ["\u65E5", "\u6708", "\u706B", "\u6C34", "\u6728", "\u91D1", "\u571F"]
9910      },
9911      yearRange: [1900, (/* @__PURE__ */ new Date()).getFullYear()],
9912      toString(date) {
9913        const day = date.getDate();
9914        const month = date.getMonth() + 1;
9915        const year = date.getFullYear();
9916        return `${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}`;
9917      }
9918    });
9919    dateInput.pikaday = picker;
9920  }
9921}
9922document.addEventListener("turbo:load", initializePikadayFields);
9923document.addEventListener("turbo:render", initializePikadayFields);
9924
9925// app/javascript/application.js
9926var Colorme = { getJapanPostalCode };
9927window.Colorme = Colorme;
9928window.addEventListener("turbo:load", () => {
9929  let s = document.createElement("script");
9930  s.src = "https://seal.atlas.globalsign.com/gss/one/seal?image=seal_115-57_ja.png";
9931  document.body.appendChild(s);
9932});
9933Turbo.StreamActions.redirect = function() {
9934  Turbo.visit(this.target);
9935};
9936/*! Bundled license information:
9937
9938pikaday/pikaday.js:
9939  (*!
9940   * Pikaday
9941   *
9942   * Copyright © 2014 David Bushell | BSD & MIT license | https://github.com/Pikaday/Pikaday
9943   *)
9944
9945@hotwired/turbo/dist/turbo.es2017-esm.js:
9946  (*!
9947  Turbo 8.0.10
9948  Copyright © 2024 37signals LLC
9949   *)
9950*/

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.