// src/router.ts import { cloneDeep as cloneDeep3, get as get3, set as set3 } from "lodash-es"; // src/config.ts import { get, has, set } from "lodash-es"; var Config = class { constructor(defaults) { this.config = {}; this.defaults = defaults; } extend(defaults) { if (defaults) { this.defaults = { ...this.defaults, ...defaults }; } return this; } replace(newConfig) { this.config = newConfig; } get(key) { return has(this.config, key) ? get(this.config, key) : get(this.defaults, key); } set(keyOrValues, value) { if (typeof keyOrValues === "string") { set(this.config, keyOrValues, value); } else { Object.entries(keyOrValues).forEach(([key, val]) => { set(this.config, key, val); }); } } }; var config = new Config({ form: { recentlySuccessfulDuration: 2e3, forceIndicesArrayFormatInFormData: true }, future: { preserveEqualProps: false, useDataInertiaHeadAttribute: false, useDialogForErrorModal: false, useScriptElementForInitialPage: false }, prefetch: { cacheFor: 3e4, hoverDelay: 75 } }); // src/debounce.ts function debounce(fn, delay) { let timeoutID; return function(...args) { clearTimeout(timeoutID); timeoutID = setTimeout(() => fn.apply(this, args), delay); }; } // src/events.ts function fireEvent(name, options) { return document.dispatchEvent(new CustomEvent(`inertia:${name}`, options)); } var fireBeforeEvent = (visit) => { return fireEvent("before", { cancelable: true, detail: { visit } }); }; var fireErrorEvent = (errors) => { return fireEvent("error", { detail: { errors } }); }; var fireExceptionEvent = (exception) => { return fireEvent("exception", { cancelable: true, detail: { exception } }); }; var fireFinishEvent = (visit) => { return fireEvent("finish", { detail: { visit } }); }; var fireInvalidEvent = (response) => { return fireEvent("invalid", { cancelable: true, detail: { response } }); }; var fireBeforeUpdateEvent = (page2) => { return fireEvent("beforeUpdate", { detail: { page: page2 } }); }; var fireNavigateEvent = (page2) => { return fireEvent("navigate", { detail: { page: page2 } }); }; var fireProgressEvent = (progress3) => { return fireEvent("progress", { detail: { progress: progress3 } }); }; var fireStartEvent = (visit) => { return fireEvent("start", { detail: { visit } }); }; var fireSuccessEvent = (page2) => { return fireEvent("success", { detail: { page: page2 } }); }; var firePrefetchedEvent = (response, visit) => { return fireEvent("prefetched", { detail: { fetchedAt: Date.now(), response: response.data, visit } }); }; var firePrefetchingEvent = (visit) => { return fireEvent("prefetching", { detail: { visit } }); }; var fireFlashEvent = (flash) => { return fireEvent("flash", { detail: { flash } }); }; // src/history.ts import { cloneDeep as cloneDeep2, isEqual } from "lodash-es"; // src/sessionStorage.ts var SessionStorage = class { static set(key, value) { if (typeof window !== "undefined") { window.sessionStorage.setItem(key, JSON.stringify(value)); } } static get(key) { if (typeof window !== "undefined") { return JSON.parse(window.sessionStorage.getItem(key) || "null"); } } static merge(key, value) { const existing = this.get(key); if (existing === null) { this.set(key, value); } else { this.set(key, { ...existing, ...value }); } } static remove(key) { if (typeof window !== "undefined") { window.sessionStorage.removeItem(key); } } static removeNested(key, nestedKey) { const existing = this.get(key); if (existing !== null) { delete existing[nestedKey]; this.set(key, existing); } } static exists(key) { try { return this.get(key) !== null; } catch (error) { return false; } } static clear() { if (typeof window !== "undefined") { window.sessionStorage.clear(); } } }; SessionStorage.locationVisitKey = "inertiaLocationVisit"; // src/encryption.ts var encryptHistory = async (data) => { if (typeof window === "undefined") { throw new Error("Unable to encrypt history"); } const iv = getIv(); const storedKey = await getKeyFromSessionStorage(); const key = await getOrCreateKey(storedKey); if (!key) { throw new Error("Unable to encrypt history"); } const encrypted = await encryptData(iv, key, data); return encrypted; }; var historySessionStorageKeys = { key: "historyKey", iv: "historyIv" }; var decryptHistory = async (data) => { const iv = getIv(); const storedKey = await getKeyFromSessionStorage(); if (!storedKey) { throw new Error("Unable to decrypt history"); } return await decryptData(iv, storedKey, data); }; var encryptData = async (iv, key, data) => { if (typeof window === "undefined") { throw new Error("Unable to encrypt history"); } if (typeof window.crypto.subtle === "undefined") { console.warn("Encryption is not supported in this environment. SSL is required."); return Promise.resolve(data); } const textEncoder = new TextEncoder(); const str = JSON.stringify(data); const encoded = new Uint8Array(str.length * 3); const result = textEncoder.encodeInto(str, encoded); return window.crypto.subtle.encrypt( { name: "AES-GCM", iv }, key, encoded.subarray(0, result.written) ); }; var decryptData = async (iv, key, data) => { if (typeof window.crypto.subtle === "undefined") { console.warn("Decryption is not supported in this environment. SSL is required."); return Promise.resolve(data); } const decrypted = await window.crypto.subtle.decrypt( { name: "AES-GCM", iv }, key, data ); return JSON.parse(new TextDecoder().decode(decrypted)); }; var getIv = () => { const ivString = SessionStorage.get(historySessionStorageKeys.iv); if (ivString) { return new Uint8Array(ivString); } const iv = window.crypto.getRandomValues(new Uint8Array(12)); SessionStorage.set(historySessionStorageKeys.iv, Array.from(iv)); return iv; }; var createKey = async () => { if (typeof window.crypto.subtle === "undefined") { console.warn("Encryption is not supported in this environment. SSL is required."); return Promise.resolve(null); } return window.crypto.subtle.generateKey( { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"] ); }; var saveKey = async (key) => { if (typeof window.crypto.subtle === "undefined") { console.warn("Encryption is not supported in this environment. SSL is required."); return Promise.resolve(); } const keyData = await window.crypto.subtle.exportKey("raw", key); SessionStorage.set(historySessionStorageKeys.key, Array.from(new Uint8Array(keyData))); }; var getOrCreateKey = async (key) => { if (key) { return key; } const newKey = await createKey(); if (!newKey) { return null; } await saveKey(newKey); return newKey; }; var getKeyFromSessionStorage = async () => { const stringKey = SessionStorage.get(historySessionStorageKeys.key); if (!stringKey) { return null; } const key = await window.crypto.subtle.importKey( "raw", new Uint8Array(stringKey), { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"] ); return key; }; // src/prefetched.ts import { cloneDeep } from "lodash-es"; // src/objectUtils.ts var objectsAreEqual = (obj1, obj2, excludeKeys) => { if (obj1 === obj2) { return true; } for (const key in obj1) { if (excludeKeys.includes(key)) { continue; } if (obj1[key] === obj2[key]) { continue; } if (!compareValues(obj1[key], obj2[key])) { return false; } } for (const key in obj2) { if (excludeKeys.includes(key)) { continue; } if (!(key in obj1)) { return false; } } return true; }; var compareValues = (value1, value2) => { switch (typeof value1) { case "object": return objectsAreEqual(value1, value2, []); case "function": return value1.toString() === value2.toString(); default: return value1 === value2; } }; // src/time.ts var conversionMap = { ms: 1, s: 1e3, m: 1e3 * 60, h: 1e3 * 60 * 60, d: 1e3 * 60 * 60 * 24 }; var timeToMs = (time) => { if (typeof time === "number") { return time; } for (const [unit, conversion] of Object.entries(conversionMap)) { if (time.endsWith(unit)) { return parseFloat(time) * conversion; } } return parseInt(time); }; // src/prefetched.ts var PrefetchedRequests = class { constructor() { this.cached = []; this.inFlightRequests = []; this.removalTimers = []; this.currentUseId = null; } add(params, sendFunc, { cacheFor, cacheTags }) { const inFlight = this.findInFlight(params); if (inFlight) { return Promise.resolve(); } const existing = this.findCached(params); if (!params.fresh && existing && existing.staleTimestamp > Date.now()) { return Promise.resolve(); } const [stale, prefetchExpiresIn] = this.extractStaleValues(cacheFor); const promise = new Promise((resolve, reject) => { sendFunc({ ...params, onCancel: () => { this.remove(params); params.onCancel(); reject(); }, onError: (error) => { this.remove(params); params.onError(error); reject(); }, onPrefetching(visitParams) { params.onPrefetching(visitParams); }, onPrefetched(response, visit) { params.onPrefetched(response, visit); }, onPrefetchResponse(response) { resolve(response); }, onPrefetchError(error) { prefetchedRequests.removeFromInFlight(params); reject(error); } }); }).then((response) => { this.remove(params); const pageResponse = response.getPageResponse(); page.mergeOncePropsIntoResponse(pageResponse); this.cached.push({ params: { ...params }, staleTimestamp: Date.now() + stale, expiresAt: Date.now() + prefetchExpiresIn, response: promise, singleUse: prefetchExpiresIn === 0, timestamp: Date.now(), inFlight: false, tags: Array.isArray(cacheTags) ? cacheTags : [cacheTags] }); const oncePropExpiresIn = this.getShortestOncePropTtl(pageResponse); this.scheduleForRemoval( params, oncePropExpiresIn ? Math.min(prefetchExpiresIn, oncePropExpiresIn) : prefetchExpiresIn ); this.removeFromInFlight(params); response.handlePrefetch(); return response; }); this.inFlightRequests.push({ params: { ...params }, response: promise, staleTimestamp: null, inFlight: true }); return promise; } removeAll() { this.cached = []; this.removalTimers.forEach((removalTimer) => { clearTimeout(removalTimer.timer); }); this.removalTimers = []; } removeByTags(tags) { this.cached = this.cached.filter((prefetched) => { return !prefetched.tags.some((tag) => tags.includes(tag)); }); } remove(params) { this.cached = this.cached.filter((prefetched) => { return !this.paramsAreEqual(prefetched.params, params); }); this.clearTimer(params); } removeFromInFlight(params) { this.inFlightRequests = this.inFlightRequests.filter((prefetching) => { return !this.paramsAreEqual(prefetching.params, params); }); } extractStaleValues(cacheFor) { const [stale, expires] = this.cacheForToStaleAndExpires(cacheFor); return [timeToMs(stale), timeToMs(expires)]; } cacheForToStaleAndExpires(cacheFor) { if (!Array.isArray(cacheFor)) { return [cacheFor, cacheFor]; } switch (cacheFor.length) { case 0: return [0, 0]; case 1: return [cacheFor[0], cacheFor[0]]; default: return [cacheFor[0], cacheFor[1]]; } } clearTimer(params) { const timer = this.removalTimers.find((removalTimer) => { return this.paramsAreEqual(removalTimer.params, params); }); if (timer) { clearTimeout(timer.timer); this.removalTimers = this.removalTimers.filter((removalTimer) => removalTimer !== timer); } } scheduleForRemoval(params, expiresIn) { if (typeof window === "undefined") { return; } this.clearTimer(params); if (expiresIn > 0) { const timer = window.setTimeout(() => this.remove(params), expiresIn); this.removalTimers.push({ params, timer }); } } get(params) { return this.findCached(params) || this.findInFlight(params); } use(prefetched, params) { const id = `${params.url.pathname}-${Date.now()}-${Math.random().toString(36).substring(7)}`; this.currentUseId = id; return prefetched.response.then((response) => { if (this.currentUseId !== id) { return; } response.mergeParams({ ...params, onPrefetched: () => { } }); this.removeSingleUseItems(params); return response.handle(); }); } removeSingleUseItems(params) { this.cached = this.cached.filter((prefetched) => { if (!this.paramsAreEqual(prefetched.params, params)) { return true; } return !prefetched.singleUse; }); } findCached(params) { return this.cached.find((prefetched) => { return this.paramsAreEqual(prefetched.params, params); }) || null; } findInFlight(params) { return this.inFlightRequests.find((prefetched) => { return this.paramsAreEqual(prefetched.params, params); }) || null; } withoutPurposePrefetchHeader(params) { const newParams = cloneDeep(params); if (newParams.headers["Purpose"] === "prefetch") { delete newParams.headers["Purpose"]; } return newParams; } paramsAreEqual(params1, params2) { return objectsAreEqual( this.withoutPurposePrefetchHeader(params1), this.withoutPurposePrefetchHeader(params2), [ "showProgress", "replace", "prefetch", "preserveScroll", "preserveState", "onBefore", "onBeforeUpdate", "onStart", "onProgress", "onFinish", "onCancel", "onSuccess", "onError", "onFlash", "onPrefetched", "onCancelToken", "onPrefetching", "async", "viewTransition" ] ); } updateCachedOncePropsFromCurrentPage() { this.cached.forEach((prefetched) => { prefetched.response.then((response) => { const pageResponse = response.getPageResponse(); page.mergeOncePropsIntoResponse(pageResponse, { force: true }); for (const [group, deferredProps] of Object.entries(pageResponse.deferredProps ?? {})) { const remaining = deferredProps.filter((prop) => pageResponse.props[prop] === void 0); if (remaining.length > 0) { pageResponse.deferredProps[group] = remaining; } else { delete pageResponse.deferredProps[group]; } } const oncePropExpiresIn = this.getShortestOncePropTtl(pageResponse); if (oncePropExpiresIn === null) { return; } const prefetchExpiresIn = prefetched.expiresAt - Date.now(); const expiresIn = Math.min(prefetchExpiresIn, oncePropExpiresIn); if (expiresIn > 0) { this.scheduleForRemoval(prefetched.params, expiresIn); } else { this.remove(prefetched.params); } }); }); } getShortestOncePropTtl(page2) { const expiryTimestamps = Object.values(page2.onceProps ?? {}).map((onceProp) => onceProp.expiresAt).filter((expiresAt) => !!expiresAt); if (expiryTimestamps.length === 0) { return null; } return Math.min(...expiryTimestamps) - Date.now(); } }; var prefetchedRequests = new PrefetchedRequests(); // src/domUtils.ts var elementInViewport = (el) => { if (el.offsetParent === null) { return false; } const rect = el.getBoundingClientRect(); const verticallyVisible = rect.top < window.innerHeight && rect.bottom >= 0; const horizontallyVisible = rect.left < window.innerWidth && rect.right >= 0; return verticallyVisible && horizontallyVisible; }; var getScrollableParent = (element) => { const allowsVerticalScroll = (el) => { const computedStyle = window.getComputedStyle(el); if (["scroll", "overlay"].includes(computedStyle.overflowY)) { return true; } if (computedStyle.overflowY !== "auto") { return false; } if (["visible", "clip"].includes(computedStyle.overflowX)) { return true; } return hasDimensionConstraint(computedStyle.maxHeight, el.style.height); }; const allowsHorizontalScroll = (el) => { const computedStyle = window.getComputedStyle(el); if (["scroll", "overlay"].includes(computedStyle.overflowX)) { return true; } if (computedStyle.overflowX !== "auto") { return false; } if (["visible", "clip"].includes(computedStyle.overflowY)) { return true; } return hasDimensionConstraint(computedStyle.maxWidth, el.style.width); }; const hasDimensionConstraint = (computedMaxDimension, inlineStyleDimension) => { if (computedMaxDimension && computedMaxDimension !== "none" && computedMaxDimension !== "0px") { return true; } if (inlineStyleDimension && inlineStyleDimension !== "auto" && inlineStyleDimension !== "0") { return true; } return false; }; let parent = element?.parentElement; while (parent) { const allowsScroll = allowsVerticalScroll(parent) || allowsHorizontalScroll(parent); if (window.getComputedStyle(parent).display !== "contents" && allowsScroll) { return parent; } parent = parent.parentElement; } return null; }; var getElementsInViewportFromCollection = (elements, referenceElement) => { if (!referenceElement) { return elements.filter((element) => elementInViewport(element)); } const referenceIndex = elements.indexOf(referenceElement); const upwardElements = []; const downwardElements = []; for (let i = referenceIndex; i >= 0; i--) { const element = elements[i]; if (elementInViewport(element)) { upwardElements.push(element); } else { break; } } for (let i = referenceIndex + 1; i < elements.length; i++) { const element = elements[i]; if (elementInViewport(element)) { downwardElements.push(element); } else { break; } } return [...upwardElements.reverse(), ...downwardElements]; }; var requestAnimationFrame = (cb, times = 1) => { window.requestAnimationFrame(() => { if (times > 1) { requestAnimationFrame(cb, times - 1); } else { cb(); } }); }; var getInitialPageFromDOM = (id, useScriptElement = false) => { if (typeof window === "undefined") { return null; } if (!useScriptElement) { const el = document.getElementById(id); if (el?.dataset.page) { return JSON.parse(el.dataset.page); } } const scriptEl = document.querySelector(`script[data-page="${id}"][type="application/json"]`); if (scriptEl?.textContent) { return JSON.parse(scriptEl.textContent); } return null; }; // src/scroll.ts var isServer = typeof window === "undefined"; var isFirefox = !isServer && /Firefox/i.test(window.navigator.userAgent); var Scroll = class { static save() { history.saveScrollPositions(this.getScrollRegions()); } static getScrollRegions() { return Array.from(this.regions()).map((region) => ({ top: region.scrollTop, left: region.scrollLeft })); } static regions() { return document.querySelectorAll("[scroll-region]"); } static scrollToTop() { if (isFirefox && getComputedStyle(document.documentElement).scrollBehavior === "smooth") { return requestAnimationFrame(() => window.scrollTo(0, 0), 2); } window.scrollTo(0, 0); } static reset() { const anchorHash = isServer ? null : window.location.hash; if (!anchorHash) { this.scrollToTop(); } this.regions().forEach((region) => { if (typeof region.scrollTo === "function") { region.scrollTo(0, 0); } else { region.scrollTop = 0; region.scrollLeft = 0; } }); this.save(); this.scrollToAnchor(); } static scrollToAnchor() { const anchorHash = isServer ? null : window.location.hash; if (anchorHash) { setTimeout(() => { const anchorElement = document.getElementById(anchorHash.slice(1)); anchorElement ? anchorElement.scrollIntoView() : this.scrollToTop(); }); } } static restore(scrollRegions) { if (isServer) { return; } window.requestAnimationFrame(() => { this.restoreDocument(); this.restoreScrollRegions(scrollRegions); }); } static restoreScrollRegions(scrollRegions) { if (isServer) { return; } this.regions().forEach((region, index) => { const scrollPosition = scrollRegions[index]; if (!scrollPosition) { return; } if (typeof region.scrollTo === "function") { region.scrollTo(scrollPosition.left, scrollPosition.top); } else { region.scrollTop = scrollPosition.top; region.scrollLeft = scrollPosition.left; } }); } static restoreDocument() { const scrollPosition = history.getDocumentScrollPosition(); window.scrollTo(scrollPosition.left, scrollPosition.top); } static onScroll(event) { const target = event.target; if (typeof target.hasAttribute === "function" && target.hasAttribute("scroll-region")) { this.save(); } } static onWindowScroll() { history.saveDocumentScrollPosition({ top: window.scrollY, left: window.scrollX }); } }; // src/url.ts import * as qs from "qs"; // src/files.ts var isFile = (value) => typeof File !== "undefined" && value instanceof File || value instanceof Blob || typeof FileList !== "undefined" && value instanceof FileList && value.length > 0; function hasFiles(data) { return isFile(data) || data instanceof FormData && Array.from(data.values()).some((value) => hasFiles(value)) || typeof data === "object" && data !== null && Object.values(data).some((value) => hasFiles(value)); } // src/formData.ts var isFormData = (value) => value instanceof FormData; function objectToFormData(source, form = new FormData(), parentKey = null, queryStringArrayFormat = "brackets") { source = source || {}; for (const key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { append(form, composeKey(parentKey, key, "indices"), source[key], queryStringArrayFormat); } } return form; } function composeKey(parent, key, format) { if (!parent) { return key; } return format === "brackets" ? `${parent}[]` : `${parent}[${key}]`; } function append(form, key, value, format) { if (Array.isArray(value)) { return Array.from(value.keys()).forEach( (index) => append(form, composeKey(key, index.toString(), format), value[index], format) ); } else if (value instanceof Date) { return form.append(key, value.toISOString()); } else if (value instanceof File) { return form.append(key, value, value.name); } else if (value instanceof Blob) { return form.append(key, value); } else if (typeof value === "boolean") { return form.append(key, value ? "1" : "0"); } else if (typeof value === "string") { return form.append(key, value); } else if (typeof value === "number") { return form.append(key, `${value}`); } else if (value === null || value === void 0) { return form.append(key, ""); } objectToFormData(value, form, key, format); } // src/url.ts function hrefToUrl(href) { return new URL(href.toString(), typeof window === "undefined" ? void 0 : window.location.toString()); } var transformUrlAndData = (href, data, method, forceFormData, queryStringArrayFormat) => { let url = typeof href === "string" ? hrefToUrl(href) : href; if ((hasFiles(data) || forceFormData) && !isFormData(data)) { if (config.get("form.forceIndicesArrayFormatInFormData")) { queryStringArrayFormat = "indices"; } data = objectToFormData(data, new FormData(), null, queryStringArrayFormat); } if (isFormData(data)) { return [url, data]; } const [_href, _data] = mergeDataIntoQueryString(method, url, data, queryStringArrayFormat); return [hrefToUrl(_href), _data]; }; function mergeDataIntoQueryString(method, href, data, qsArrayFormat = "brackets") { const hasDataForQueryString = method === "get" && !isFormData(data) && Object.keys(data).length > 0; const hasHost = urlHasProtocol(href.toString()); const hasAbsolutePath = hasHost || href.toString().startsWith("/") || href.toString() === ""; const hasRelativePath = !hasAbsolutePath && !href.toString().startsWith("#") && !href.toString().startsWith("?"); const hasRelativePathWithDotPrefix = /^[.]{1,2}([/]|$)/.test(href.toString()); const hasSearch = href.toString().includes("?") || hasDataForQueryString; const hasHash = href.toString().includes("#"); const url = new URL(href.toString(), typeof window === "undefined" ? "http://localhost" : window.location.toString()); if (hasDataForQueryString) { const hasIndices = /\[\d+\]/.test(decodeURIComponent(url.search)); const parseOptions = { ignoreQueryPrefix: true, allowSparse: true }; url.search = qs.stringify( { ...qs.parse(url.search, parseOptions), ...data }, { encodeValuesOnly: true, arrayFormat: hasIndices ? "indices" : qsArrayFormat } ); } return [ [ hasHost ? `${url.protocol}//${url.host}` : "", hasAbsolutePath ? url.pathname : "", hasRelativePath ? url.pathname.substring(hasRelativePathWithDotPrefix ? 0 : 1) : "", hasSearch ? url.search : "", hasHash ? url.hash : "" ].join(""), hasDataForQueryString ? {} : data ]; } function urlWithoutHash(url) { url = new URL(url.href); url.hash = ""; return url; } var setHashIfSameUrl = (originUrl, destinationUrl) => { if (originUrl.hash && !destinationUrl.hash && urlWithoutHash(originUrl).href === destinationUrl.href) { destinationUrl.hash = originUrl.hash; } }; var isSameUrlWithoutHash = (url1, url2) => { return urlWithoutHash(url1).href === urlWithoutHash(url2).href; }; var isSameUrlWithoutQueryOrHash = (url1, url2) => { return url1.origin === url2.origin && url1.pathname === url2.pathname; }; function isUrlMethodPair(href) { return href !== null && typeof href === "object" && href !== void 0 && "url" in href && "method" in href; } function urlHasProtocol(url) { return /^([a-z][a-z0-9+.-]*:)?\/\/[^/]/i.test(url); } function urlToString(url, absolute) { const urlObj = typeof url === "string" ? hrefToUrl(url) : url; return absolute ? `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}${urlObj.search}${urlObj.hash}` : `${urlObj.pathname}${urlObj.search}${urlObj.hash}`; } // src/page.ts var CurrentPage = class { constructor() { this.componentId = {}; this.listeners = []; this.isFirstPageLoad = true; this.cleared = false; this.pendingDeferredProps = null; this.historyQuotaExceeded = false; } init({ initialPage, swapComponent, resolveComponent, onFlash }) { this.page = { ...initialPage, flash: initialPage.flash ?? {} }; this.swapComponent = swapComponent; this.resolveComponent = resolveComponent; this.onFlashCallback = onFlash; eventHandler.on("historyQuotaExceeded", () => { this.historyQuotaExceeded = true; }); return this; } set(page2, { replace = false, preserveScroll = false, preserveState = false, viewTransition = false } = {}) { if (Object.keys(page2.deferredProps || {}).length) { this.pendingDeferredProps = { deferredProps: page2.deferredProps, component: page2.component, url: page2.url }; if (page2.initialDeferredProps === void 0) { page2.initialDeferredProps = page2.deferredProps; } } this.componentId = {}; const componentId = this.componentId; if (page2.clearHistory) { history.clear(); } return this.resolve(page2.component).then((component) => { if (componentId !== this.componentId) { return; } page2.rememberedState ?? (page2.rememberedState = {}); const isServer3 = typeof window === "undefined"; const location = !isServer3 ? window.location : new URL(page2.url); const scrollRegions = !isServer3 && preserveScroll ? Scroll.getScrollRegions() : []; replace = replace || isSameUrlWithoutHash(hrefToUrl(page2.url), location); const pageForHistory = { ...page2, flash: {} }; return new Promise( (resolve) => replace ? history.replaceState(pageForHistory, resolve) : history.pushState(pageForHistory, resolve) ).then(() => { const isNewComponent = !this.isTheSame(page2); if (!isNewComponent && Object.keys(page2.props.errors || {}).length > 0) { viewTransition = false; } this.page = page2; this.cleared = false; if (this.hasOnceProps()) { prefetchedRequests.updateCachedOncePropsFromCurrentPage(); } if (isNewComponent) { this.fireEventsFor("newComponent"); } if (this.isFirstPageLoad) { this.fireEventsFor("firstLoad"); } this.isFirstPageLoad = false; if (this.historyQuotaExceeded) { this.historyQuotaExceeded = false; return; } return this.swap({ component, page: page2, preserveState, viewTransition }).then(() => { if (preserveScroll) { window.requestAnimationFrame(() => Scroll.restoreScrollRegions(scrollRegions)); } else { Scroll.reset(); } if (this.pendingDeferredProps && this.pendingDeferredProps.component === page2.component && this.pendingDeferredProps.url === page2.url) { eventHandler.fireInternalEvent("loadDeferredProps", this.pendingDeferredProps.deferredProps); } this.pendingDeferredProps = null; if (!replace) { fireNavigateEvent(page2); } }); }); }); } setQuietly(page2, { preserveState = false } = {}) { return this.resolve(page2.component).then((component) => { this.page = page2; this.cleared = false; history.setCurrent(page2); return this.swap({ component, page: page2, preserveState, viewTransition: false }); }); } clear() { this.cleared = true; } isCleared() { return this.cleared; } get() { return this.page; } getWithoutFlashData() { return { ...this.page, flash: {} }; } hasOnceProps() { return Object.keys(this.page.onceProps ?? {}).length > 0; } merge(data) { this.page = { ...this.page, ...data }; } setFlash(flash) { this.page = { ...this.page, flash }; this.onFlashCallback?.(flash); } setUrlHash(hash) { if (!this.page.url.includes(hash)) { this.page.url += hash; } } remember(data) { this.page.rememberedState = data; } swap({ component, page: page2, preserveState, viewTransition }) { const doSwap = () => this.swapComponent({ component, page: page2, preserveState }); if (!viewTransition || !document?.startViewTransition) { return doSwap(); } const viewTransitionCallback = typeof viewTransition === "boolean" ? () => null : viewTransition; return new Promise((resolve) => { const transitionResult = document.startViewTransition(() => doSwap().then(resolve)); viewTransitionCallback(transitionResult); }); } resolve(component) { return Promise.resolve(this.resolveComponent(component)); } isTheSame(page2) { return this.page.component === page2.component; } on(event, callback) { this.listeners.push({ event, callback }); return () => { this.listeners = this.listeners.filter((listener) => listener.event !== event && listener.callback !== callback); }; } fireEventsFor(event) { this.listeners.filter((listener) => listener.event === event).forEach((listener) => listener.callback()); } mergeOncePropsIntoResponse(response, { force = false } = {}) { Object.entries(response.onceProps ?? {}).forEach(([key, onceProp]) => { const existingOnceProp = this.page.onceProps?.[key]; if (existingOnceProp === void 0) { return; } if (force || response.props[onceProp.prop] === void 0) { response.props[onceProp.prop] = this.page.props[existingOnceProp.prop]; response.onceProps[key].expiresAt = existingOnceProp.expiresAt; } }); } }; var page = new CurrentPage(); // src/queue.ts var Queue = class { constructor() { this.items = []; this.processingPromise = null; } add(item) { this.items.push(item); return this.process(); } process() { this.processingPromise ?? (this.processingPromise = this.processNext().finally(() => { this.processingPromise = null; })); return this.processingPromise; } processNext() { const next = this.items.shift(); if (next) { return Promise.resolve(next()).then(() => this.processNext()); } return Promise.resolve(); } }; // src/history.ts var isServer2 = typeof window === "undefined"; var queue = new Queue(); var isChromeIOS = !isServer2 && /CriOS/.test(window.navigator.userAgent); var History = class { constructor() { this.rememberedState = "rememberedState"; this.scrollRegions = "scrollRegions"; this.preserveUrl = false; this.current = {}; // We need initialState for `restore` this.initialState = null; } remember(data, key) { this.replaceState({ ...page.getWithoutFlashData(), rememberedState: { ...page.get()?.rememberedState ?? {}, [key]: data } }); } restore(key) { if (!isServer2) { return this.current[this.rememberedState]?.[key] !== void 0 ? this.current[this.rememberedState]?.[key] : this.initialState?.[this.rememberedState]?.[key]; } } pushState(page2, cb = null) { if (isServer2) { return; } if (this.preserveUrl) { cb && cb(); return; } this.current = page2; queue.add(() => { return this.getPageData(page2).then((data) => { const doPush = () => this.doPushState({ page: data }, page2.url).then(() => cb?.()); if (isChromeIOS) { return new Promise((resolve) => { setTimeout(() => doPush().then(resolve)); }); } return doPush(); }); }); } clonePageProps(page2) { try { structuredClone(page2.props); return page2; } catch { return { ...page2, props: cloneDeep2(page2.props) }; } } getPageData(page2) { const pageWithClonedProps = this.clonePageProps(page2); return new Promise((resolve) => { return page2.encryptHistory ? encryptHistory(pageWithClonedProps).then(resolve) : resolve(pageWithClonedProps); }); } processQueue() { return queue.process(); } decrypt(page2 = null) { if (isServer2) { return Promise.resolve(page2 ?? page.get()); } const pageData = page2 ?? window.history.state?.page; return this.decryptPageData(pageData).then((data) => { if (!data) { throw new Error("Unable to decrypt history"); } if (this.initialState === null) { this.initialState = data ?? void 0; } else { this.current = data ?? {}; } return data; }); } decryptPageData(pageData) { return pageData instanceof ArrayBuffer ? decryptHistory(pageData) : Promise.resolve(pageData); } saveScrollPositions(scrollRegions) { queue.add(() => { return Promise.resolve().then(() => { if (!window.history.state?.page) { return; } if (isEqual(this.getScrollRegions(), scrollRegions)) { return; } return this.doReplaceState({ page: window.history.state.page, scrollRegions }); }); }); } saveDocumentScrollPosition(scrollRegion) { queue.add(() => { return Promise.resolve().then(() => { if (!window.history.state?.page) { return; } if (isEqual(this.getDocumentScrollPosition(), scrollRegion)) { return; } return this.doReplaceState({ page: window.history.state.page, documentScrollPosition: scrollRegion }); }); }); } getScrollRegions() { return window.history.state?.scrollRegions || []; } getDocumentScrollPosition() { return window.history.state?.documentScrollPosition || { top: 0, left: 0 }; } replaceState(page2, cb = null) { if (isEqual(this.current, page2)) { cb && cb(); return; } page.merge(page2); if (isServer2) { return; } if (this.preserveUrl) { cb && cb(); return; } this.current = page2; queue.add(() => { return this.getPageData(page2).then((data) => { const doReplace = () => this.doReplaceState({ page: data }, page2.url).then(() => cb?.()); if (isChromeIOS) { return new Promise((resolve) => { setTimeout(() => doReplace().then(resolve)); }); } return doReplace(); }); }); } isHistoryThrottleError(error) { return error instanceof Error && error.name === "SecurityError" && (error.message.includes("history.pushState") || error.message.includes("history.replaceState")); } isQuotaExceededError(error) { return error instanceof Error && error.name === "QuotaExceededError"; } withThrottleProtection(cb) { return Promise.resolve().then(() => { try { return cb(); } catch (error) { if (!this.isHistoryThrottleError(error)) { throw error; } console.error(error.message); } }); } doReplaceState(data, url) { return this.withThrottleProtection(() => { window.history.replaceState( { ...data, scrollRegions: data.scrollRegions ?? window.history.state?.scrollRegions, documentScrollPosition: data.documentScrollPosition ?? window.history.state?.documentScrollPosition }, "", url ); }); } doPushState(data, url) { return this.withThrottleProtection(() => { try { window.history.pushState(data, "", url); } catch (error) { if (!this.isQuotaExceededError(error)) { throw error; } eventHandler.fireInternalEvent("historyQuotaExceeded", url); } }); } getState(key, defaultValue) { return this.current?.[key] ?? defaultValue; } deleteState(key) { if (this.current[key] !== void 0) { delete this.current[key]; this.replaceState(this.current); } } clearInitialState(key) { if (this.initialState && this.initialState[key] !== void 0) { delete this.initialState[key]; } } browserHasHistoryEntry() { return !isServer2 && !!window.history.state?.page; } clear() { SessionStorage.remove(historySessionStorageKeys.key); SessionStorage.remove(historySessionStorageKeys.iv); } setCurrent(page2) { this.current = page2; } isValidState(state) { return !!state.page; } getAllState() { return this.current; } }; if (typeof window !== "undefined" && window.history.scrollRestoration) { window.history.scrollRestoration = "manual"; } var history = new History(); // src/eventHandler.ts var EventHandler = class { constructor() { this.internalListeners = []; } init() { if (typeof window !== "undefined") { window.addEventListener("popstate", this.handlePopstateEvent.bind(this)); window.addEventListener("scroll", debounce(Scroll.onWindowScroll.bind(Scroll), 100), true); } if (typeof document !== "undefined") { document.addEventListener("scroll", debounce(Scroll.onScroll.bind(Scroll), 100), true); } } onGlobalEvent(type, callback) { const listener = ((event) => { const response = callback(event); if (event.cancelable && !event.defaultPrevented && response === false) { event.preventDefault(); } }); return this.registerListener(`inertia:${type}`, listener); } on(event, callback) { this.internalListeners.push({ event, listener: callback }); return () => { this.internalListeners = this.internalListeners.filter((listener) => listener.listener !== callback); }; } onMissingHistoryItem() { page.clear(); this.fireInternalEvent("missingHistoryItem"); } fireInternalEvent(event, ...args) { this.internalListeners.filter((listener) => listener.event === event).forEach((listener) => listener.listener(...args)); } registerListener(type, listener) { document.addEventListener(type, listener); return () => document.removeEventListener(type, listener); } handlePopstateEvent(event) { const state = event.state || null; if (state === null) { const url = hrefToUrl(page.get().url); url.hash = window.location.hash; history.replaceState({ ...page.getWithoutFlashData(), url: url.href }); Scroll.reset(); return; } if (!history.isValidState(state)) { return this.onMissingHistoryItem(); } history.decrypt(state.page).then((data) => { if (page.get().version !== data.version) { this.onMissingHistoryItem(); return; } router.cancelAll({ prefetch: false }); page.setQuietly(data, { preserveState: false }).then(() => { Scroll.restore(history.getScrollRegions()); fireNavigateEvent(page.get()); const pendingDeferred = {}; const pageProps = page.get().props; for (const [group, props] of Object.entries(data.initialDeferredProps ?? data.deferredProps ?? {})) { const missing = props.filter((prop) => pageProps[prop] === void 0); if (missing.length > 0) { pendingDeferred[group] = missing; } } if (Object.keys(pendingDeferred).length > 0) { this.fireInternalEvent("loadDeferredProps", pendingDeferred); } }); }).catch(() => { this.onMissingHistoryItem(); }); } }; var eventHandler = new EventHandler(); // src/navigationType.ts var NavigationType = class { constructor() { this.type = this.resolveType(); } resolveType() { if (typeof window === "undefined") { return "navigate"; } if (window.performance && window.performance.getEntriesByType && window.performance.getEntriesByType("navigation").length > 0) { return window.performance.getEntriesByType("navigation")[0].type; } return "navigate"; } get() { return this.type; } isBackForward() { return this.type === "back_forward"; } isReload() { return this.type === "reload"; } }; var navigationType = new NavigationType(); // src/initialVisit.ts var InitialVisit = class { static handle() { this.clearRememberedStateOnReload(); const scenarios = [this.handleBackForward, this.handleLocation, this.handleDefault]; scenarios.find((handler) => handler.bind(this)()); } static clearRememberedStateOnReload() { if (navigationType.isReload()) { history.deleteState(history.rememberedState); history.clearInitialState(history.rememberedState); } } static handleBackForward() { if (!navigationType.isBackForward() || !history.browserHasHistoryEntry()) { return false; } const scrollRegions = history.getScrollRegions(); history.decrypt().then((data) => { page.set(data, { preserveScroll: true, preserveState: true }).then(() => { Scroll.restore(scrollRegions); fireNavigateEvent(page.get()); }); }).catch(() => { eventHandler.onMissingHistoryItem(); }); return true; } /** * @link https://inertiajs.com/redirects#external-redirects */ static handleLocation() { if (!SessionStorage.exists(SessionStorage.locationVisitKey)) { return false; } const locationVisit = SessionStorage.get(SessionStorage.locationVisitKey) || {}; SessionStorage.remove(SessionStorage.locationVisitKey); if (typeof window !== "undefined") { page.setUrlHash(window.location.hash); } history.decrypt(page.get()).then(() => { const rememberedState = history.getState(history.rememberedState, {}); const scrollRegions = history.getScrollRegions(); page.remember(rememberedState); page.set(page.get(), { preserveScroll: locationVisit.preserveScroll, preserveState: true }).then(() => { if (locationVisit.preserveScroll) { Scroll.restore(scrollRegions); } fireNavigateEvent(page.get()); }); }).catch(() => { eventHandler.onMissingHistoryItem(); }); return true; } static handleDefault() { if (typeof window !== "undefined") { page.setUrlHash(window.location.hash); } page.set(page.get(), { preserveScroll: true, preserveState: true }).then(() => { if (navigationType.isReload()) { Scroll.restore(history.getScrollRegions()); } else { Scroll.scrollToAnchor(); } const page2 = page.get(); fireNavigateEvent(page2); const flash = page2.flash; if (Object.keys(flash).length > 0) { queueMicrotask(() => fireFlashEvent(flash)); } }); } }; // src/poll.ts var Poll = class { constructor(interval, cb, options) { this.id = null; this.throttle = false; this.keepAlive = false; this.cbCount = 0; this.keepAlive = options.keepAlive ?? false; this.cb = cb; this.interval = interval; if (options.autoStart ?? true) { this.start(); } } stop() { if (this.id) { clearInterval(this.id); } } start() { if (typeof window === "undefined") { return; } this.stop(); this.id = window.setInterval(() => { if (!this.throttle || this.cbCount % 10 === 0) { this.cb(); } if (this.throttle) { this.cbCount++; } }, this.interval); } isInBackground(hidden) { this.throttle = this.keepAlive ? false : hidden; if (this.throttle) { this.cbCount = 0; } } }; // src/polls.ts var Polls = class { constructor() { this.polls = []; this.setupVisibilityListener(); } add(interval, cb, options) { const poll = new Poll(interval, cb, options); this.polls.push(poll); return { stop: () => poll.stop(), start: () => poll.start() }; } clear() { this.polls.forEach((poll) => poll.stop()); this.polls = []; } setupVisibilityListener() { if (typeof document === "undefined") { return; } document.addEventListener( "visibilitychange", () => { this.polls.forEach((poll) => poll.isInBackground(document.hidden)); }, false ); } }; var polls = new Polls(); // src/request.ts import { default as axios } from "axios"; // src/requestParams.ts var RequestParams = class _RequestParams { constructor(params) { this.callbacks = []; if (!params.prefetch) { this.params = params; } else { const wrappedCallbacks = { onBefore: this.wrapCallback(params, "onBefore"), onBeforeUpdate: this.wrapCallback(params, "onBeforeUpdate"), onStart: this.wrapCallback(params, "onStart"), onProgress: this.wrapCallback(params, "onProgress"), onFinish: this.wrapCallback(params, "onFinish"), onCancel: this.wrapCallback(params, "onCancel"), onSuccess: this.wrapCallback(params, "onSuccess"), onError: this.wrapCallback(params, "onError"), onFlash: this.wrapCallback(params, "onFlash"), onCancelToken: this.wrapCallback(params, "onCancelToken"), onPrefetched: this.wrapCallback(params, "onPrefetched"), onPrefetching: this.wrapCallback(params, "onPrefetching") }; this.params = { ...params, ...wrappedCallbacks, onPrefetchResponse: params.onPrefetchResponse || (() => { }), onPrefetchError: params.onPrefetchError || (() => { }) }; } } static create(params) { return new _RequestParams(params); } data() { return this.params.method === "get" ? null : this.params.data; } queryParams() { return this.params.method === "get" ? this.params.data : {}; } isPartial() { return this.params.only.length > 0 || this.params.except.length > 0 || this.params.reset.length > 0; } isPrefetch() { return this.params.prefetch === true; } isDeferredPropsRequest() { return this.params.deferredProps === true; } onCancelToken(cb) { this.params.onCancelToken({ cancel: cb }); } markAsFinished() { this.params.completed = true; this.params.cancelled = false; this.params.interrupted = false; } markAsCancelled({ cancelled = true, interrupted = false }) { this.params.onCancel(); this.params.completed = false; this.params.cancelled = cancelled; this.params.interrupted = interrupted; } wasCancelledAtAll() { return this.params.cancelled || this.params.interrupted; } onFinish() { this.params.onFinish(this.params); } onStart() { this.params.onStart(this.params); } onPrefetching() { this.params.onPrefetching(this.params); } onPrefetchResponse(response) { if (this.params.onPrefetchResponse) { this.params.onPrefetchResponse(response); } } onPrefetchError(error) { if (this.params.onPrefetchError) { this.params.onPrefetchError(error); } } all() { return this.params; } headers() { const headers = { ...this.params.headers }; if (this.isPartial()) { headers["X-Inertia-Partial-Component"] = page.get().component; } const only = this.params.only.concat(this.params.reset); if (only.length > 0) { headers["X-Inertia-Partial-Data"] = only.join(","); } if (this.params.except.length > 0) { headers["X-Inertia-Partial-Except"] = this.params.except.join(","); } if (this.params.reset.length > 0) { headers["X-Inertia-Reset"] = this.params.reset.join(","); } if (this.params.errorBag && this.params.errorBag.length > 0) { headers["X-Inertia-Error-Bag"] = this.params.errorBag; } return headers; } setPreserveOptions(page2) { this.params.preserveScroll = _RequestParams.resolvePreserveOption(this.params.preserveScroll, page2); this.params.preserveState = _RequestParams.resolvePreserveOption(this.params.preserveState, page2); } runCallbacks() { this.callbacks.forEach(({ name, args }) => { this.params[name](...args); }); } merge(toMerge) { this.params = { ...this.params, ...toMerge }; } wrapCallback(params, name) { return (...args) => { this.recordCallback(name, args); params[name](...args); }; } recordCallback(name, args) { this.callbacks.push({ name, args }); } static resolvePreserveOption(value, page2) { if (typeof value === "function") { return value(page2); } if (value === "errors") { return Object.keys(page2.props.errors || {}).length > 0; } return value; } }; // src/response.ts import { get as get2, isEqual as isEqual2, set as set2 } from "lodash-es"; // src/modal.ts var modal_default = { modal: null, listener: null, createIframeAndPage(html) { if (typeof html === "object") { html = `All Inertia requests must receive a valid Inertia response, however a plain JSON response was received.