home to your local SPACEGIRL 💫 arimelody.space
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

gooby htmx

Signed-off-by: ari melody <ari@arimelody.me>

-4211
-141
public/script/lib/htmx-head-support.js
··· 1 - //========================================================== 2 - // head-support.js 3 - // 4 - // An extension to htmx 1.0 to add head tag merging. 5 - //========================================================== 6 - (function(){ 7 - 8 - var api = null; 9 - 10 - function log() { 11 - //console.log(arguments); 12 - } 13 - 14 - function mergeHead(newContent, defaultMergeStrategy) { 15 - 16 - if (newContent && newContent.indexOf('<head') > -1) { 17 - const htmlDoc = document.createElement("html"); 18 - // remove svgs to avoid conflicts 19 - var contentWithSvgsRemoved = newContent.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim, ''); 20 - // extract head tag 21 - var headTag = contentWithSvgsRemoved.match(/(<head(\s[^>]*>|>)([\s\S]*?)<\/head>)/im); 22 - 23 - // if the head tag exists... 24 - if (headTag) { 25 - 26 - var added = [] 27 - var removed = [] 28 - var preserved = [] 29 - var nodesToAppend = [] 30 - 31 - htmlDoc.innerHTML = headTag; 32 - var newHeadTag = htmlDoc.querySelector("head"); 33 - var currentHead = document.head; 34 - 35 - if (newHeadTag == null) { 36 - return; 37 - } else { 38 - // put all new head elements into a Map, by their outerHTML 39 - var srcToNewHeadNodes = new Map(); 40 - for (const newHeadChild of newHeadTag.children) { 41 - srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild); 42 - } 43 - } 44 - 45 - 46 - 47 - // determine merge strategy 48 - var mergeStrategy = api.getAttributeValue(newHeadTag, "hx-head") || defaultMergeStrategy; 49 - 50 - // get the current head 51 - for (const currentHeadElt of currentHead.children) { 52 - 53 - // If the current head element is in the map 54 - var inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML); 55 - var isReAppended = currentHeadElt.getAttribute("hx-head") === "re-eval"; 56 - var isPreserved = api.getAttributeValue(currentHeadElt, "hx-preserve") === "true"; 57 - if (inNewContent || isPreserved) { 58 - if (isReAppended) { 59 - // remove the current version and let the new version replace it and re-execute 60 - removed.push(currentHeadElt); 61 - } else { 62 - // this element already exists and should not be re-appended, so remove it from 63 - // the new content map, preserving it in the DOM 64 - srcToNewHeadNodes.delete(currentHeadElt.outerHTML); 65 - preserved.push(currentHeadElt); 66 - } 67 - } else { 68 - if (mergeStrategy === "append") { 69 - // we are appending and this existing element is not new content 70 - // so if and only if it is marked for re-append do we do anything 71 - if (isReAppended) { 72 - removed.push(currentHeadElt); 73 - nodesToAppend.push(currentHeadElt); 74 - } 75 - } else { 76 - // if this is a merge, we remove this content since it is not in the new head 77 - if (api.triggerEvent(document.body, "htmx:removingHeadElement", {headElement: currentHeadElt}) !== false) { 78 - removed.push(currentHeadElt); 79 - } 80 - } 81 - } 82 - } 83 - 84 - // Push the tremaining new head elements in the Map into the 85 - // nodes to append to the head tag 86 - nodesToAppend.push(...srcToNewHeadNodes.values()); 87 - log("to append: ", nodesToAppend); 88 - 89 - for (const newNode of nodesToAppend) { 90 - log("adding: ", newNode); 91 - var newElt = document.createRange().createContextualFragment(newNode.outerHTML); 92 - log(newElt); 93 - if (api.triggerEvent(document.body, "htmx:addingHeadElement", {headElement: newElt}) !== false) { 94 - currentHead.appendChild(newElt); 95 - added.push(newElt); 96 - } 97 - } 98 - 99 - // remove all removed elements, after we have appended the new elements to avoid 100 - // additional network requests for things like style sheets 101 - for (const removedElement of removed) { 102 - if (api.triggerEvent(document.body, "htmx:removingHeadElement", {headElement: removedElement}) !== false) { 103 - currentHead.removeChild(removedElement); 104 - } 105 - } 106 - 107 - api.triggerEvent(document.body, "htmx:afterHeadMerge", {added: added, kept: preserved, removed: removed}); 108 - } 109 - } 110 - } 111 - 112 - htmx.defineExtension("head-support", { 113 - init: function(apiRef) { 114 - // store a reference to the internal API. 115 - api = apiRef; 116 - 117 - htmx.on('htmx:afterSwap', function(evt){ 118 - var serverResponse = evt.detail.xhr.response; 119 - if (api.triggerEvent(document.body, "htmx:beforeHeadMerge", evt.detail)) { 120 - mergeHead(serverResponse, evt.detail.boosted ? "merge" : "append"); 121 - } 122 - }) 123 - 124 - htmx.on('htmx:historyRestore', function(evt){ 125 - if (api.triggerEvent(document.body, "htmx:beforeHeadMerge", evt.detail)) { 126 - if (evt.detail.cacheMiss) { 127 - mergeHead(evt.detail.serverResponse, "merge"); 128 - } else { 129 - mergeHead(evt.detail.item.head, "merge"); 130 - } 131 - } 132 - }) 133 - 134 - htmx.on('htmx:historyItemCreated', function(evt){ 135 - var historyItem = evt.detail.item; 136 - historyItem.head = document.head.outerHTML; 137 - }) 138 - } 139 - }); 140 - 141 - })()
-147
public/script/lib/htmx-preload.js
··· 1 - // This adds the "preload" extension to htmx. By default, this will 2 - // preload the targets of any tags with `href` or `hx-get` attributes 3 - // if they also have a `preload` attribute as well. See documentation 4 - // for more details 5 - htmx.defineExtension("preload", { 6 - 7 - onEvent: function(name, event) { 8 - 9 - // Only take actions on "htmx:afterProcessNode" 10 - if (name !== "htmx:afterProcessNode") { 11 - return; 12 - } 13 - 14 - // SOME HELPER FUNCTIONS WE'LL NEED ALONG THE WAY 15 - 16 - // attr gets the closest non-empty value from the attribute. 17 - var attr = function(node, property) { 18 - if (node == undefined) {return undefined;} 19 - return node.getAttribute(property) || node.getAttribute("data-" + property) || attr(node.parentElement, property) 20 - } 21 - 22 - // load handles the actual HTTP fetch, and uses htmx.ajax in cases where we're 23 - // preloading an htmx resource (this sends the same HTTP headers as a regular htmx request) 24 - var load = function(node) { 25 - 26 - // Called after a successful AJAX request, to mark the 27 - // content as loaded (and prevent additional AJAX calls.) 28 - var done = function(html) { 29 - if (!node.preloadAlways) { 30 - node.preloadState = "DONE" 31 - } 32 - 33 - if (attr(node, "preload-images") == "true") { 34 - document.createElement("div").innerHTML = html // create and populate a node to load linked resources, too. 35 - } 36 - } 37 - 38 - return function() { 39 - 40 - // If this value has already been loaded, then do not try again. 41 - if (node.preloadState !== "READY") { 42 - return; 43 - } 44 - 45 - // Special handling for HX-GET - use built-in htmx.ajax function 46 - // so that headers match other htmx requests, then set 47 - // node.preloadState = TRUE so that requests are not duplicated 48 - // in the future 49 - var hxGet = node.getAttribute("hx-get") || node.getAttribute("data-hx-get") 50 - if (hxGet) { 51 - htmx.ajax("GET", hxGet, { 52 - source: node, 53 - handler:function(elt, info) { 54 - done(info.xhr.responseText); 55 - } 56 - }); 57 - return; 58 - } 59 - 60 - // Otherwise, perform a standard xhr request, then set 61 - // node.preloadState = TRUE so that requests are not duplicated 62 - // in the future. 63 - if (node.getAttribute("href")) { 64 - var r = new XMLHttpRequest(); 65 - r.open("GET", node.getAttribute("href")); 66 - r.onload = function() {done(r.responseText);}; 67 - r.send(); 68 - return; 69 - } 70 - } 71 - } 72 - 73 - // This function processes a specific node and sets up event handlers. 74 - // We'll search for nodes and use it below. 75 - var init = function(node) { 76 - 77 - // If this node DOES NOT include a "GET" transaction, then there's nothing to do here. 78 - if (node.getAttribute("href") + node.getAttribute("hx-get") + node.getAttribute("data-hx-get") == "") { 79 - return; 80 - } 81 - 82 - // Guarantee that we only initialize each node once. 83 - if (node.preloadState !== undefined) { 84 - return; 85 - } 86 - 87 - // Get event name from config. 88 - var on = attr(node, "preload") || "mousedown" 89 - const always = on.indexOf("always") !== -1 90 - if (always) { 91 - on = on.replace('always', '').trim() 92 - } 93 - 94 - // FALL THROUGH to here means we need to add an EventListener 95 - 96 - // Apply the listener to the node 97 - node.addEventListener(on, function(evt) { 98 - if (node.preloadState === "PAUSE") { // Only add one event listener 99 - node.preloadState = "READY"; // Required for the `load` function to trigger 100 - 101 - // Special handling for "mouseover" events. Wait 100ms before triggering load. 102 - if (on === "mouseover") { 103 - window.setTimeout(load(node), 100); 104 - } else { 105 - load(node)() // all other events trigger immediately. 106 - } 107 - } 108 - }) 109 - 110 - // Special handling for certain built-in event handlers 111 - switch (on) { 112 - 113 - case "mouseover": 114 - // Mirror `touchstart` events (fires immediately) 115 - node.addEventListener("touchstart", load(node)); 116 - 117 - // WHhen the mouse leaves, immediately disable the preload 118 - node.addEventListener("mouseout", function(evt) { 119 - if ((evt.target === node) && (node.preloadState === "READY")) { 120 - node.preloadState = "PAUSE"; 121 - } 122 - }) 123 - break; 124 - 125 - case "mousedown": 126 - // Mirror `touchstart` events (fires immediately) 127 - node.addEventListener("touchstart", load(node)); 128 - break; 129 - } 130 - 131 - // Mark the node as ready to run. 132 - node.preloadState = "PAUSE"; 133 - node.preloadAlways = always; 134 - htmx.trigger(node, "preload:init") // This event can be used to load content immediately. 135 - } 136 - 137 - // Search for all child nodes that have a "preload" attribute 138 - event.target.querySelectorAll("[preload]").forEach(function(node) { 139 - 140 - // Initialize the node with the "preload" attribute 141 - init(node) 142 - 143 - // Initialize all child elements that are anchors or have `hx-get` (use with care) 144 - node.querySelectorAll("a,[hx-get],[data-hx-get]").forEach(init) 145 - }) 146 - } 147 - })
-3922
public/script/lib/htmx.js
··· 1 - // UMD insanity 2 - // This code sets up support for (in order) AMD, ES6 modules, and globals. 3 - (function (root, factory) { 4 - //@ts-ignore 5 - if (typeof define === 'function' && define.amd) { 6 - // AMD. Register as an anonymous module. 7 - //@ts-ignore 8 - define([], factory); 9 - } else if (typeof module === 'object' && module.exports) { 10 - // Node. Does not work with strict CommonJS, but 11 - // only CommonJS-like environments that support module.exports, 12 - // like Node. 13 - module.exports = factory(); 14 - } else { 15 - // Browser globals 16 - root.htmx = root.htmx || factory(); 17 - } 18 - }(typeof self !== 'undefined' ? self : this, function () { 19 - return (function () { 20 - 'use strict'; 21 - 22 - // Public API 23 - //** @type {import("./htmx").HtmxApi} */ 24 - // TODO: list all methods in public API 25 - var htmx = { 26 - onLoad: onLoadHelper, 27 - process: processNode, 28 - on: addEventListenerImpl, 29 - off: removeEventListenerImpl, 30 - trigger : triggerEvent, 31 - ajax : ajaxHelper, 32 - find : find, 33 - findAll : findAll, 34 - closest : closest, 35 - values : function(elt, type){ 36 - var inputValues = getInputValues(elt, type || "post"); 37 - return inputValues.values; 38 - }, 39 - remove : removeElement, 40 - addClass : addClassToElement, 41 - removeClass : removeClassFromElement, 42 - toggleClass : toggleClassOnElement, 43 - takeClass : takeClassForElement, 44 - defineExtension : defineExtension, 45 - removeExtension : removeExtension, 46 - logAll : logAll, 47 - logNone : logNone, 48 - logger : null, 49 - config : { 50 - historyEnabled:true, 51 - historyCacheSize:10, 52 - refreshOnHistoryMiss:false, 53 - defaultSwapStyle:'innerHTML', 54 - defaultSwapDelay:0, 55 - defaultSettleDelay:20, 56 - includeIndicatorStyles:true, 57 - indicatorClass:'htmx-indicator', 58 - requestClass:'htmx-request', 59 - addedClass:'htmx-added', 60 - settlingClass:'htmx-settling', 61 - swappingClass:'htmx-swapping', 62 - allowEval:true, 63 - allowScriptTags:true, 64 - inlineScriptNonce:'', 65 - attributesToSettle:["class", "style", "width", "height"], 66 - withCredentials:false, 67 - timeout:0, 68 - wsReconnectDelay: 'full-jitter', 69 - wsBinaryType: 'blob', 70 - disableSelector: "[hx-disable], [data-hx-disable]", 71 - useTemplateFragments: false, 72 - scrollBehavior: 'smooth', 73 - defaultFocusScroll: false, 74 - getCacheBusterParam: false, 75 - globalViewTransitions: false, 76 - methodsThatUseUrlParams: ["get"], 77 - selfRequestsOnly: false, 78 - ignoreTitle: false, 79 - scrollIntoViewOnBoost: true, 80 - triggerSpecsCache: null, 81 - }, 82 - parseInterval:parseInterval, 83 - _:internalEval, 84 - createEventSource: function(url){ 85 - return new EventSource(url, {withCredentials:true}) 86 - }, 87 - createWebSocket: function(url){ 88 - var sock = new WebSocket(url, []); 89 - sock.binaryType = htmx.config.wsBinaryType; 90 - return sock; 91 - }, 92 - version: "1.9.11" 93 - }; 94 - 95 - /** @type {import("./htmx").HtmxInternalApi} */ 96 - var internalAPI = { 97 - addTriggerHandler: addTriggerHandler, 98 - bodyContains: bodyContains, 99 - canAccessLocalStorage: canAccessLocalStorage, 100 - findThisElement: findThisElement, 101 - filterValues: filterValues, 102 - hasAttribute: hasAttribute, 103 - getAttributeValue: getAttributeValue, 104 - getClosestAttributeValue: getClosestAttributeValue, 105 - getClosestMatch: getClosestMatch, 106 - getExpressionVars: getExpressionVars, 107 - getHeaders: getHeaders, 108 - getInputValues: getInputValues, 109 - getInternalData: getInternalData, 110 - getSwapSpecification: getSwapSpecification, 111 - getTriggerSpecs: getTriggerSpecs, 112 - getTarget: getTarget, 113 - makeFragment: makeFragment, 114 - mergeObjects: mergeObjects, 115 - makeSettleInfo: makeSettleInfo, 116 - oobSwap: oobSwap, 117 - querySelectorExt: querySelectorExt, 118 - selectAndSwap: selectAndSwap, 119 - settleImmediately: settleImmediately, 120 - shouldCancel: shouldCancel, 121 - triggerEvent: triggerEvent, 122 - triggerErrorEvent: triggerErrorEvent, 123 - withExtensions: withExtensions, 124 - } 125 - 126 - var VERBS = ['get', 'post', 'put', 'delete', 'patch']; 127 - var VERB_SELECTOR = VERBS.map(function(verb){ 128 - return "[hx-" + verb + "], [data-hx-" + verb + "]" 129 - }).join(", "); 130 - 131 - var HEAD_TAG_REGEX = makeTagRegEx('head'), 132 - TITLE_TAG_REGEX = makeTagRegEx('title'), 133 - SVG_TAGS_REGEX = makeTagRegEx('svg', true); 134 - 135 - //==================================================================== 136 - // Utilities 137 - //==================================================================== 138 - 139 - /** 140 - * @param {string} tag 141 - * @param {boolean} global 142 - * @returns {RegExp} 143 - */ 144 - function makeTagRegEx(tag, global = false) { 145 - return new RegExp(`<${tag}(\\s[^>]*>|>)([\\s\\S]*?)<\\/${tag}>`, 146 - global ? 'gim' : 'im'); 147 - } 148 - 149 - function parseInterval(str) { 150 - if (str == undefined) { 151 - return undefined; 152 - } 153 - 154 - let interval = NaN; 155 - if (str.slice(-2) == "ms") { 156 - interval = parseFloat(str.slice(0, -2)); 157 - } else if (str.slice(-1) == "s") { 158 - interval = parseFloat(str.slice(0, -1)) * 1000; 159 - } else if (str.slice(-1) == "m") { 160 - interval = parseFloat(str.slice(0, -1)) * 1000 * 60; 161 - } else { 162 - interval = parseFloat(str); 163 - } 164 - return isNaN(interval) ? undefined : interval; 165 - } 166 - 167 - /** 168 - * @param {HTMLElement} elt 169 - * @param {string} name 170 - * @returns {(string | null)} 171 - */ 172 - function getRawAttribute(elt, name) { 173 - return elt.getAttribute && elt.getAttribute(name); 174 - } 175 - 176 - // resolve with both hx and data-hx prefixes 177 - function hasAttribute(elt, qualifiedName) { 178 - return elt.hasAttribute && (elt.hasAttribute(qualifiedName) || 179 - elt.hasAttribute("data-" + qualifiedName)); 180 - } 181 - 182 - /** 183 - * 184 - * @param {HTMLElement} elt 185 - * @param {string} qualifiedName 186 - * @returns {(string | null)} 187 - */ 188 - function getAttributeValue(elt, qualifiedName) { 189 - return getRawAttribute(elt, qualifiedName) || getRawAttribute(elt, "data-" + qualifiedName); 190 - } 191 - 192 - /** 193 - * @param {HTMLElement} elt 194 - * @returns {HTMLElement | null} 195 - */ 196 - function parentElt(elt) { 197 - return elt.parentElement; 198 - } 199 - 200 - /** 201 - * @returns {Document} 202 - */ 203 - function getDocument() { 204 - return document; 205 - } 206 - 207 - /** 208 - * @param {HTMLElement} elt 209 - * @param {(e:HTMLElement) => boolean} condition 210 - * @returns {HTMLElement | null} 211 - */ 212 - function getClosestMatch(elt, condition) { 213 - while (elt && !condition(elt)) { 214 - elt = parentElt(elt); 215 - } 216 - 217 - return elt ? elt : null; 218 - } 219 - 220 - function getAttributeValueWithDisinheritance(initialElement, ancestor, attributeName){ 221 - var attributeValue = getAttributeValue(ancestor, attributeName); 222 - var disinherit = getAttributeValue(ancestor, "hx-disinherit"); 223 - if (initialElement !== ancestor && disinherit && (disinherit === "*" || disinherit.split(" ").indexOf(attributeName) >= 0)) { 224 - return "unset"; 225 - } else { 226 - return attributeValue 227 - } 228 - } 229 - 230 - /** 231 - * @param {HTMLElement} elt 232 - * @param {string} attributeName 233 - * @returns {string | null} 234 - */ 235 - function getClosestAttributeValue(elt, attributeName) { 236 - var closestAttr = null; 237 - getClosestMatch(elt, function (e) { 238 - return closestAttr = getAttributeValueWithDisinheritance(elt, e, attributeName); 239 - }); 240 - if (closestAttr !== "unset") { 241 - return closestAttr; 242 - } 243 - } 244 - 245 - /** 246 - * @param {HTMLElement} elt 247 - * @param {string} selector 248 - * @returns {boolean} 249 - */ 250 - function matches(elt, selector) { 251 - // @ts-ignore: non-standard properties for browser compatibility 252 - // noinspection JSUnresolvedVariable 253 - var matchesFunction = elt.matches || elt.matchesSelector || elt.msMatchesSelector || elt.mozMatchesSelector || elt.webkitMatchesSelector || elt.oMatchesSelector; 254 - return matchesFunction && matchesFunction.call(elt, selector); 255 - } 256 - 257 - /** 258 - * @param {string} str 259 - * @returns {string} 260 - */ 261 - function getStartTag(str) { 262 - var tagMatcher = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i 263 - var match = tagMatcher.exec( str ); 264 - if (match) { 265 - return match[1].toLowerCase(); 266 - } else { 267 - return ""; 268 - } 269 - } 270 - 271 - /** 272 - * 273 - * @param {string} resp 274 - * @param {number} depth 275 - * @returns {Element} 276 - */ 277 - function parseHTML(resp, depth) { 278 - var parser = new DOMParser(); 279 - var responseDoc = parser.parseFromString(resp, "text/html"); 280 - 281 - /** @type {Element} */ 282 - var responseNode = responseDoc.body; 283 - while (depth > 0) { 284 - depth--; 285 - // @ts-ignore 286 - responseNode = responseNode.firstChild; 287 - } 288 - if (responseNode == null) { 289 - // @ts-ignore 290 - responseNode = getDocument().createDocumentFragment(); 291 - } 292 - return responseNode; 293 - } 294 - 295 - function aFullPageResponse(resp) { 296 - return /<body/.test(resp) 297 - } 298 - 299 - /** 300 - * 301 - * @param {string} response 302 - * @returns {Element} 303 - */ 304 - function makeFragment(response) { 305 - var partialResponse = !aFullPageResponse(response); 306 - var startTag = getStartTag(response); 307 - var content = response; 308 - if (startTag === 'head') { 309 - content = content.replace(HEAD_TAG_REGEX, ''); 310 - } 311 - if (htmx.config.useTemplateFragments && partialResponse) { 312 - var fragment = parseHTML("<body><template>" + content + "</template></body>", 0); 313 - // @ts-ignore type mismatch between DocumentFragment and Element. 314 - // TODO: Are these close enough for htmx to use interchangeably? 315 - var fragmentContent = fragment.querySelector('template').content; 316 - if (htmx.config.allowScriptTags) { 317 - // if there is a nonce set up, set it on the new script tags 318 - forEach(fragmentContent.querySelectorAll("script"), function (script) { 319 - if (htmx.config.inlineScriptNonce) { 320 - script.nonce = htmx.config.inlineScriptNonce; 321 - } 322 - // mark as executed due to template insertion semantics on all browsers except firefox fml 323 - script.htmxExecuted = navigator.userAgent.indexOf("Firefox") === -1; 324 - }) 325 - } else { 326 - forEach(fragmentContent.querySelectorAll("script"), function (script) { 327 - // remove all script tags if scripts are disabled 328 - removeElement(script); 329 - }) 330 - } 331 - return fragmentContent; 332 - } 333 - switch (startTag) { 334 - case "thead": 335 - case "tbody": 336 - case "tfoot": 337 - case "colgroup": 338 - case "caption": 339 - return parseHTML("<table>" + content + "</table>", 1); 340 - case "col": 341 - return parseHTML("<table><colgroup>" + content + "</colgroup></table>", 2); 342 - case "tr": 343 - return parseHTML("<table><tbody>" + content + "</tbody></table>", 2); 344 - case "td": 345 - case "th": 346 - return parseHTML("<table><tbody><tr>" + content + "</tr></tbody></table>", 3); 347 - case "script": 348 - case "style": 349 - return parseHTML("<div>" + content + "</div>", 1); 350 - default: 351 - return parseHTML(content, 0); 352 - } 353 - } 354 - 355 - /** 356 - * @param {Function} func 357 - */ 358 - function maybeCall(func){ 359 - if(func) { 360 - func(); 361 - } 362 - } 363 - 364 - /** 365 - * @param {any} o 366 - * @param {string} type 367 - * @returns 368 - */ 369 - function isType(o, type) { 370 - return Object.prototype.toString.call(o) === "[object " + type + "]"; 371 - } 372 - 373 - /** 374 - * @param {*} o 375 - * @returns {o is Function} 376 - */ 377 - function isFunction(o) { 378 - return isType(o, "Function"); 379 - } 380 - 381 - /** 382 - * @param {*} o 383 - * @returns {o is Object} 384 - */ 385 - function isRawObject(o) { 386 - return isType(o, "Object"); 387 - } 388 - 389 - /** 390 - * getInternalData retrieves "private" data stored by htmx within an element 391 - * @param {HTMLElement} elt 392 - * @returns {*} 393 - */ 394 - function getInternalData(elt) { 395 - var dataProp = 'htmx-internal-data'; 396 - var data = elt[dataProp]; 397 - if (!data) { 398 - data = elt[dataProp] = {}; 399 - } 400 - return data; 401 - } 402 - 403 - /** 404 - * toArray converts an ArrayLike object into a real array. 405 - * @param {ArrayLike} arr 406 - * @returns {any[]} 407 - */ 408 - function toArray(arr) { 409 - var returnArr = []; 410 - if (arr) { 411 - for (var i = 0; i < arr.length; i++) { 412 - returnArr.push(arr[i]); 413 - } 414 - } 415 - return returnArr 416 - } 417 - 418 - function forEach(arr, func) { 419 - if (arr) { 420 - for (var i = 0; i < arr.length; i++) { 421 - func(arr[i]); 422 - } 423 - } 424 - } 425 - 426 - function isScrolledIntoView(el) { 427 - var rect = el.getBoundingClientRect(); 428 - var elemTop = rect.top; 429 - var elemBottom = rect.bottom; 430 - return elemTop < window.innerHeight && elemBottom >= 0; 431 - } 432 - 433 - function bodyContains(elt) { 434 - // IE Fix 435 - if (elt.getRootNode && elt.getRootNode() instanceof window.ShadowRoot) { 436 - return getDocument().body.contains(elt.getRootNode().host); 437 - } else { 438 - return getDocument().body.contains(elt); 439 - } 440 - } 441 - 442 - function splitOnWhitespace(trigger) { 443 - return trigger.trim().split(/\s+/); 444 - } 445 - 446 - /** 447 - * mergeObjects takes all of the keys from 448 - * obj2 and duplicates them into obj1 449 - * @param {Object} obj1 450 - * @param {Object} obj2 451 - * @returns {Object} 452 - */ 453 - function mergeObjects(obj1, obj2) { 454 - for (var key in obj2) { 455 - if (obj2.hasOwnProperty(key)) { 456 - obj1[key] = obj2[key]; 457 - } 458 - } 459 - return obj1; 460 - } 461 - 462 - function parseJSON(jString) { 463 - try { 464 - return JSON.parse(jString); 465 - } catch(error) { 466 - logError(error); 467 - return null; 468 - } 469 - } 470 - 471 - function canAccessLocalStorage() { 472 - var test = 'htmx:localStorageTest'; 473 - try { 474 - localStorage.setItem(test, test); 475 - localStorage.removeItem(test); 476 - return true; 477 - } catch(e) { 478 - return false; 479 - } 480 - } 481 - 482 - function normalizePath(path) { 483 - try { 484 - var url = new URL(path); 485 - if (url) { 486 - path = url.pathname + url.search; 487 - } 488 - // remove trailing slash, unless index page 489 - if (!(/^\/$/.test(path))) { 490 - path = path.replace(/\/+$/, ''); 491 - } 492 - return path; 493 - } catch (e) { 494 - // be kind to IE11, which doesn't support URL() 495 - return path; 496 - } 497 - } 498 - 499 - //========================================================================================== 500 - // public API 501 - //========================================================================================== 502 - 503 - function internalEval(str){ 504 - return maybeEval(getDocument().body, function () { 505 - return eval(str); 506 - }); 507 - } 508 - 509 - function onLoadHelper(callback) { 510 - var value = htmx.on("htmx:load", function(evt) { 511 - callback(evt.detail.elt); 512 - }); 513 - return value; 514 - } 515 - 516 - function logAll(){ 517 - htmx.logger = function(elt, event, data) { 518 - if(console) { 519 - console.log(event, elt, data); 520 - } 521 - } 522 - } 523 - 524 - function logNone() { 525 - htmx.logger = null 526 - } 527 - 528 - function find(eltOrSelector, selector) { 529 - if (selector) { 530 - return eltOrSelector.querySelector(selector); 531 - } else { 532 - return find(getDocument(), eltOrSelector); 533 - } 534 - } 535 - 536 - function findAll(eltOrSelector, selector) { 537 - if (selector) { 538 - return eltOrSelector.querySelectorAll(selector); 539 - } else { 540 - return findAll(getDocument(), eltOrSelector); 541 - } 542 - } 543 - 544 - function removeElement(elt, delay) { 545 - elt = resolveTarget(elt); 546 - if (delay) { 547 - setTimeout(function(){ 548 - removeElement(elt); 549 - elt = null; 550 - }, delay); 551 - } else { 552 - elt.parentElement.removeChild(elt); 553 - } 554 - } 555 - 556 - function addClassToElement(elt, clazz, delay) { 557 - elt = resolveTarget(elt); 558 - if (delay) { 559 - setTimeout(function(){ 560 - addClassToElement(elt, clazz); 561 - elt = null; 562 - }, delay); 563 - } else { 564 - elt.classList && elt.classList.add(clazz); 565 - } 566 - } 567 - 568 - function removeClassFromElement(elt, clazz, delay) { 569 - elt = resolveTarget(elt); 570 - if (delay) { 571 - setTimeout(function(){ 572 - removeClassFromElement(elt, clazz); 573 - elt = null; 574 - }, delay); 575 - } else { 576 - if (elt.classList) { 577 - elt.classList.remove(clazz); 578 - // if there are no classes left, remove the class attribute 579 - if (elt.classList.length === 0) { 580 - elt.removeAttribute("class"); 581 - } 582 - } 583 - } 584 - } 585 - 586 - function toggleClassOnElement(elt, clazz) { 587 - elt = resolveTarget(elt); 588 - elt.classList.toggle(clazz); 589 - } 590 - 591 - function takeClassForElement(elt, clazz) { 592 - elt = resolveTarget(elt); 593 - forEach(elt.parentElement.children, function(child){ 594 - removeClassFromElement(child, clazz); 595 - }) 596 - addClassToElement(elt, clazz); 597 - } 598 - 599 - function closest(elt, selector) { 600 - elt = resolveTarget(elt); 601 - if (elt.closest) { 602 - return elt.closest(selector); 603 - } else { 604 - // TODO remove when IE goes away 605 - do{ 606 - if (elt == null || matches(elt, selector)){ 607 - return elt; 608 - } 609 - } 610 - while (elt = elt && parentElt(elt)); 611 - return null; 612 - } 613 - } 614 - 615 - function startsWith(str, prefix) { 616 - return str.substring(0, prefix.length) === prefix 617 - } 618 - 619 - function endsWith(str, suffix) { 620 - return str.substring(str.length - suffix.length) === suffix 621 - } 622 - 623 - function normalizeSelector(selector) { 624 - var trimmedSelector = selector.trim(); 625 - if (startsWith(trimmedSelector, "<") && endsWith(trimmedSelector, "/>")) { 626 - return trimmedSelector.substring(1, trimmedSelector.length - 2); 627 - } else { 628 - return trimmedSelector; 629 - } 630 - } 631 - 632 - function querySelectorAllExt(elt, selector) { 633 - if (selector.indexOf("closest ") === 0) { 634 - return [closest(elt, normalizeSelector(selector.substr(8)))]; 635 - } else if (selector.indexOf("find ") === 0) { 636 - return [find(elt, normalizeSelector(selector.substr(5)))]; 637 - } else if (selector === "next") { 638 - return [elt.nextElementSibling] 639 - } else if (selector.indexOf("next ") === 0) { 640 - return [scanForwardQuery(elt, normalizeSelector(selector.substr(5)))]; 641 - } else if (selector === "previous") { 642 - return [elt.previousElementSibling] 643 - } else if (selector.indexOf("previous ") === 0) { 644 - return [scanBackwardsQuery(elt, normalizeSelector(selector.substr(9)))]; 645 - } else if (selector === 'document') { 646 - return [document]; 647 - } else if (selector === 'window') { 648 - return [window]; 649 - } else if (selector === 'body') { 650 - return [document.body]; 651 - } else { 652 - return getDocument().querySelectorAll(normalizeSelector(selector)); 653 - } 654 - } 655 - 656 - var scanForwardQuery = function(start, match) { 657 - var results = getDocument().querySelectorAll(match); 658 - for (var i = 0; i < results.length; i++) { 659 - var elt = results[i]; 660 - if (elt.compareDocumentPosition(start) === Node.DOCUMENT_POSITION_PRECEDING) { 661 - return elt; 662 - } 663 - } 664 - } 665 - 666 - var scanBackwardsQuery = function(start, match) { 667 - var results = getDocument().querySelectorAll(match); 668 - for (var i = results.length - 1; i >= 0; i--) { 669 - var elt = results[i]; 670 - if (elt.compareDocumentPosition(start) === Node.DOCUMENT_POSITION_FOLLOWING) { 671 - return elt; 672 - } 673 - } 674 - } 675 - 676 - function querySelectorExt(eltOrSelector, selector) { 677 - if (selector) { 678 - return querySelectorAllExt(eltOrSelector, selector)[0]; 679 - } else { 680 - return querySelectorAllExt(getDocument().body, eltOrSelector)[0]; 681 - } 682 - } 683 - 684 - function resolveTarget(arg2) { 685 - if (isType(arg2, 'String')) { 686 - return find(arg2); 687 - } else { 688 - return arg2; 689 - } 690 - } 691 - 692 - function processEventArgs(arg1, arg2, arg3) { 693 - if (isFunction(arg2)) { 694 - return { 695 - target: getDocument().body, 696 - event: arg1, 697 - listener: arg2 698 - } 699 - } else { 700 - return { 701 - target: resolveTarget(arg1), 702 - event: arg2, 703 - listener: arg3 704 - } 705 - } 706 - 707 - } 708 - 709 - function addEventListenerImpl(arg1, arg2, arg3) { 710 - ready(function(){ 711 - var eventArgs = processEventArgs(arg1, arg2, arg3); 712 - eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); 713 - }) 714 - var b = isFunction(arg2); 715 - return b ? arg2 : arg3; 716 - } 717 - 718 - function removeEventListenerImpl(arg1, arg2, arg3) { 719 - ready(function(){ 720 - var eventArgs = processEventArgs(arg1, arg2, arg3); 721 - eventArgs.target.removeEventListener(eventArgs.event, eventArgs.listener); 722 - }) 723 - return isFunction(arg2) ? arg2 : arg3; 724 - } 725 - 726 - //==================================================================== 727 - // Node processing 728 - //==================================================================== 729 - 730 - var DUMMY_ELT = getDocument().createElement("output"); // dummy element for bad selectors 731 - function findAttributeTargets(elt, attrName) { 732 - var attrTarget = getClosestAttributeValue(elt, attrName); 733 - if (attrTarget) { 734 - if (attrTarget === "this") { 735 - return [findThisElement(elt, attrName)]; 736 - } else { 737 - var result = querySelectorAllExt(elt, attrTarget); 738 - if (result.length === 0) { 739 - logError('The selector "' + attrTarget + '" on ' + attrName + " returned no matches!"); 740 - return [DUMMY_ELT] 741 - } else { 742 - return result; 743 - } 744 - } 745 - } 746 - } 747 - 748 - function findThisElement(elt, attribute){ 749 - return getClosestMatch(elt, function (elt) { 750 - return getAttributeValue(elt, attribute) != null; 751 - }) 752 - } 753 - 754 - function getTarget(elt) { 755 - var targetStr = getClosestAttributeValue(elt, "hx-target"); 756 - if (targetStr) { 757 - if (targetStr === "this") { 758 - return findThisElement(elt,'hx-target'); 759 - } else { 760 - return querySelectorExt(elt, targetStr) 761 - } 762 - } else { 763 - var data = getInternalData(elt); 764 - if (data.boosted) { 765 - return getDocument().body; 766 - } else { 767 - return elt; 768 - } 769 - } 770 - } 771 - 772 - function shouldSettleAttribute(name) { 773 - var attributesToSettle = htmx.config.attributesToSettle; 774 - for (var i = 0; i < attributesToSettle.length; i++) { 775 - if (name === attributesToSettle[i]) { 776 - return true; 777 - } 778 - } 779 - return false; 780 - } 781 - 782 - function cloneAttributes(mergeTo, mergeFrom) { 783 - forEach(mergeTo.attributes, function (attr) { 784 - if (!mergeFrom.hasAttribute(attr.name) && shouldSettleAttribute(attr.name)) { 785 - mergeTo.removeAttribute(attr.name) 786 - } 787 - }); 788 - forEach(mergeFrom.attributes, function (attr) { 789 - if (shouldSettleAttribute(attr.name)) { 790 - mergeTo.setAttribute(attr.name, attr.value); 791 - } 792 - }); 793 - } 794 - 795 - function isInlineSwap(swapStyle, target) { 796 - var extensions = getExtensions(target); 797 - for (var i = 0; i < extensions.length; i++) { 798 - var extension = extensions[i]; 799 - try { 800 - if (extension.isInlineSwap(swapStyle)) { 801 - return true; 802 - } 803 - } catch(e) { 804 - logError(e); 805 - } 806 - } 807 - return swapStyle === "outerHTML"; 808 - } 809 - 810 - /** 811 - * 812 - * @param {string} oobValue 813 - * @param {HTMLElement} oobElement 814 - * @param {*} settleInfo 815 - * @returns 816 - */ 817 - function oobSwap(oobValue, oobElement, settleInfo) { 818 - var selector = "#" + getRawAttribute(oobElement, "id"); 819 - var swapStyle = "outerHTML"; 820 - if (oobValue === "true") { 821 - // do nothing 822 - } else if (oobValue.indexOf(":") > 0) { 823 - swapStyle = oobValue.substr(0, oobValue.indexOf(":")); 824 - selector = oobValue.substr(oobValue.indexOf(":") + 1, oobValue.length); 825 - } else { 826 - swapStyle = oobValue; 827 - } 828 - 829 - var targets = getDocument().querySelectorAll(selector); 830 - if (targets) { 831 - forEach( 832 - targets, 833 - function (target) { 834 - var fragment; 835 - var oobElementClone = oobElement.cloneNode(true); 836 - fragment = getDocument().createDocumentFragment(); 837 - fragment.appendChild(oobElementClone); 838 - if (!isInlineSwap(swapStyle, target)) { 839 - fragment = oobElementClone; // if this is not an inline swap, we use the content of the node, not the node itself 840 - } 841 - 842 - var beforeSwapDetails = {shouldSwap: true, target: target, fragment:fragment }; 843 - if (!triggerEvent(target, 'htmx:oobBeforeSwap', beforeSwapDetails)) return; 844 - 845 - target = beforeSwapDetails.target; // allow re-targeting 846 - if (beforeSwapDetails['shouldSwap']){ 847 - swap(swapStyle, target, target, fragment, settleInfo); 848 - } 849 - forEach(settleInfo.elts, function (elt) { 850 - triggerEvent(elt, 'htmx:oobAfterSwap', beforeSwapDetails); 851 - }); 852 - } 853 - ); 854 - oobElement.parentNode.removeChild(oobElement); 855 - } else { 856 - oobElement.parentNode.removeChild(oobElement); 857 - triggerErrorEvent(getDocument().body, "htmx:oobErrorNoTarget", {content: oobElement}); 858 - } 859 - return oobValue; 860 - } 861 - 862 - function handleOutOfBandSwaps(elt, fragment, settleInfo) { 863 - var oobSelects = getClosestAttributeValue(elt, "hx-select-oob"); 864 - if (oobSelects) { 865 - var oobSelectValues = oobSelects.split(","); 866 - for (var i = 0; i < oobSelectValues.length; i++) { 867 - var oobSelectValue = oobSelectValues[i].split(":", 2); 868 - var id = oobSelectValue[0].trim(); 869 - if (id.indexOf("#") === 0) { 870 - id = id.substring(1); 871 - } 872 - var oobValue = oobSelectValue[1] || "true"; 873 - var oobElement = fragment.querySelector("#" + id); 874 - if (oobElement) { 875 - oobSwap(oobValue, oobElement, settleInfo); 876 - } 877 - } 878 - } 879 - forEach(findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]'), function (oobElement) { 880 - var oobValue = getAttributeValue(oobElement, "hx-swap-oob"); 881 - if (oobValue != null) { 882 - oobSwap(oobValue, oobElement, settleInfo); 883 - } 884 - }); 885 - } 886 - 887 - function handlePreservedElements(fragment) { 888 - forEach(findAll(fragment, '[hx-preserve], [data-hx-preserve]'), function (preservedElt) { 889 - var id = getAttributeValue(preservedElt, "id"); 890 - var oldElt = getDocument().getElementById(id); 891 - if (oldElt != null) { 892 - preservedElt.parentNode.replaceChild(oldElt, preservedElt); 893 - } 894 - }); 895 - } 896 - 897 - function handleAttributes(parentNode, fragment, settleInfo) { 898 - forEach(fragment.querySelectorAll("[id]"), function (newNode) { 899 - var id = getRawAttribute(newNode, "id") 900 - if (id && id.length > 0) { 901 - var normalizedId = id.replace("'", "\\'"); 902 - var normalizedTag = newNode.tagName.replace(':', '\\:'); 903 - var oldNode = parentNode.querySelector(normalizedTag + "[id='" + normalizedId + "']"); 904 - if (oldNode && oldNode !== parentNode) { 905 - var newAttributes = newNode.cloneNode(); 906 - cloneAttributes(newNode, oldNode); 907 - settleInfo.tasks.push(function () { 908 - cloneAttributes(newNode, newAttributes); 909 - }); 910 - } 911 - } 912 - }); 913 - } 914 - 915 - function makeAjaxLoadTask(child) { 916 - return function () { 917 - removeClassFromElement(child, htmx.config.addedClass); 918 - processNode(child); 919 - processScripts(child); 920 - processFocus(child) 921 - triggerEvent(child, 'htmx:load'); 922 - }; 923 - } 924 - 925 - function processFocus(child) { 926 - var autofocus = "[autofocus]"; 927 - var autoFocusedElt = matches(child, autofocus) ? child : child.querySelector(autofocus) 928 - if (autoFocusedElt != null) { 929 - autoFocusedElt.focus(); 930 - } 931 - } 932 - 933 - function insertNodesBefore(parentNode, insertBefore, fragment, settleInfo) { 934 - handleAttributes(parentNode, fragment, settleInfo); 935 - while(fragment.childNodes.length > 0){ 936 - var child = fragment.firstChild; 937 - addClassToElement(child, htmx.config.addedClass); 938 - parentNode.insertBefore(child, insertBefore); 939 - if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) { 940 - settleInfo.tasks.push(makeAjaxLoadTask(child)); 941 - } 942 - } 943 - } 944 - 945 - // based on https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0, 946 - // derived from Java's string hashcode implementation 947 - function stringHash(string, hash) { 948 - var char = 0; 949 - while (char < string.length){ 950 - hash = (hash << 5) - hash + string.charCodeAt(char++) | 0; // bitwise or ensures we have a 32-bit int 951 - } 952 - return hash; 953 - } 954 - 955 - function attributeHash(elt) { 956 - var hash = 0; 957 - // IE fix 958 - if (elt.attributes) { 959 - for (var i = 0; i < elt.attributes.length; i++) { 960 - var attribute = elt.attributes[i]; 961 - if(attribute.value){ // only include attributes w/ actual values (empty is same as non-existent) 962 - hash = stringHash(attribute.name, hash); 963 - hash = stringHash(attribute.value, hash); 964 - } 965 - } 966 - } 967 - return hash; 968 - } 969 - 970 - function deInitOnHandlers(elt) { 971 - var internalData = getInternalData(elt); 972 - if (internalData.onHandlers) { 973 - for (var i = 0; i < internalData.onHandlers.length; i++) { 974 - const handlerInfo = internalData.onHandlers[i]; 975 - elt.removeEventListener(handlerInfo.event, handlerInfo.listener); 976 - } 977 - delete internalData.onHandlers 978 - } 979 - } 980 - 981 - function deInitNode(element) { 982 - var internalData = getInternalData(element); 983 - if (internalData.timeout) { 984 - clearTimeout(internalData.timeout); 985 - } 986 - if (internalData.webSocket) { 987 - internalData.webSocket.close(); 988 - } 989 - if (internalData.sseEventSource) { 990 - internalData.sseEventSource.close(); 991 - } 992 - if (internalData.listenerInfos) { 993 - forEach(internalData.listenerInfos, function (info) { 994 - if (info.on) { 995 - info.on.removeEventListener(info.trigger, info.listener); 996 - } 997 - }); 998 - } 999 - deInitOnHandlers(element); 1000 - forEach(Object.keys(internalData), function(key) { delete internalData[key] }); 1001 - } 1002 - 1003 - function cleanUpElement(element) { 1004 - triggerEvent(element, "htmx:beforeCleanupElement") 1005 - deInitNode(element); 1006 - if (element.children) { // IE 1007 - forEach(element.children, function(child) { cleanUpElement(child) }); 1008 - } 1009 - } 1010 - 1011 - function swapOuterHTML(target, fragment, settleInfo) { 1012 - if (target.tagName === "BODY") { 1013 - return swapInnerHTML(target, fragment, settleInfo); 1014 - } else { 1015 - // @type {HTMLElement} 1016 - var newElt 1017 - var eltBeforeNewContent = target.previousSibling; 1018 - insertNodesBefore(parentElt(target), target, fragment, settleInfo); 1019 - if (eltBeforeNewContent == null) { 1020 - newElt = parentElt(target).firstChild; 1021 - } else { 1022 - newElt = eltBeforeNewContent.nextSibling; 1023 - } 1024 - settleInfo.elts = settleInfo.elts.filter(function(e) { return e != target }); 1025 - while(newElt && newElt !== target) { 1026 - if (newElt.nodeType === Node.ELEMENT_NODE) { 1027 - settleInfo.elts.push(newElt); 1028 - } 1029 - newElt = newElt.nextElementSibling; 1030 - } 1031 - cleanUpElement(target); 1032 - parentElt(target).removeChild(target); 1033 - } 1034 - } 1035 - 1036 - function swapAfterBegin(target, fragment, settleInfo) { 1037 - return insertNodesBefore(target, target.firstChild, fragment, settleInfo); 1038 - } 1039 - 1040 - function swapBeforeBegin(target, fragment, settleInfo) { 1041 - return insertNodesBefore(parentElt(target), target, fragment, settleInfo); 1042 - } 1043 - 1044 - function swapBeforeEnd(target, fragment, settleInfo) { 1045 - return insertNodesBefore(target, null, fragment, settleInfo); 1046 - } 1047 - 1048 - function swapAfterEnd(target, fragment, settleInfo) { 1049 - return insertNodesBefore(parentElt(target), target.nextSibling, fragment, settleInfo); 1050 - } 1051 - function swapDelete(target, fragment, settleInfo) { 1052 - cleanUpElement(target); 1053 - return parentElt(target).removeChild(target); 1054 - } 1055 - 1056 - function swapInnerHTML(target, fragment, settleInfo) { 1057 - var firstChild = target.firstChild; 1058 - insertNodesBefore(target, firstChild, fragment, settleInfo); 1059 - if (firstChild) { 1060 - while (firstChild.nextSibling) { 1061 - cleanUpElement(firstChild.nextSibling) 1062 - target.removeChild(firstChild.nextSibling); 1063 - } 1064 - cleanUpElement(firstChild) 1065 - target.removeChild(firstChild); 1066 - } 1067 - } 1068 - 1069 - function maybeSelectFromResponse(elt, fragment, selectOverride) { 1070 - var selector = selectOverride || getClosestAttributeValue(elt, "hx-select"); 1071 - if (selector) { 1072 - var newFragment = getDocument().createDocumentFragment(); 1073 - forEach(fragment.querySelectorAll(selector), function (node) { 1074 - newFragment.appendChild(node); 1075 - }); 1076 - fragment = newFragment; 1077 - } 1078 - return fragment; 1079 - } 1080 - 1081 - function swap(swapStyle, elt, target, fragment, settleInfo) { 1082 - switch (swapStyle) { 1083 - case "none": 1084 - return; 1085 - case "outerHTML": 1086 - swapOuterHTML(target, fragment, settleInfo); 1087 - return; 1088 - case "afterbegin": 1089 - swapAfterBegin(target, fragment, settleInfo); 1090 - return; 1091 - case "beforebegin": 1092 - swapBeforeBegin(target, fragment, settleInfo); 1093 - return; 1094 - case "beforeend": 1095 - swapBeforeEnd(target, fragment, settleInfo); 1096 - return; 1097 - case "afterend": 1098 - swapAfterEnd(target, fragment, settleInfo); 1099 - return; 1100 - case "delete": 1101 - swapDelete(target, fragment, settleInfo); 1102 - return; 1103 - default: 1104 - var extensions = getExtensions(elt); 1105 - for (var i = 0; i < extensions.length; i++) { 1106 - var ext = extensions[i]; 1107 - try { 1108 - var newElements = ext.handleSwap(swapStyle, target, fragment, settleInfo); 1109 - if (newElements) { 1110 - if (typeof newElements.length !== 'undefined') { 1111 - // if handleSwap returns an array (like) of elements, we handle them 1112 - for (var j = 0; j < newElements.length; j++) { 1113 - var child = newElements[j]; 1114 - if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) { 1115 - settleInfo.tasks.push(makeAjaxLoadTask(child)); 1116 - } 1117 - } 1118 - } 1119 - return; 1120 - } 1121 - } catch (e) { 1122 - logError(e); 1123 - } 1124 - } 1125 - if (swapStyle === "innerHTML") { 1126 - swapInnerHTML(target, fragment, settleInfo); 1127 - } else { 1128 - swap(htmx.config.defaultSwapStyle, elt, target, fragment, settleInfo); 1129 - } 1130 - } 1131 - } 1132 - 1133 - function findTitle(content) { 1134 - if (content.indexOf('<title') > -1) { 1135 - var contentWithSvgsRemoved = content.replace(SVG_TAGS_REGEX, ''); 1136 - var result = contentWithSvgsRemoved.match(TITLE_TAG_REGEX); 1137 - if (result) { 1138 - return result[2]; 1139 - } 1140 - } 1141 - } 1142 - 1143 - function selectAndSwap(swapStyle, target, elt, responseText, settleInfo, selectOverride) { 1144 - settleInfo.title = findTitle(responseText); 1145 - var fragment = makeFragment(responseText); 1146 - if (fragment) { 1147 - handleOutOfBandSwaps(elt, fragment, settleInfo); 1148 - fragment = maybeSelectFromResponse(elt, fragment, selectOverride); 1149 - handlePreservedElements(fragment); 1150 - return swap(swapStyle, elt, target, fragment, settleInfo); 1151 - } 1152 - } 1153 - 1154 - function handleTrigger(xhr, header, elt) { 1155 - var triggerBody = xhr.getResponseHeader(header); 1156 - if (triggerBody.indexOf("{") === 0) { 1157 - var triggers = parseJSON(triggerBody); 1158 - for (var eventName in triggers) { 1159 - if (triggers.hasOwnProperty(eventName)) { 1160 - var detail = triggers[eventName]; 1161 - if (!isRawObject(detail)) { 1162 - detail = {"value": detail} 1163 - } 1164 - triggerEvent(elt, eventName, detail); 1165 - } 1166 - } 1167 - } else { 1168 - var eventNames = triggerBody.split(",") 1169 - for (var i = 0; i < eventNames.length; i++) { 1170 - triggerEvent(elt, eventNames[i].trim(), []); 1171 - } 1172 - } 1173 - } 1174 - 1175 - var WHITESPACE = /\s/; 1176 - var WHITESPACE_OR_COMMA = /[\s,]/; 1177 - var SYMBOL_START = /[_$a-zA-Z]/; 1178 - var SYMBOL_CONT = /[_$a-zA-Z0-9]/; 1179 - var STRINGISH_START = ['"', "'", "/"]; 1180 - var NOT_WHITESPACE = /[^\s]/; 1181 - var COMBINED_SELECTOR_START = /[{(]/; 1182 - var COMBINED_SELECTOR_END = /[})]/; 1183 - function tokenizeString(str) { 1184 - var tokens = []; 1185 - var position = 0; 1186 - while (position < str.length) { 1187 - if(SYMBOL_START.exec(str.charAt(position))) { 1188 - var startPosition = position; 1189 - while (SYMBOL_CONT.exec(str.charAt(position + 1))) { 1190 - position++; 1191 - } 1192 - tokens.push(str.substr(startPosition, position - startPosition + 1)); 1193 - } else if (STRINGISH_START.indexOf(str.charAt(position)) !== -1) { 1194 - var startChar = str.charAt(position); 1195 - var startPosition = position; 1196 - position++; 1197 - while (position < str.length && str.charAt(position) !== startChar ) { 1198 - if (str.charAt(position) === "\\") { 1199 - position++; 1200 - } 1201 - position++; 1202 - } 1203 - tokens.push(str.substr(startPosition, position - startPosition + 1)); 1204 - } else { 1205 - var symbol = str.charAt(position); 1206 - tokens.push(symbol); 1207 - } 1208 - position++; 1209 - } 1210 - return tokens; 1211 - } 1212 - 1213 - function isPossibleRelativeReference(token, last, paramName) { 1214 - return SYMBOL_START.exec(token.charAt(0)) && 1215 - token !== "true" && 1216 - token !== "false" && 1217 - token !== "this" && 1218 - token !== paramName && 1219 - last !== "."; 1220 - } 1221 - 1222 - function maybeGenerateConditional(elt, tokens, paramName) { 1223 - if (tokens[0] === '[') { 1224 - tokens.shift(); 1225 - var bracketCount = 1; 1226 - var conditionalSource = " return (function(" + paramName + "){ return ("; 1227 - var last = null; 1228 - while (tokens.length > 0) { 1229 - var token = tokens[0]; 1230 - if (token === "]") { 1231 - bracketCount--; 1232 - if (bracketCount === 0) { 1233 - if (last === null) { 1234 - conditionalSource = conditionalSource + "true"; 1235 - } 1236 - tokens.shift(); 1237 - conditionalSource += ")})"; 1238 - try { 1239 - var conditionFunction = maybeEval(elt,function () { 1240 - return Function(conditionalSource)(); 1241 - }, 1242 - function(){return true}) 1243 - conditionFunction.source = conditionalSource; 1244 - return conditionFunction; 1245 - } catch (e) { 1246 - triggerErrorEvent(getDocument().body, "htmx:syntax:error", {error:e, source:conditionalSource}) 1247 - return null; 1248 - } 1249 - } 1250 - } else if (token === "[") { 1251 - bracketCount++; 1252 - } 1253 - if (isPossibleRelativeReference(token, last, paramName)) { 1254 - conditionalSource += "((" + paramName + "." + token + ") ? (" + paramName + "." + token + ") : (window." + token + "))"; 1255 - } else { 1256 - conditionalSource = conditionalSource + token; 1257 - } 1258 - last = tokens.shift(); 1259 - } 1260 - } 1261 - } 1262 - 1263 - function consumeUntil(tokens, match) { 1264 - var result = ""; 1265 - while (tokens.length > 0 && !match.test(tokens[0])) { 1266 - result += tokens.shift(); 1267 - } 1268 - return result; 1269 - } 1270 - 1271 - function consumeCSSSelector(tokens) { 1272 - var result; 1273 - if (tokens.length > 0 && COMBINED_SELECTOR_START.test(tokens[0])) { 1274 - tokens.shift(); 1275 - result = consumeUntil(tokens, COMBINED_SELECTOR_END).trim(); 1276 - tokens.shift(); 1277 - } else { 1278 - result = consumeUntil(tokens, WHITESPACE_OR_COMMA); 1279 - } 1280 - return result; 1281 - } 1282 - 1283 - var INPUT_SELECTOR = 'input, textarea, select'; 1284 - 1285 - /** 1286 - * @param {HTMLElement} elt 1287 - * @param {string} explicitTrigger 1288 - * @param {cache} cache for trigger specs 1289 - * @returns {import("./htmx").HtmxTriggerSpecification[]} 1290 - */ 1291 - function parseAndCacheTrigger(elt, explicitTrigger, cache) { 1292 - var triggerSpecs = []; 1293 - var tokens = tokenizeString(explicitTrigger); 1294 - do { 1295 - consumeUntil(tokens, NOT_WHITESPACE); 1296 - var initialLength = tokens.length; 1297 - var trigger = consumeUntil(tokens, /[,\[\s]/); 1298 - if (trigger !== "") { 1299 - if (trigger === "every") { 1300 - var every = {trigger: 'every'}; 1301 - consumeUntil(tokens, NOT_WHITESPACE); 1302 - every.pollInterval = parseInterval(consumeUntil(tokens, /[,\[\s]/)); 1303 - consumeUntil(tokens, NOT_WHITESPACE); 1304 - var eventFilter = maybeGenerateConditional(elt, tokens, "event"); 1305 - if (eventFilter) { 1306 - every.eventFilter = eventFilter; 1307 - } 1308 - triggerSpecs.push(every); 1309 - } else if (trigger.indexOf("sse:") === 0) { 1310 - triggerSpecs.push({trigger: 'sse', sseEvent: trigger.substr(4)}); 1311 - } else { 1312 - var triggerSpec = {trigger: trigger}; 1313 - var eventFilter = maybeGenerateConditional(elt, tokens, "event"); 1314 - if (eventFilter) { 1315 - triggerSpec.eventFilter = eventFilter; 1316 - } 1317 - while (tokens.length > 0 && tokens[0] !== ",") { 1318 - consumeUntil(tokens, NOT_WHITESPACE) 1319 - var token = tokens.shift(); 1320 - if (token === "changed") { 1321 - triggerSpec.changed = true; 1322 - } else if (token === "once") { 1323 - triggerSpec.once = true; 1324 - } else if (token === "consume") { 1325 - triggerSpec.consume = true; 1326 - } else if (token === "delay" && tokens[0] === ":") { 1327 - tokens.shift(); 1328 - triggerSpec.delay = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA)); 1329 - } else if (token === "from" && tokens[0] === ":") { 1330 - tokens.shift(); 1331 - if (COMBINED_SELECTOR_START.test(tokens[0])) { 1332 - var from_arg = consumeCSSSelector(tokens); 1333 - } else { 1334 - var from_arg = consumeUntil(tokens, WHITESPACE_OR_COMMA); 1335 - if (from_arg === "closest" || from_arg === "find" || from_arg === "next" || from_arg === "previous") { 1336 - tokens.shift(); 1337 - var selector = consumeCSSSelector(tokens); 1338 - // `next` and `previous` allow a selector-less syntax 1339 - if (selector.length > 0) { 1340 - from_arg += " " + selector; 1341 - } 1342 - } 1343 - } 1344 - triggerSpec.from = from_arg; 1345 - } else if (token === "target" && tokens[0] === ":") { 1346 - tokens.shift(); 1347 - triggerSpec.target = consumeCSSSelector(tokens); 1348 - } else if (token === "throttle" && tokens[0] === ":") { 1349 - tokens.shift(); 1350 - triggerSpec.throttle = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA)); 1351 - } else if (token === "queue" && tokens[0] === ":") { 1352 - tokens.shift(); 1353 - triggerSpec.queue = consumeUntil(tokens, WHITESPACE_OR_COMMA); 1354 - } else if (token === "root" && tokens[0] === ":") { 1355 - tokens.shift(); 1356 - triggerSpec[token] = consumeCSSSelector(tokens); 1357 - } else if (token === "threshold" && tokens[0] === ":") { 1358 - tokens.shift(); 1359 - triggerSpec[token] = consumeUntil(tokens, WHITESPACE_OR_COMMA); 1360 - } else { 1361 - triggerErrorEvent(elt, "htmx:syntax:error", {token:tokens.shift()}); 1362 - } 1363 - } 1364 - triggerSpecs.push(triggerSpec); 1365 - } 1366 - } 1367 - if (tokens.length === initialLength) { 1368 - triggerErrorEvent(elt, "htmx:syntax:error", {token:tokens.shift()}); 1369 - } 1370 - consumeUntil(tokens, NOT_WHITESPACE); 1371 - } while (tokens[0] === "," && tokens.shift()) 1372 - if (cache) { 1373 - cache[explicitTrigger] = triggerSpecs 1374 - } 1375 - return triggerSpecs 1376 - } 1377 - 1378 - /** 1379 - * @param {HTMLElement} elt 1380 - * @returns {import("./htmx").HtmxTriggerSpecification[]} 1381 - */ 1382 - function getTriggerSpecs(elt) { 1383 - var explicitTrigger = getAttributeValue(elt, 'hx-trigger'); 1384 - var triggerSpecs = []; 1385 - if (explicitTrigger) { 1386 - var cache = htmx.config.triggerSpecsCache 1387 - triggerSpecs = (cache && cache[explicitTrigger]) || parseAndCacheTrigger(elt, explicitTrigger, cache) 1388 - } 1389 - 1390 - if (triggerSpecs.length > 0) { 1391 - return triggerSpecs; 1392 - } else if (matches(elt, 'form')) { 1393 - return [{trigger: 'submit'}]; 1394 - } else if (matches(elt, 'input[type="button"], input[type="submit"]')){ 1395 - return [{trigger: 'click'}]; 1396 - } else if (matches(elt, INPUT_SELECTOR)) { 1397 - return [{trigger: 'change'}]; 1398 - } else { 1399 - return [{trigger: 'click'}]; 1400 - } 1401 - } 1402 - 1403 - function cancelPolling(elt) { 1404 - getInternalData(elt).cancelled = true; 1405 - } 1406 - 1407 - function processPolling(elt, handler, spec) { 1408 - var nodeData = getInternalData(elt); 1409 - nodeData.timeout = setTimeout(function () { 1410 - if (bodyContains(elt) && nodeData.cancelled !== true) { 1411 - if (!maybeFilterEvent(spec, elt, makeEvent('hx:poll:trigger', { 1412 - triggerSpec: spec, 1413 - target: elt 1414 - }))) { 1415 - handler(elt); 1416 - } 1417 - processPolling(elt, handler, spec); 1418 - } 1419 - }, spec.pollInterval); 1420 - } 1421 - 1422 - function isLocalLink(elt) { 1423 - return location.hostname === elt.hostname && 1424 - getRawAttribute(elt,'href') && 1425 - getRawAttribute(elt,'href').indexOf("#") !== 0; 1426 - } 1427 - 1428 - function boostElement(elt, nodeData, triggerSpecs) { 1429 - if ((elt.tagName === "A" && isLocalLink(elt) && (elt.target === "" || elt.target === "_self")) || elt.tagName === "FORM") { 1430 - nodeData.boosted = true; 1431 - var verb, path; 1432 - if (elt.tagName === "A") { 1433 - verb = "get"; 1434 - path = getRawAttribute(elt, 'href') 1435 - } else { 1436 - var rawAttribute = getRawAttribute(elt, "method"); 1437 - verb = rawAttribute ? rawAttribute.toLowerCase() : "get"; 1438 - if (verb === "get") { 1439 - } 1440 - path = getRawAttribute(elt, 'action'); 1441 - } 1442 - triggerSpecs.forEach(function(triggerSpec) { 1443 - addEventListener(elt, function(elt, evt) { 1444 - if (closest(elt, htmx.config.disableSelector)) { 1445 - cleanUpElement(elt) 1446 - return 1447 - } 1448 - issueAjaxRequest(verb, path, elt, evt) 1449 - }, nodeData, triggerSpec, true); 1450 - }); 1451 - } 1452 - } 1453 - 1454 - /** 1455 - * 1456 - * @param {Event} evt 1457 - * @param {HTMLElement} elt 1458 - * @returns 1459 - */ 1460 - function shouldCancel(evt, elt) { 1461 - if (evt.type === "submit" || evt.type === "click") { 1462 - if (elt.tagName === "FORM") { 1463 - return true; 1464 - } 1465 - if (matches(elt, 'input[type="submit"], button') && closest(elt, 'form') !== null) { 1466 - return true; 1467 - } 1468 - if (elt.tagName === "A" && elt.href && 1469 - (elt.getAttribute('href') === '#' || elt.getAttribute('href').indexOf("#") !== 0)) { 1470 - return true; 1471 - } 1472 - } 1473 - return false; 1474 - } 1475 - 1476 - function ignoreBoostedAnchorCtrlClick(elt, evt) { 1477 - return getInternalData(elt).boosted && elt.tagName === "A" && evt.type === "click" && (evt.ctrlKey || evt.metaKey); 1478 - } 1479 - 1480 - function maybeFilterEvent(triggerSpec, elt, evt) { 1481 - var eventFilter = triggerSpec.eventFilter; 1482 - if(eventFilter){ 1483 - try { 1484 - return eventFilter.call(elt, evt) !== true; 1485 - } catch(e) { 1486 - triggerErrorEvent(getDocument().body, "htmx:eventFilter:error", {error: e, source:eventFilter.source}); 1487 - return true; 1488 - } 1489 - } 1490 - return false; 1491 - } 1492 - 1493 - function addEventListener(elt, handler, nodeData, triggerSpec, explicitCancel) { 1494 - var elementData = getInternalData(elt); 1495 - var eltsToListenOn; 1496 - if (triggerSpec.from) { 1497 - eltsToListenOn = querySelectorAllExt(elt, triggerSpec.from); 1498 - } else { 1499 - eltsToListenOn = [elt]; 1500 - } 1501 - // store the initial values of the elements, so we can tell if they change 1502 - if (triggerSpec.changed) { 1503 - eltsToListenOn.forEach(function (eltToListenOn) { 1504 - var eltToListenOnData = getInternalData(eltToListenOn); 1505 - eltToListenOnData.lastValue = eltToListenOn.value; 1506 - }) 1507 - } 1508 - forEach(eltsToListenOn, function (eltToListenOn) { 1509 - var eventListener = function (evt) { 1510 - if (!bodyContains(elt)) { 1511 - eltToListenOn.removeEventListener(triggerSpec.trigger, eventListener); 1512 - return; 1513 - } 1514 - if (ignoreBoostedAnchorCtrlClick(elt, evt)) { 1515 - return; 1516 - } 1517 - if (explicitCancel || shouldCancel(evt, elt)) { 1518 - evt.preventDefault(); 1519 - } 1520 - if (maybeFilterEvent(triggerSpec, elt, evt)) { 1521 - return; 1522 - } 1523 - var eventData = getInternalData(evt); 1524 - eventData.triggerSpec = triggerSpec; 1525 - if (eventData.handledFor == null) { 1526 - eventData.handledFor = []; 1527 - } 1528 - if (eventData.handledFor.indexOf(elt) < 0) { 1529 - eventData.handledFor.push(elt); 1530 - if (triggerSpec.consume) { 1531 - evt.stopPropagation(); 1532 - } 1533 - if (triggerSpec.target && evt.target) { 1534 - if (!matches(evt.target, triggerSpec.target)) { 1535 - return; 1536 - } 1537 - } 1538 - if (triggerSpec.once) { 1539 - if (elementData.triggeredOnce) { 1540 - return; 1541 - } else { 1542 - elementData.triggeredOnce = true; 1543 - } 1544 - } 1545 - if (triggerSpec.changed) { 1546 - var eltToListenOnData = getInternalData(eltToListenOn) 1547 - if (eltToListenOnData.lastValue === eltToListenOn.value) { 1548 - return; 1549 - } 1550 - eltToListenOnData.lastValue = eltToListenOn.value 1551 - } 1552 - if (elementData.delayed) { 1553 - clearTimeout(elementData.delayed); 1554 - } 1555 - if (elementData.throttle) { 1556 - return; 1557 - } 1558 - 1559 - if (triggerSpec.throttle > 0) { 1560 - if (!elementData.throttle) { 1561 - handler(elt, evt); 1562 - elementData.throttle = setTimeout(function () { 1563 - elementData.throttle = null; 1564 - }, triggerSpec.throttle); 1565 - } 1566 - } else if (triggerSpec.delay > 0) { 1567 - elementData.delayed = setTimeout(function() { handler(elt, evt) }, triggerSpec.delay); 1568 - } else { 1569 - triggerEvent(elt, 'htmx:trigger') 1570 - handler(elt, evt); 1571 - } 1572 - } 1573 - }; 1574 - if (nodeData.listenerInfos == null) { 1575 - nodeData.listenerInfos = []; 1576 - } 1577 - nodeData.listenerInfos.push({ 1578 - trigger: triggerSpec.trigger, 1579 - listener: eventListener, 1580 - on: eltToListenOn 1581 - }) 1582 - eltToListenOn.addEventListener(triggerSpec.trigger, eventListener); 1583 - }); 1584 - } 1585 - 1586 - var windowIsScrolling = false // used by initScrollHandler 1587 - var scrollHandler = null; 1588 - function initScrollHandler() { 1589 - if (!scrollHandler) { 1590 - scrollHandler = function() { 1591 - windowIsScrolling = true 1592 - }; 1593 - window.addEventListener("scroll", scrollHandler) 1594 - setInterval(function() { 1595 - if (windowIsScrolling) { 1596 - windowIsScrolling = false; 1597 - forEach(getDocument().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"), function (elt) { 1598 - maybeReveal(elt); 1599 - }) 1600 - } 1601 - }, 200); 1602 - } 1603 - } 1604 - 1605 - function maybeReveal(elt) { 1606 - if (!hasAttribute(elt,'data-hx-revealed') && isScrolledIntoView(elt)) { 1607 - elt.setAttribute('data-hx-revealed', 'true'); 1608 - var nodeData = getInternalData(elt); 1609 - if (nodeData.initHash) { 1610 - triggerEvent(elt, 'revealed'); 1611 - } else { 1612 - // if the node isn't initialized, wait for it before triggering the request 1613 - elt.addEventListener("htmx:afterProcessNode", function(evt) { triggerEvent(elt, 'revealed') }, {once: true}); 1614 - } 1615 - } 1616 - } 1617 - 1618 - //==================================================================== 1619 - // Web Sockets 1620 - //==================================================================== 1621 - 1622 - function processWebSocketInfo(elt, nodeData, info) { 1623 - var values = splitOnWhitespace(info); 1624 - for (var i = 0; i < values.length; i++) { 1625 - var value = values[i].split(/:(.+)/); 1626 - if (value[0] === "connect") { 1627 - ensureWebSocket(elt, value[1], 0); 1628 - } 1629 - if (value[0] === "send") { 1630 - processWebSocketSend(elt); 1631 - } 1632 - } 1633 - } 1634 - 1635 - function ensureWebSocket(elt, wssSource, retryCount) { 1636 - if (!bodyContains(elt)) { 1637 - return; // stop ensuring websocket connection when socket bearing element ceases to exist 1638 - } 1639 - 1640 - if (wssSource.indexOf("/") == 0) { // complete absolute paths only 1641 - var base_part = location.hostname + (location.port ? ':'+location.port: ''); 1642 - if (location.protocol == 'https:') { 1643 - wssSource = "wss://" + base_part + wssSource; 1644 - } else if (location.protocol == 'http:') { 1645 - wssSource = "ws://" + base_part + wssSource; 1646 - } 1647 - } 1648 - var socket = htmx.createWebSocket(wssSource); 1649 - socket.onerror = function (e) { 1650 - triggerErrorEvent(elt, "htmx:wsError", {error:e, socket:socket}); 1651 - maybeCloseWebSocketSource(elt); 1652 - }; 1653 - 1654 - socket.onclose = function (e) { 1655 - if ([1006, 1012, 1013].indexOf(e.code) >= 0) { // Abnormal Closure/Service Restart/Try Again Later 1656 - var delay = getWebSocketReconnectDelay(retryCount); 1657 - setTimeout(function() { 1658 - ensureWebSocket(elt, wssSource, retryCount+1); // creates a websocket with a new timeout 1659 - }, delay); 1660 - } 1661 - }; 1662 - socket.onopen = function (e) { 1663 - retryCount = 0; 1664 - } 1665 - 1666 - getInternalData(elt).webSocket = socket; 1667 - socket.addEventListener('message', function (event) { 1668 - if (maybeCloseWebSocketSource(elt)) { 1669 - return; 1670 - } 1671 - 1672 - var response = event.data; 1673 - withExtensions(elt, function(extension){ 1674 - response = extension.transformResponse(response, null, elt); 1675 - }); 1676 - 1677 - var settleInfo = makeSettleInfo(elt); 1678 - var fragment = makeFragment(response); 1679 - var children = toArray(fragment.children); 1680 - for (var i = 0; i < children.length; i++) { 1681 - var child = children[i]; 1682 - oobSwap(getAttributeValue(child, "hx-swap-oob") || "true", child, settleInfo); 1683 - } 1684 - 1685 - settleImmediately(settleInfo.tasks); 1686 - }); 1687 - } 1688 - 1689 - function maybeCloseWebSocketSource(elt) { 1690 - if (!bodyContains(elt)) { 1691 - getInternalData(elt).webSocket.close(); 1692 - return true; 1693 - } 1694 - } 1695 - 1696 - function processWebSocketSend(elt) { 1697 - var webSocketSourceElt = getClosestMatch(elt, function (parent) { 1698 - return getInternalData(parent).webSocket != null; 1699 - }); 1700 - if (webSocketSourceElt) { 1701 - elt.addEventListener(getTriggerSpecs(elt)[0].trigger, function (evt) { 1702 - var webSocket = getInternalData(webSocketSourceElt).webSocket; 1703 - var headers = getHeaders(elt, webSocketSourceElt); 1704 - var results = getInputValues(elt, 'post'); 1705 - var errors = results.errors; 1706 - var rawParameters = results.values; 1707 - var expressionVars = getExpressionVars(elt); 1708 - var allParameters = mergeObjects(rawParameters, expressionVars); 1709 - var filteredParameters = filterValues(allParameters, elt); 1710 - filteredParameters['HEADERS'] = headers; 1711 - if (errors && errors.length > 0) { 1712 - triggerEvent(elt, 'htmx:validation:halted', errors); 1713 - return; 1714 - } 1715 - webSocket.send(JSON.stringify(filteredParameters)); 1716 - if(shouldCancel(evt, elt)){ 1717 - evt.preventDefault(); 1718 - } 1719 - }); 1720 - } else { 1721 - triggerErrorEvent(elt, "htmx:noWebSocketSourceError"); 1722 - } 1723 - } 1724 - 1725 - function getWebSocketReconnectDelay(retryCount) { 1726 - var delay = htmx.config.wsReconnectDelay; 1727 - if (typeof delay === 'function') { 1728 - // @ts-ignore 1729 - return delay(retryCount); 1730 - } 1731 - if (delay === 'full-jitter') { 1732 - var exp = Math.min(retryCount, 6); 1733 - var maxDelay = 1000 * Math.pow(2, exp); 1734 - return maxDelay * Math.random(); 1735 - } 1736 - logError('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"'); 1737 - } 1738 - 1739 - //==================================================================== 1740 - // Server Sent Events 1741 - //==================================================================== 1742 - 1743 - function processSSEInfo(elt, nodeData, info) { 1744 - var values = splitOnWhitespace(info); 1745 - for (var i = 0; i < values.length; i++) { 1746 - var value = values[i].split(/:(.+)/); 1747 - if (value[0] === "connect") { 1748 - processSSESource(elt, value[1]); 1749 - } 1750 - 1751 - if ((value[0] === "swap")) { 1752 - processSSESwap(elt, value[1]) 1753 - } 1754 - } 1755 - } 1756 - 1757 - function processSSESource(elt, sseSrc) { 1758 - var source = htmx.createEventSource(sseSrc); 1759 - source.onerror = function (e) { 1760 - triggerErrorEvent(elt, "htmx:sseError", {error:e, source:source}); 1761 - maybeCloseSSESource(elt); 1762 - }; 1763 - getInternalData(elt).sseEventSource = source; 1764 - } 1765 - 1766 - function processSSESwap(elt, sseEventName) { 1767 - var sseSourceElt = getClosestMatch(elt, hasEventSource); 1768 - if (sseSourceElt) { 1769 - var sseEventSource = getInternalData(sseSourceElt).sseEventSource; 1770 - var sseListener = function (event) { 1771 - if (maybeCloseSSESource(sseSourceElt)) { 1772 - return; 1773 - } 1774 - if (!bodyContains(elt)) { 1775 - sseEventSource.removeEventListener(sseEventName, sseListener); 1776 - return; 1777 - } 1778 - 1779 - /////////////////////////// 1780 - // TODO: merge this code with AJAX and WebSockets code in the future. 1781 - 1782 - var response = event.data; 1783 - withExtensions(elt, function(extension){ 1784 - response = extension.transformResponse(response, null, elt); 1785 - }); 1786 - 1787 - var swapSpec = getSwapSpecification(elt) 1788 - var target = getTarget(elt) 1789 - var settleInfo = makeSettleInfo(elt); 1790 - 1791 - selectAndSwap(swapSpec.swapStyle, target, elt, response, settleInfo) 1792 - settleImmediately(settleInfo.tasks) 1793 - triggerEvent(elt, "htmx:sseMessage", event) 1794 - }; 1795 - 1796 - getInternalData(elt).sseListener = sseListener; 1797 - sseEventSource.addEventListener(sseEventName, sseListener); 1798 - } else { 1799 - triggerErrorEvent(elt, "htmx:noSSESourceError"); 1800 - } 1801 - } 1802 - 1803 - function processSSETrigger(elt, handler, sseEventName) { 1804 - var sseSourceElt = getClosestMatch(elt, hasEventSource); 1805 - if (sseSourceElt) { 1806 - var sseEventSource = getInternalData(sseSourceElt).sseEventSource; 1807 - var sseListener = function () { 1808 - if (!maybeCloseSSESource(sseSourceElt)) { 1809 - if (bodyContains(elt)) { 1810 - handler(elt); 1811 - } else { 1812 - sseEventSource.removeEventListener(sseEventName, sseListener); 1813 - } 1814 - } 1815 - }; 1816 - getInternalData(elt).sseListener = sseListener; 1817 - sseEventSource.addEventListener(sseEventName, sseListener); 1818 - } else { 1819 - triggerErrorEvent(elt, "htmx:noSSESourceError"); 1820 - } 1821 - } 1822 - 1823 - function maybeCloseSSESource(elt) { 1824 - if (!bodyContains(elt)) { 1825 - getInternalData(elt).sseEventSource.close(); 1826 - return true; 1827 - } 1828 - } 1829 - 1830 - function hasEventSource(node) { 1831 - return getInternalData(node).sseEventSource != null; 1832 - } 1833 - 1834 - //==================================================================== 1835 - 1836 - function loadImmediately(elt, handler, nodeData, delay) { 1837 - var load = function(){ 1838 - if (!nodeData.loaded) { 1839 - nodeData.loaded = true; 1840 - handler(elt); 1841 - } 1842 - } 1843 - if (delay > 0) { 1844 - setTimeout(load, delay); 1845 - } else { 1846 - load(); 1847 - } 1848 - } 1849 - 1850 - function processVerbs(elt, nodeData, triggerSpecs) { 1851 - var explicitAction = false; 1852 - forEach(VERBS, function (verb) { 1853 - if (hasAttribute(elt,'hx-' + verb)) { 1854 - var path = getAttributeValue(elt, 'hx-' + verb); 1855 - explicitAction = true; 1856 - nodeData.path = path; 1857 - nodeData.verb = verb; 1858 - triggerSpecs.forEach(function(triggerSpec) { 1859 - addTriggerHandler(elt, triggerSpec, nodeData, function (elt, evt) { 1860 - if (closest(elt, htmx.config.disableSelector)) { 1861 - cleanUpElement(elt) 1862 - return 1863 - } 1864 - issueAjaxRequest(verb, path, elt, evt) 1865 - }) 1866 - }); 1867 - } 1868 - }); 1869 - return explicitAction; 1870 - } 1871 - 1872 - function addTriggerHandler(elt, triggerSpec, nodeData, handler) { 1873 - if (triggerSpec.sseEvent) { 1874 - processSSETrigger(elt, handler, triggerSpec.sseEvent); 1875 - } else if (triggerSpec.trigger === "revealed") { 1876 - initScrollHandler(); 1877 - addEventListener(elt, handler, nodeData, triggerSpec); 1878 - maybeReveal(elt); 1879 - } else if (triggerSpec.trigger === "intersect") { 1880 - var observerOptions = {}; 1881 - if (triggerSpec.root) { 1882 - observerOptions.root = querySelectorExt(elt, triggerSpec.root) 1883 - } 1884 - if (triggerSpec.threshold) { 1885 - observerOptions.threshold = parseFloat(triggerSpec.threshold); 1886 - } 1887 - var observer = new IntersectionObserver(function (entries) { 1888 - for (var i = 0; i < entries.length; i++) { 1889 - var entry = entries[i]; 1890 - if (entry.isIntersecting) { 1891 - triggerEvent(elt, "intersect"); 1892 - break; 1893 - } 1894 - } 1895 - }, observerOptions); 1896 - observer.observe(elt); 1897 - addEventListener(elt, handler, nodeData, triggerSpec); 1898 - } else if (triggerSpec.trigger === "load") { 1899 - if (!maybeFilterEvent(triggerSpec, elt, makeEvent("load", {elt: elt}))) { 1900 - loadImmediately(elt, handler, nodeData, triggerSpec.delay); 1901 - } 1902 - } else if (triggerSpec.pollInterval > 0) { 1903 - nodeData.polling = true; 1904 - processPolling(elt, handler, triggerSpec); 1905 - } else { 1906 - addEventListener(elt, handler, nodeData, triggerSpec); 1907 - } 1908 - } 1909 - 1910 - function evalScript(script) { 1911 - if (!script.htmxExecuted && htmx.config.allowScriptTags && 1912 - (script.type === "text/javascript" || script.type === "module" || script.type === "") ) { 1913 - var newScript = getDocument().createElement("script"); 1914 - forEach(script.attributes, function (attr) { 1915 - newScript.setAttribute(attr.name, attr.value); 1916 - }); 1917 - newScript.textContent = script.textContent; 1918 - newScript.async = false; 1919 - if (htmx.config.inlineScriptNonce) { 1920 - newScript.nonce = htmx.config.inlineScriptNonce; 1921 - } 1922 - var parent = script.parentElement; 1923 - 1924 - try { 1925 - parent.insertBefore(newScript, script); 1926 - } catch (e) { 1927 - logError(e); 1928 - } finally { 1929 - // remove old script element, but only if it is still in DOM 1930 - if (script.parentElement) { 1931 - script.parentElement.removeChild(script); 1932 - } 1933 - } 1934 - } 1935 - } 1936 - 1937 - function processScripts(elt) { 1938 - if (matches(elt, "script")) { 1939 - evalScript(elt); 1940 - } 1941 - forEach(findAll(elt, "script"), function (script) { 1942 - evalScript(script); 1943 - }); 1944 - } 1945 - 1946 - function shouldProcessHxOn(elt) { 1947 - var attributes = elt.attributes 1948 - for (var j = 0; j < attributes.length; j++) { 1949 - var attrName = attributes[j].name 1950 - if (startsWith(attrName, "hx-on:") || startsWith(attrName, "data-hx-on:") || 1951 - startsWith(attrName, "hx-on-") || startsWith(attrName, "data-hx-on-")) { 1952 - return true 1953 - } 1954 - } 1955 - return false 1956 - } 1957 - 1958 - function findHxOnWildcardElements(elt) { 1959 - var node = null 1960 - var elements = [] 1961 - 1962 - if (shouldProcessHxOn(elt)) { 1963 - elements.push(elt) 1964 - } 1965 - 1966 - if (document.evaluate) { 1967 - var iter = document.evaluate('.//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") or' + 1968 - ' starts-with(name(), "hx-on-") or starts-with(name(), "data-hx-on-") ]]', elt) 1969 - while (node = iter.iterateNext()) elements.push(node) 1970 - } else { 1971 - var allElements = elt.getElementsByTagName("*") 1972 - for (var i = 0; i < allElements.length; i++) { 1973 - if (shouldProcessHxOn(allElements[i])) { 1974 - elements.push(allElements[i]) 1975 - } 1976 - } 1977 - } 1978 - 1979 - return elements 1980 - } 1981 - 1982 - function findElementsToProcess(elt) { 1983 - if (elt.querySelectorAll) { 1984 - var boostedSelector = ", [hx-boost] a, [data-hx-boost] a, a[hx-boost], a[data-hx-boost]"; 1985 - var results = elt.querySelectorAll(VERB_SELECTOR + boostedSelector + ", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws]," + 1986 - " [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]"); 1987 - return results; 1988 - } else { 1989 - return []; 1990 - } 1991 - } 1992 - 1993 - // Handle submit buttons/inputs that have the form attribute set 1994 - // see https://developer.mozilla.org/docs/Web/HTML/Element/button 1995 - function maybeSetLastButtonClicked(evt) { 1996 - var elt = closest(evt.target, "button, input[type='submit']"); 1997 - var internalData = getRelatedFormData(evt) 1998 - if (internalData) { 1999 - internalData.lastButtonClicked = elt; 2000 - } 2001 - }; 2002 - function maybeUnsetLastButtonClicked(evt){ 2003 - var internalData = getRelatedFormData(evt) 2004 - if (internalData) { 2005 - internalData.lastButtonClicked = null; 2006 - } 2007 - } 2008 - function getRelatedFormData(evt) { 2009 - var elt = closest(evt.target, "button, input[type='submit']"); 2010 - if (!elt) { 2011 - return; 2012 - } 2013 - var form = resolveTarget('#' + getRawAttribute(elt, 'form')) || closest(elt, 'form'); 2014 - if (!form) { 2015 - return; 2016 - } 2017 - return getInternalData(form); 2018 - } 2019 - function initButtonTracking(elt) { 2020 - // need to handle both click and focus in: 2021 - // focusin - in case someone tabs in to a button and hits the space bar 2022 - // click - on OSX buttons do not focus on click see https://bugs.webkit.org/show_bug.cgi?id=13724 2023 - elt.addEventListener('click', maybeSetLastButtonClicked) 2024 - elt.addEventListener('focusin', maybeSetLastButtonClicked) 2025 - elt.addEventListener('focusout', maybeUnsetLastButtonClicked) 2026 - } 2027 - 2028 - function countCurlies(line) { 2029 - var tokens = tokenizeString(line); 2030 - var netCurlies = 0; 2031 - for (var i = 0; i < tokens.length; i++) { 2032 - const token = tokens[i]; 2033 - if (token === "{") { 2034 - netCurlies++; 2035 - } else if (token === "}") { 2036 - netCurlies--; 2037 - } 2038 - } 2039 - return netCurlies; 2040 - } 2041 - 2042 - function addHxOnEventHandler(elt, eventName, code) { 2043 - var nodeData = getInternalData(elt); 2044 - if (!Array.isArray(nodeData.onHandlers)) { 2045 - nodeData.onHandlers = []; 2046 - } 2047 - var func; 2048 - var listener = function (e) { 2049 - return maybeEval(elt, function() { 2050 - if (!func) { 2051 - func = new Function("event", code); 2052 - } 2053 - func.call(elt, e); 2054 - }); 2055 - }; 2056 - elt.addEventListener(eventName, listener); 2057 - nodeData.onHandlers.push({event:eventName, listener:listener}); 2058 - } 2059 - 2060 - function processHxOn(elt) { 2061 - var hxOnValue = getAttributeValue(elt, 'hx-on'); 2062 - if (hxOnValue) { 2063 - var handlers = {} 2064 - var lines = hxOnValue.split("\n"); 2065 - var currentEvent = null; 2066 - var curlyCount = 0; 2067 - while (lines.length > 0) { 2068 - var line = lines.shift(); 2069 - var match = line.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/); 2070 - if (curlyCount === 0 && match) { 2071 - line.split(":") 2072 - currentEvent = match[1].slice(0, -1); // strip last colon 2073 - handlers[currentEvent] = match[2]; 2074 - } else { 2075 - handlers[currentEvent] += line; 2076 - } 2077 - curlyCount += countCurlies(line); 2078 - } 2079 - 2080 - for (var eventName in handlers) { 2081 - addHxOnEventHandler(elt, eventName, handlers[eventName]); 2082 - } 2083 - } 2084 - } 2085 - 2086 - function processHxOnWildcard(elt) { 2087 - // wipe any previous on handlers so that this function takes precedence 2088 - deInitOnHandlers(elt) 2089 - 2090 - for (var i = 0; i < elt.attributes.length; i++) { 2091 - var name = elt.attributes[i].name 2092 - var value = elt.attributes[i].value 2093 - if (startsWith(name, "hx-on") || startsWith(name, "data-hx-on")) { 2094 - var afterOnPosition = name.indexOf("-on") + 3; 2095 - var nextChar = name.slice(afterOnPosition, afterOnPosition + 1); 2096 - if (nextChar === "-" || nextChar === ":") { 2097 - var eventName = name.slice(afterOnPosition + 1); 2098 - // if the eventName starts with a colon or dash, prepend "htmx" for shorthand support 2099 - if (startsWith(eventName, ":")) { 2100 - eventName = "htmx" + eventName 2101 - } else if (startsWith(eventName, "-")) { 2102 - eventName = "htmx:" + eventName.slice(1); 2103 - } else if (startsWith(eventName, "htmx-")) { 2104 - eventName = "htmx:" + eventName.slice(5); 2105 - } 2106 - 2107 - addHxOnEventHandler(elt, eventName, value) 2108 - } 2109 - } 2110 - } 2111 - } 2112 - 2113 - function initNode(elt) { 2114 - if (closest(elt, htmx.config.disableSelector)) { 2115 - cleanUpElement(elt) 2116 - return; 2117 - } 2118 - var nodeData = getInternalData(elt); 2119 - if (nodeData.initHash !== attributeHash(elt)) { 2120 - // clean up any previously processed info 2121 - deInitNode(elt); 2122 - 2123 - nodeData.initHash = attributeHash(elt); 2124 - 2125 - processHxOn(elt); 2126 - 2127 - triggerEvent(elt, "htmx:beforeProcessNode") 2128 - 2129 - if (elt.value) { 2130 - nodeData.lastValue = elt.value; 2131 - } 2132 - 2133 - var triggerSpecs = getTriggerSpecs(elt); 2134 - var hasExplicitHttpAction = processVerbs(elt, nodeData, triggerSpecs); 2135 - 2136 - if (!hasExplicitHttpAction) { 2137 - if (getClosestAttributeValue(elt, "hx-boost") === "true") { 2138 - boostElement(elt, nodeData, triggerSpecs); 2139 - } else if (hasAttribute(elt, 'hx-trigger')) { 2140 - triggerSpecs.forEach(function (triggerSpec) { 2141 - // For "naked" triggers, don't do anything at all 2142 - addTriggerHandler(elt, triggerSpec, nodeData, function () { 2143 - }) 2144 - }) 2145 - } 2146 - } 2147 - 2148 - // Handle submit buttons/inputs that have the form attribute set 2149 - // see https://developer.mozilla.org/docs/Web/HTML/Element/button 2150 - if (elt.tagName === "FORM" || (getRawAttribute(elt, "type") === "submit" && hasAttribute(elt, "form"))) { 2151 - initButtonTracking(elt) 2152 - } 2153 - 2154 - var sseInfo = getAttributeValue(elt, 'hx-sse'); 2155 - if (sseInfo) { 2156 - processSSEInfo(elt, nodeData, sseInfo); 2157 - } 2158 - 2159 - var wsInfo = getAttributeValue(elt, 'hx-ws'); 2160 - if (wsInfo) { 2161 - processWebSocketInfo(elt, nodeData, wsInfo); 2162 - } 2163 - triggerEvent(elt, "htmx:afterProcessNode"); 2164 - } 2165 - } 2166 - 2167 - function processNode(elt) { 2168 - elt = resolveTarget(elt); 2169 - if (closest(elt, htmx.config.disableSelector)) { 2170 - cleanUpElement(elt) 2171 - return; 2172 - } 2173 - initNode(elt); 2174 - forEach(findElementsToProcess(elt), function(child) { initNode(child) }); 2175 - // Because it happens second, the new way of adding onHandlers superseeds the old one 2176 - // i.e. if there are any hx-on:eventName attributes, the hx-on attribute will be ignored 2177 - forEach(findHxOnWildcardElements(elt), processHxOnWildcard); 2178 - } 2179 - 2180 - //==================================================================== 2181 - // Event/Log Support 2182 - //==================================================================== 2183 - 2184 - function kebabEventName(str) { 2185 - return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); 2186 - } 2187 - 2188 - function makeEvent(eventName, detail) { 2189 - var evt; 2190 - if (window.CustomEvent && typeof window.CustomEvent === 'function') { 2191 - evt = new CustomEvent(eventName, {bubbles: true, cancelable: true, detail: detail}); 2192 - } else { 2193 - evt = getDocument().createEvent('CustomEvent'); 2194 - evt.initCustomEvent(eventName, true, true, detail); 2195 - } 2196 - return evt; 2197 - } 2198 - 2199 - function triggerErrorEvent(elt, eventName, detail) { 2200 - triggerEvent(elt, eventName, mergeObjects({error:eventName}, detail)); 2201 - } 2202 - 2203 - function ignoreEventForLogging(eventName) { 2204 - return eventName === "htmx:afterProcessNode" 2205 - } 2206 - 2207 - /** 2208 - * `withExtensions` locates all active extensions for a provided element, then 2209 - * executes the provided function using each of the active extensions. It should 2210 - * be called internally at every extendable execution point in htmx. 2211 - * 2212 - * @param {HTMLElement} elt 2213 - * @param {(extension:import("./htmx").HtmxExtension) => void} toDo 2214 - * @returns void 2215 - */ 2216 - function withExtensions(elt, toDo) { 2217 - forEach(getExtensions(elt), function(extension){ 2218 - try { 2219 - toDo(extension); 2220 - } catch (e) { 2221 - logError(e); 2222 - } 2223 - }); 2224 - } 2225 - 2226 - function logError(msg) { 2227 - if(console.error) { 2228 - console.error(msg); 2229 - } else if (console.log) { 2230 - console.log("ERROR: ", msg); 2231 - } 2232 - } 2233 - 2234 - function triggerEvent(elt, eventName, detail) { 2235 - elt = resolveTarget(elt); 2236 - if (detail == null) { 2237 - detail = {}; 2238 - } 2239 - detail["elt"] = elt; 2240 - var event = makeEvent(eventName, detail); 2241 - if (htmx.logger && !ignoreEventForLogging(eventName)) { 2242 - htmx.logger(elt, eventName, detail); 2243 - } 2244 - if (detail.error) { 2245 - logError(detail.error); 2246 - triggerEvent(elt, "htmx:error", {errorInfo:detail}) 2247 - } 2248 - var eventResult = elt.dispatchEvent(event); 2249 - var kebabName = kebabEventName(eventName); 2250 - if (eventResult && kebabName !== eventName) { 2251 - var kebabedEvent = makeEvent(kebabName, event.detail); 2252 - eventResult = eventResult && elt.dispatchEvent(kebabedEvent) 2253 - } 2254 - withExtensions(elt, function (extension) { 2255 - eventResult = eventResult && (extension.onEvent(eventName, event) !== false && !event.defaultPrevented) 2256 - }); 2257 - return eventResult; 2258 - } 2259 - 2260 - //==================================================================== 2261 - // History Support 2262 - //==================================================================== 2263 - var currentPathForHistory = location.pathname+location.search; 2264 - 2265 - function getHistoryElement() { 2266 - var historyElt = getDocument().querySelector('[hx-history-elt],[data-hx-history-elt]'); 2267 - return historyElt || getDocument().body; 2268 - } 2269 - 2270 - function saveToHistoryCache(url, content, title, scroll) { 2271 - if (!canAccessLocalStorage()) { 2272 - return; 2273 - } 2274 - 2275 - if (htmx.config.historyCacheSize <= 0) { 2276 - // make sure that an eventually already existing cache is purged 2277 - localStorage.removeItem("htmx-history-cache"); 2278 - return; 2279 - } 2280 - 2281 - url = normalizePath(url); 2282 - 2283 - var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || []; 2284 - for (var i = 0; i < historyCache.length; i++) { 2285 - if (historyCache[i].url === url) { 2286 - historyCache.splice(i, 1); 2287 - break; 2288 - } 2289 - } 2290 - var newHistoryItem = {url:url, content: content, title:title, scroll:scroll}; 2291 - triggerEvent(getDocument().body, "htmx:historyItemCreated", {item:newHistoryItem, cache: historyCache}) 2292 - historyCache.push(newHistoryItem) 2293 - while (historyCache.length > htmx.config.historyCacheSize) { 2294 - historyCache.shift(); 2295 - } 2296 - while(historyCache.length > 0){ 2297 - try { 2298 - localStorage.setItem("htmx-history-cache", JSON.stringify(historyCache)); 2299 - break; 2300 - } catch (e) { 2301 - triggerErrorEvent(getDocument().body, "htmx:historyCacheError", {cause:e, cache: historyCache}) 2302 - historyCache.shift(); // shrink the cache and retry 2303 - } 2304 - } 2305 - } 2306 - 2307 - function getCachedHistory(url) { 2308 - if (!canAccessLocalStorage()) { 2309 - return null; 2310 - } 2311 - 2312 - url = normalizePath(url); 2313 - 2314 - var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || []; 2315 - for (var i = 0; i < historyCache.length; i++) { 2316 - if (historyCache[i].url === url) { 2317 - return historyCache[i]; 2318 - } 2319 - } 2320 - return null; 2321 - } 2322 - 2323 - function cleanInnerHtmlForHistory(elt) { 2324 - var className = htmx.config.requestClass; 2325 - var clone = elt.cloneNode(true); 2326 - forEach(findAll(clone, "." + className), function(child){ 2327 - removeClassFromElement(child, className); 2328 - }); 2329 - return clone.innerHTML; 2330 - } 2331 - 2332 - function saveCurrentPageToHistory() { 2333 - var elt = getHistoryElement(); 2334 - var path = currentPathForHistory || location.pathname+location.search; 2335 - 2336 - // Allow history snapshot feature to be disabled where hx-history="false" 2337 - // is present *anywhere* in the current document we're about to save, 2338 - // so we can prevent privileged data entering the cache. 2339 - // The page will still be reachable as a history entry, but htmx will fetch it 2340 - // live from the server onpopstate rather than look in the localStorage cache 2341 - var disableHistoryCache 2342 - try { 2343 - disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]') 2344 - } catch (e) { 2345 - // IE11: insensitive modifier not supported so fallback to case sensitive selector 2346 - disableHistoryCache = getDocument().querySelector('[hx-history="false"],[data-hx-history="false"]') 2347 - } 2348 - if (!disableHistoryCache) { 2349 - triggerEvent(getDocument().body, "htmx:beforeHistorySave", {path: path, historyElt: elt}); 2350 - saveToHistoryCache(path, cleanInnerHtmlForHistory(elt), getDocument().title, window.scrollY); 2351 - } 2352 - 2353 - if (htmx.config.historyEnabled) history.replaceState({htmx: true}, getDocument().title, window.location.href); 2354 - } 2355 - 2356 - function pushUrlIntoHistory(path) { 2357 - // remove the cache buster parameter, if any 2358 - if (htmx.config.getCacheBusterParam) { 2359 - path = path.replace(/org\.htmx\.cache-buster=[^&]*&?/, '') 2360 - if (endsWith(path, '&') || endsWith(path, "?")) { 2361 - path = path.slice(0, -1); 2362 - } 2363 - } 2364 - if(htmx.config.historyEnabled) { 2365 - history.pushState({htmx:true}, "", path); 2366 - } 2367 - currentPathForHistory = path; 2368 - } 2369 - 2370 - function replaceUrlInHistory(path) { 2371 - if(htmx.config.historyEnabled) history.replaceState({htmx:true}, "", path); 2372 - currentPathForHistory = path; 2373 - } 2374 - 2375 - function settleImmediately(tasks) { 2376 - forEach(tasks, function (task) { 2377 - task.call(); 2378 - }); 2379 - } 2380 - 2381 - function loadHistoryFromServer(path) { 2382 - var request = new XMLHttpRequest(); 2383 - var details = {path: path, xhr:request}; 2384 - triggerEvent(getDocument().body, "htmx:historyCacheMiss", details); 2385 - request.open('GET', path, true); 2386 - request.setRequestHeader("HX-Request", "true"); 2387 - request.setRequestHeader("HX-History-Restore-Request", "true"); 2388 - request.setRequestHeader("HX-Current-URL", getDocument().location.href); 2389 - request.onload = function () { 2390 - if (this.status >= 200 && this.status < 400) { 2391 - triggerEvent(getDocument().body, "htmx:historyCacheMissLoad", details); 2392 - var fragment = makeFragment(this.response); 2393 - // @ts-ignore 2394 - fragment = fragment.querySelector('[hx-history-elt],[data-hx-history-elt]') || fragment; 2395 - var historyElement = getHistoryElement(); 2396 - var settleInfo = makeSettleInfo(historyElement); 2397 - var title = findTitle(this.response); 2398 - if (title) { 2399 - var titleElt = find("title"); 2400 - if (titleElt) { 2401 - titleElt.innerHTML = title; 2402 - } else { 2403 - window.document.title = title; 2404 - } 2405 - } 2406 - // @ts-ignore 2407 - swapInnerHTML(historyElement, fragment, settleInfo) 2408 - settleImmediately(settleInfo.tasks); 2409 - currentPathForHistory = path; 2410 - triggerEvent(getDocument().body, "htmx:historyRestore", {path: path, cacheMiss:true, serverResponse:this.response}); 2411 - } else { 2412 - triggerErrorEvent(getDocument().body, "htmx:historyCacheMissLoadError", details); 2413 - } 2414 - }; 2415 - request.send(); 2416 - } 2417 - 2418 - function restoreHistory(path) { 2419 - saveCurrentPageToHistory(); 2420 - path = path || location.pathname+location.search; 2421 - var cached = getCachedHistory(path); 2422 - if (cached) { 2423 - var fragment = makeFragment(cached.content); 2424 - var historyElement = getHistoryElement(); 2425 - var settleInfo = makeSettleInfo(historyElement); 2426 - swapInnerHTML(historyElement, fragment, settleInfo) 2427 - settleImmediately(settleInfo.tasks); 2428 - document.title = cached.title; 2429 - setTimeout(function () { 2430 - window.scrollTo(0, cached.scroll); 2431 - }, 0); // next 'tick', so browser has time to render layout 2432 - currentPathForHistory = path; 2433 - triggerEvent(getDocument().body, "htmx:historyRestore", {path:path, item:cached}); 2434 - } else { 2435 - if (htmx.config.refreshOnHistoryMiss) { 2436 - 2437 - // @ts-ignore: optional parameter in reload() function throws error 2438 - window.location.reload(true); 2439 - } else { 2440 - loadHistoryFromServer(path); 2441 - } 2442 - } 2443 - } 2444 - 2445 - function addRequestIndicatorClasses(elt) { 2446 - var indicators = findAttributeTargets(elt, 'hx-indicator'); 2447 - if (indicators == null) { 2448 - indicators = [elt]; 2449 - } 2450 - forEach(indicators, function (ic) { 2451 - var internalData = getInternalData(ic); 2452 - internalData.requestCount = (internalData.requestCount || 0) + 1; 2453 - ic.classList["add"].call(ic.classList, htmx.config.requestClass); 2454 - }); 2455 - return indicators; 2456 - } 2457 - 2458 - function disableElements(elt) { 2459 - var disabledElts = findAttributeTargets(elt, 'hx-disabled-elt'); 2460 - if (disabledElts == null) { 2461 - disabledElts = []; 2462 - } 2463 - forEach(disabledElts, function (disabledElement) { 2464 - var internalData = getInternalData(disabledElement); 2465 - internalData.requestCount = (internalData.requestCount || 0) + 1; 2466 - disabledElement.setAttribute("disabled", ""); 2467 - }); 2468 - return disabledElts; 2469 - } 2470 - 2471 - function removeRequestIndicators(indicators, disabled) { 2472 - forEach(indicators, function (ic) { 2473 - var internalData = getInternalData(ic); 2474 - internalData.requestCount = (internalData.requestCount || 0) - 1; 2475 - if (internalData.requestCount === 0) { 2476 - ic.classList["remove"].call(ic.classList, htmx.config.requestClass); 2477 - } 2478 - }); 2479 - forEach(disabled, function (disabledElement) { 2480 - var internalData = getInternalData(disabledElement); 2481 - internalData.requestCount = (internalData.requestCount || 0) - 1; 2482 - if (internalData.requestCount === 0) { 2483 - disabledElement.removeAttribute('disabled'); 2484 - } 2485 - }); 2486 - } 2487 - 2488 - //==================================================================== 2489 - // Input Value Processing 2490 - //==================================================================== 2491 - 2492 - function haveSeenNode(processed, elt) { 2493 - for (var i = 0; i < processed.length; i++) { 2494 - var node = processed[i]; 2495 - if (node.isSameNode(elt)) { 2496 - return true; 2497 - } 2498 - } 2499 - return false; 2500 - } 2501 - 2502 - function shouldInclude(elt) { 2503 - if(elt.name === "" || elt.name == null || elt.disabled || closest(elt, "fieldset[disabled]")) { 2504 - return false; 2505 - } 2506 - // ignore "submitter" types (see jQuery src/serialize.js) 2507 - if (elt.type === "button" || elt.type === "submit" || elt.tagName === "image" || elt.tagName === "reset" || elt.tagName === "file" ) { 2508 - return false; 2509 - } 2510 - if (elt.type === "checkbox" || elt.type === "radio" ) { 2511 - return elt.checked; 2512 - } 2513 - return true; 2514 - } 2515 - 2516 - function addValueToValues(name, value, values) { 2517 - // This is a little ugly because both the current value of the named value in the form 2518 - // and the new value could be arrays, so we have to handle all four cases :/ 2519 - if (name != null && value != null) { 2520 - var current = values[name]; 2521 - if (current === undefined) { 2522 - values[name] = value; 2523 - } else if (Array.isArray(current)) { 2524 - if (Array.isArray(value)) { 2525 - values[name] = current.concat(value); 2526 - } else { 2527 - current.push(value); 2528 - } 2529 - } else { 2530 - if (Array.isArray(value)) { 2531 - values[name] = [current].concat(value); 2532 - } else { 2533 - values[name] = [current, value]; 2534 - } 2535 - } 2536 - } 2537 - } 2538 - 2539 - function processInputValue(processed, values, errors, elt, validate) { 2540 - if (elt == null || haveSeenNode(processed, elt)) { 2541 - return; 2542 - } else { 2543 - processed.push(elt); 2544 - } 2545 - if (shouldInclude(elt)) { 2546 - var name = getRawAttribute(elt,"name"); 2547 - var value = elt.value; 2548 - if (elt.multiple && elt.tagName === "SELECT") { 2549 - value = toArray(elt.querySelectorAll("option:checked")).map(function (e) { return e.value }); 2550 - } 2551 - // include file inputs 2552 - if (elt.files) { 2553 - value = toArray(elt.files); 2554 - } 2555 - addValueToValues(name, value, values); 2556 - if (validate) { 2557 - validateElement(elt, errors); 2558 - } 2559 - } 2560 - if (matches(elt, 'form')) { 2561 - var inputs = elt.elements; 2562 - forEach(inputs, function(input) { 2563 - processInputValue(processed, values, errors, input, validate); 2564 - }); 2565 - } 2566 - } 2567 - 2568 - function validateElement(element, errors) { 2569 - if (element.willValidate) { 2570 - triggerEvent(element, "htmx:validation:validate") 2571 - if (!element.checkValidity()) { 2572 - errors.push({elt: element, message:element.validationMessage, validity:element.validity}); 2573 - triggerEvent(element, "htmx:validation:failed", {message:element.validationMessage, validity:element.validity}) 2574 - } 2575 - } 2576 - } 2577 - 2578 - /** 2579 - * @param {HTMLElement} elt 2580 - * @param {string} verb 2581 - */ 2582 - function getInputValues(elt, verb) { 2583 - var processed = []; 2584 - var values = {}; 2585 - var formValues = {}; 2586 - var errors = []; 2587 - var internalData = getInternalData(elt); 2588 - if (internalData.lastButtonClicked && !bodyContains(internalData.lastButtonClicked)) { 2589 - internalData.lastButtonClicked = null 2590 - } 2591 - 2592 - // only validate when form is directly submitted and novalidate or formnovalidate are not set 2593 - // or if the element has an explicit hx-validate="true" on it 2594 - var validate = (matches(elt, 'form') && elt.noValidate !== true) || getAttributeValue(elt, "hx-validate") === "true"; 2595 - if (internalData.lastButtonClicked) { 2596 - validate = validate && internalData.lastButtonClicked.formNoValidate !== true; 2597 - } 2598 - 2599 - // for a non-GET include the closest form 2600 - if (verb !== 'get') { 2601 - processInputValue(processed, formValues, errors, closest(elt, 'form'), validate); 2602 - } 2603 - 2604 - // include the element itself 2605 - processInputValue(processed, values, errors, elt, validate); 2606 - 2607 - // if a button or submit was clicked last, include its value 2608 - if (internalData.lastButtonClicked || elt.tagName === "BUTTON" || 2609 - (elt.tagName === "INPUT" && getRawAttribute(elt, "type") === "submit")) { 2610 - var button = internalData.lastButtonClicked || elt 2611 - var name = getRawAttribute(button, "name") 2612 - addValueToValues(name, button.value, formValues) 2613 - } 2614 - 2615 - // include any explicit includes 2616 - var includes = findAttributeTargets(elt, "hx-include"); 2617 - forEach(includes, function(node) { 2618 - processInputValue(processed, values, errors, node, validate); 2619 - // if a non-form is included, include any input values within it 2620 - if (!matches(node, 'form')) { 2621 - forEach(node.querySelectorAll(INPUT_SELECTOR), function (descendant) { 2622 - processInputValue(processed, values, errors, descendant, validate); 2623 - }) 2624 - } 2625 - }); 2626 - 2627 - // form values take precedence, overriding the regular values 2628 - values = mergeObjects(values, formValues); 2629 - 2630 - return {errors:errors, values:values}; 2631 - } 2632 - 2633 - function appendParam(returnStr, name, realValue) { 2634 - if (returnStr !== "") { 2635 - returnStr += "&"; 2636 - } 2637 - if (String(realValue) === "[object Object]") { 2638 - realValue = JSON.stringify(realValue); 2639 - } 2640 - var s = encodeURIComponent(realValue); 2641 - returnStr += encodeURIComponent(name) + "=" + s; 2642 - return returnStr; 2643 - } 2644 - 2645 - function urlEncode(values) { 2646 - var returnStr = ""; 2647 - for (var name in values) { 2648 - if (values.hasOwnProperty(name)) { 2649 - var value = values[name]; 2650 - if (Array.isArray(value)) { 2651 - forEach(value, function(v) { 2652 - returnStr = appendParam(returnStr, name, v); 2653 - }); 2654 - } else { 2655 - returnStr = appendParam(returnStr, name, value); 2656 - } 2657 - } 2658 - } 2659 - return returnStr; 2660 - } 2661 - 2662 - function makeFormData(values) { 2663 - var formData = new FormData(); 2664 - for (var name in values) { 2665 - if (values.hasOwnProperty(name)) { 2666 - var value = values[name]; 2667 - if (Array.isArray(value)) { 2668 - forEach(value, function(v) { 2669 - formData.append(name, v); 2670 - }); 2671 - } else { 2672 - formData.append(name, value); 2673 - } 2674 - } 2675 - } 2676 - return formData; 2677 - } 2678 - 2679 - //==================================================================== 2680 - // Ajax 2681 - //==================================================================== 2682 - 2683 - /** 2684 - * @param {HTMLElement} elt 2685 - * @param {HTMLElement} target 2686 - * @param {string} prompt 2687 - * @returns {Object} // TODO: Define/Improve HtmxHeaderSpecification 2688 - */ 2689 - function getHeaders(elt, target, prompt) { 2690 - var headers = { 2691 - "HX-Request" : "true", 2692 - "HX-Trigger" : getRawAttribute(elt, "id"), 2693 - "HX-Trigger-Name" : getRawAttribute(elt, "name"), 2694 - "HX-Target" : getAttributeValue(target, "id"), 2695 - "HX-Current-URL" : getDocument().location.href, 2696 - } 2697 - getValuesForElement(elt, "hx-headers", false, headers) 2698 - if (prompt !== undefined) { 2699 - headers["HX-Prompt"] = prompt; 2700 - } 2701 - if (getInternalData(elt).boosted) { 2702 - headers["HX-Boosted"] = "true"; 2703 - } 2704 - return headers; 2705 - } 2706 - 2707 - /** 2708 - * filterValues takes an object containing form input values 2709 - * and returns a new object that only contains keys that are 2710 - * specified by the closest "hx-params" attribute 2711 - * @param {Object} inputValues 2712 - * @param {HTMLElement} elt 2713 - * @returns {Object} 2714 - */ 2715 - function filterValues(inputValues, elt) { 2716 - var paramsValue = getClosestAttributeValue(elt, "hx-params"); 2717 - if (paramsValue) { 2718 - if (paramsValue === "none") { 2719 - return {}; 2720 - } else if (paramsValue === "*") { 2721 - return inputValues; 2722 - } else if(paramsValue.indexOf("not ") === 0) { 2723 - forEach(paramsValue.substr(4).split(","), function (name) { 2724 - name = name.trim(); 2725 - delete inputValues[name]; 2726 - }); 2727 - return inputValues; 2728 - } else { 2729 - var newValues = {} 2730 - forEach(paramsValue.split(","), function (name) { 2731 - name = name.trim(); 2732 - newValues[name] = inputValues[name]; 2733 - }); 2734 - return newValues; 2735 - } 2736 - } else { 2737 - return inputValues; 2738 - } 2739 - } 2740 - 2741 - function isAnchorLink(elt) { 2742 - return getRawAttribute(elt, 'href') && getRawAttribute(elt, 'href').indexOf("#") >=0 2743 - } 2744 - 2745 - /** 2746 - * 2747 - * @param {HTMLElement} elt 2748 - * @param {string} swapInfoOverride 2749 - * @returns {import("./htmx").HtmxSwapSpecification} 2750 - */ 2751 - function getSwapSpecification(elt, swapInfoOverride) { 2752 - var swapInfo = swapInfoOverride ? swapInfoOverride : getClosestAttributeValue(elt, "hx-swap"); 2753 - var swapSpec = { 2754 - "swapStyle" : getInternalData(elt).boosted ? 'innerHTML' : htmx.config.defaultSwapStyle, 2755 - "swapDelay" : htmx.config.defaultSwapDelay, 2756 - "settleDelay" : htmx.config.defaultSettleDelay 2757 - } 2758 - if (htmx.config.scrollIntoViewOnBoost && getInternalData(elt).boosted && !isAnchorLink(elt)) { 2759 - swapSpec["show"] = "top" 2760 - } 2761 - if (swapInfo) { 2762 - var split = splitOnWhitespace(swapInfo); 2763 - if (split.length > 0) { 2764 - for (var i = 0; i < split.length; i++) { 2765 - var value = split[i]; 2766 - if (value.indexOf("swap:") === 0) { 2767 - swapSpec["swapDelay"] = parseInterval(value.substr(5)); 2768 - } else if (value.indexOf("settle:") === 0) { 2769 - swapSpec["settleDelay"] = parseInterval(value.substr(7)); 2770 - } else if (value.indexOf("transition:") === 0) { 2771 - swapSpec["transition"] = value.substr(11) === "true"; 2772 - } else if (value.indexOf("ignoreTitle:") === 0) { 2773 - swapSpec["ignoreTitle"] = value.substr(12) === "true"; 2774 - } else if (value.indexOf("scroll:") === 0) { 2775 - var scrollSpec = value.substr(7); 2776 - var splitSpec = scrollSpec.split(":"); 2777 - var scrollVal = splitSpec.pop(); 2778 - var selectorVal = splitSpec.length > 0 ? splitSpec.join(":") : null; 2779 - swapSpec["scroll"] = scrollVal; 2780 - swapSpec["scrollTarget"] = selectorVal; 2781 - } else if (value.indexOf("show:") === 0) { 2782 - var showSpec = value.substr(5); 2783 - var splitSpec = showSpec.split(":"); 2784 - var showVal = splitSpec.pop(); 2785 - var selectorVal = splitSpec.length > 0 ? splitSpec.join(":") : null; 2786 - swapSpec["show"] = showVal; 2787 - swapSpec["showTarget"] = selectorVal; 2788 - } else if (value.indexOf("focus-scroll:") === 0) { 2789 - var focusScrollVal = value.substr("focus-scroll:".length); 2790 - swapSpec["focusScroll"] = focusScrollVal == "true"; 2791 - } else if (i == 0) { 2792 - swapSpec["swapStyle"] = value; 2793 - } else { 2794 - logError('Unknown modifier in hx-swap: ' + value); 2795 - } 2796 - } 2797 - } 2798 - } 2799 - return swapSpec; 2800 - } 2801 - 2802 - function usesFormData(elt) { 2803 - return getClosestAttributeValue(elt, "hx-encoding") === "multipart/form-data" || 2804 - (matches(elt, "form") && getRawAttribute(elt, 'enctype') === "multipart/form-data"); 2805 - } 2806 - 2807 - function encodeParamsForBody(xhr, elt, filteredParameters) { 2808 - var encodedParameters = null; 2809 - withExtensions(elt, function (extension) { 2810 - if (encodedParameters == null) { 2811 - encodedParameters = extension.encodeParameters(xhr, filteredParameters, elt); 2812 - } 2813 - }); 2814 - if (encodedParameters != null) { 2815 - return encodedParameters; 2816 - } else { 2817 - if (usesFormData(elt)) { 2818 - return makeFormData(filteredParameters); 2819 - } else { 2820 - return urlEncode(filteredParameters); 2821 - } 2822 - } 2823 - } 2824 - 2825 - /** 2826 - * 2827 - * @param {Element} target 2828 - * @returns {import("./htmx").HtmxSettleInfo} 2829 - */ 2830 - function makeSettleInfo(target) { 2831 - return {tasks: [], elts: [target]}; 2832 - } 2833 - 2834 - function updateScrollState(content, swapSpec) { 2835 - var first = content[0]; 2836 - var last = content[content.length - 1]; 2837 - if (swapSpec.scroll) { 2838 - var target = null; 2839 - if (swapSpec.scrollTarget) { 2840 - target = querySelectorExt(first, swapSpec.scrollTarget); 2841 - } 2842 - if (swapSpec.scroll === "top" && (first || target)) { 2843 - target = target || first; 2844 - target.scrollTop = 0; 2845 - } 2846 - if (swapSpec.scroll === "bottom" && (last || target)) { 2847 - target = target || last; 2848 - target.scrollTop = target.scrollHeight; 2849 - } 2850 - } 2851 - if (swapSpec.show) { 2852 - var target = null; 2853 - if (swapSpec.showTarget) { 2854 - var targetStr = swapSpec.showTarget; 2855 - if (swapSpec.showTarget === "window") { 2856 - targetStr = "body"; 2857 - } 2858 - target = querySelectorExt(first, targetStr); 2859 - } 2860 - if (swapSpec.show === "top" && (first || target)) { 2861 - target = target || first; 2862 - target.scrollIntoView({block:'start', behavior: htmx.config.scrollBehavior}); 2863 - } 2864 - if (swapSpec.show === "bottom" && (last || target)) { 2865 - target = target || last; 2866 - target.scrollIntoView({block:'end', behavior: htmx.config.scrollBehavior}); 2867 - } 2868 - } 2869 - } 2870 - 2871 - /** 2872 - * @param {HTMLElement} elt 2873 - * @param {string} attr 2874 - * @param {boolean=} evalAsDefault 2875 - * @param {Object=} values 2876 - * @returns {Object} 2877 - */ 2878 - function getValuesForElement(elt, attr, evalAsDefault, values) { 2879 - if (values == null) { 2880 - values = {}; 2881 - } 2882 - if (elt == null) { 2883 - return values; 2884 - } 2885 - var attributeValue = getAttributeValue(elt, attr); 2886 - if (attributeValue) { 2887 - var str = attributeValue.trim(); 2888 - var evaluateValue = evalAsDefault; 2889 - if (str === "unset") { 2890 - return null; 2891 - } 2892 - if (str.indexOf("javascript:") === 0) { 2893 - str = str.substr(11); 2894 - evaluateValue = true; 2895 - } else if (str.indexOf("js:") === 0) { 2896 - str = str.substr(3); 2897 - evaluateValue = true; 2898 - } 2899 - if (str.indexOf('{') !== 0) { 2900 - str = "{" + str + "}"; 2901 - } 2902 - var varsValues; 2903 - if (evaluateValue) { 2904 - varsValues = maybeEval(elt,function () {return Function("return (" + str + ")")();}, {}); 2905 - } else { 2906 - varsValues = parseJSON(str); 2907 - } 2908 - for (var key in varsValues) { 2909 - if (varsValues.hasOwnProperty(key)) { 2910 - if (values[key] == null) { 2911 - values[key] = varsValues[key]; 2912 - } 2913 - } 2914 - } 2915 - } 2916 - return getValuesForElement(parentElt(elt), attr, evalAsDefault, values); 2917 - } 2918 - 2919 - function maybeEval(elt, toEval, defaultVal) { 2920 - if (htmx.config.allowEval) { 2921 - return toEval(); 2922 - } else { 2923 - triggerErrorEvent(elt, 'htmx:evalDisallowedError'); 2924 - return defaultVal; 2925 - } 2926 - } 2927 - 2928 - /** 2929 - * @param {HTMLElement} elt 2930 - * @param {*} expressionVars 2931 - * @returns 2932 - */ 2933 - function getHXVarsForElement(elt, expressionVars) { 2934 - return getValuesForElement(elt, "hx-vars", true, expressionVars); 2935 - } 2936 - 2937 - /** 2938 - * @param {HTMLElement} elt 2939 - * @param {*} expressionVars 2940 - * @returns 2941 - */ 2942 - function getHXValsForElement(elt, expressionVars) { 2943 - return getValuesForElement(elt, "hx-vals", false, expressionVars); 2944 - } 2945 - 2946 - /** 2947 - * @param {HTMLElement} elt 2948 - * @returns {Object} 2949 - */ 2950 - function getExpressionVars(elt) { 2951 - return mergeObjects(getHXVarsForElement(elt), getHXValsForElement(elt)); 2952 - } 2953 - 2954 - function safelySetHeaderValue(xhr, header, headerValue) { 2955 - if (headerValue !== null) { 2956 - try { 2957 - xhr.setRequestHeader(header, headerValue); 2958 - } catch (e) { 2959 - // On an exception, try to set the header URI encoded instead 2960 - xhr.setRequestHeader(header, encodeURIComponent(headerValue)); 2961 - xhr.setRequestHeader(header + "-URI-AutoEncoded", "true"); 2962 - } 2963 - } 2964 - } 2965 - 2966 - function getPathFromResponse(xhr) { 2967 - // NB: IE11 does not support this stuff 2968 - if (xhr.responseURL && typeof(URL) !== "undefined") { 2969 - try { 2970 - var url = new URL(xhr.responseURL); 2971 - return url.pathname + url.search; 2972 - } catch (e) { 2973 - triggerErrorEvent(getDocument().body, "htmx:badResponseUrl", {url: xhr.responseURL}); 2974 - } 2975 - } 2976 - } 2977 - 2978 - function hasHeader(xhr, regexp) { 2979 - return regexp.test(xhr.getAllResponseHeaders()) 2980 - } 2981 - 2982 - function ajaxHelper(verb, path, context) { 2983 - verb = verb.toLowerCase(); 2984 - if (context) { 2985 - if (context instanceof Element || isType(context, 'String')) { 2986 - return issueAjaxRequest(verb, path, null, null, { 2987 - targetOverride: resolveTarget(context), 2988 - returnPromise: true 2989 - }); 2990 - } else { 2991 - return issueAjaxRequest(verb, path, resolveTarget(context.source), context.event, 2992 - { 2993 - handler : context.handler, 2994 - headers : context.headers, 2995 - values : context.values, 2996 - targetOverride: resolveTarget(context.target), 2997 - swapOverride: context.swap, 2998 - select: context.select, 2999 - returnPromise: true 3000 - }); 3001 - } 3002 - } else { 3003 - return issueAjaxRequest(verb, path, null, null, { 3004 - returnPromise: true 3005 - }); 3006 - } 3007 - } 3008 - 3009 - function hierarchyForElt(elt) { 3010 - var arr = []; 3011 - while (elt) { 3012 - arr.push(elt); 3013 - elt = elt.parentElement; 3014 - } 3015 - return arr; 3016 - } 3017 - 3018 - function verifyPath(elt, path, requestConfig) { 3019 - var sameHost 3020 - var url 3021 - if (typeof URL === "function") { 3022 - url = new URL(path, document.location.href); 3023 - var origin = document.location.origin; 3024 - sameHost = origin === url.origin; 3025 - } else { 3026 - // IE11 doesn't support URL 3027 - url = path 3028 - sameHost = startsWith(path, document.location.origin) 3029 - } 3030 - 3031 - if (htmx.config.selfRequestsOnly) { 3032 - if (!sameHost) { 3033 - return false; 3034 - } 3035 - } 3036 - return triggerEvent(elt, "htmx:validateUrl", mergeObjects({url: url, sameHost: sameHost}, requestConfig)); 3037 - } 3038 - 3039 - function issueAjaxRequest(verb, path, elt, event, etc, confirmed) { 3040 - var resolve = null; 3041 - var reject = null; 3042 - etc = etc != null ? etc : {}; 3043 - if(etc.returnPromise && typeof Promise !== "undefined"){ 3044 - var promise = new Promise(function (_resolve, _reject) { 3045 - resolve = _resolve; 3046 - reject = _reject; 3047 - }); 3048 - } 3049 - if(elt == null) { 3050 - elt = getDocument().body; 3051 - } 3052 - var responseHandler = etc.handler || handleAjaxResponse; 3053 - var select = etc.select || null; 3054 - 3055 - if (!bodyContains(elt)) { 3056 - // do not issue requests for elements removed from the DOM 3057 - maybeCall(resolve); 3058 - return promise; 3059 - } 3060 - var target = etc.targetOverride || getTarget(elt); 3061 - if (target == null || target == DUMMY_ELT) { 3062 - triggerErrorEvent(elt, 'htmx:targetError', {target: getAttributeValue(elt, "hx-target")}); 3063 - maybeCall(reject); 3064 - return promise; 3065 - } 3066 - 3067 - var eltData = getInternalData(elt); 3068 - var submitter = eltData.lastButtonClicked; 3069 - 3070 - if (submitter) { 3071 - var buttonPath = getRawAttribute(submitter, "formaction"); 3072 - if (buttonPath != null) { 3073 - path = buttonPath; 3074 - } 3075 - 3076 - var buttonVerb = getRawAttribute(submitter, "formmethod") 3077 - if (buttonVerb != null) { 3078 - // ignore buttons with formmethod="dialog" 3079 - if (buttonVerb.toLowerCase() !== "dialog") { 3080 - verb = buttonVerb; 3081 - } 3082 - } 3083 - } 3084 - 3085 - var confirmQuestion = getClosestAttributeValue(elt, "hx-confirm"); 3086 - // allow event-based confirmation w/ a callback 3087 - if (confirmed === undefined) { 3088 - var issueRequest = function(skipConfirmation) { 3089 - return issueAjaxRequest(verb, path, elt, event, etc, !!skipConfirmation); 3090 - } 3091 - var confirmDetails = {target: target, elt: elt, path: path, verb: verb, triggeringEvent: event, etc: etc, issueRequest: issueRequest, question: confirmQuestion}; 3092 - if (triggerEvent(elt, 'htmx:confirm', confirmDetails) === false) { 3093 - maybeCall(resolve); 3094 - return promise; 3095 - } 3096 - } 3097 - 3098 - var syncElt = elt; 3099 - var syncStrategy = getClosestAttributeValue(elt, "hx-sync"); 3100 - var queueStrategy = null; 3101 - var abortable = false; 3102 - if (syncStrategy) { 3103 - var syncStrings = syncStrategy.split(":"); 3104 - var selector = syncStrings[0].trim(); 3105 - if (selector === "this") { 3106 - syncElt = findThisElement(elt, 'hx-sync'); 3107 - } else { 3108 - syncElt = querySelectorExt(elt, selector); 3109 - } 3110 - // default to the drop strategy 3111 - syncStrategy = (syncStrings[1] || 'drop').trim(); 3112 - eltData = getInternalData(syncElt); 3113 - if (syncStrategy === "drop" && eltData.xhr && eltData.abortable !== true) { 3114 - maybeCall(resolve); 3115 - return promise; 3116 - } else if (syncStrategy === "abort") { 3117 - if (eltData.xhr) { 3118 - maybeCall(resolve); 3119 - return promise; 3120 - } else { 3121 - abortable = true; 3122 - } 3123 - } else if (syncStrategy === "replace") { 3124 - triggerEvent(syncElt, 'htmx:abort'); // abort the current request and continue 3125 - } else if (syncStrategy.indexOf("queue") === 0) { 3126 - var queueStrArray = syncStrategy.split(" "); 3127 - queueStrategy = (queueStrArray[1] || "last").trim(); 3128 - } 3129 - } 3130 - 3131 - if (eltData.xhr) { 3132 - if (eltData.abortable) { 3133 - triggerEvent(syncElt, 'htmx:abort'); // abort the current request and continue 3134 - } else { 3135 - if(queueStrategy == null){ 3136 - if (event) { 3137 - var eventData = getInternalData(event); 3138 - if (eventData && eventData.triggerSpec && eventData.triggerSpec.queue) { 3139 - queueStrategy = eventData.triggerSpec.queue; 3140 - } 3141 - } 3142 - if (queueStrategy == null) { 3143 - queueStrategy = "last"; 3144 - } 3145 - } 3146 - if (eltData.queuedRequests == null) { 3147 - eltData.queuedRequests = []; 3148 - } 3149 - if (queueStrategy === "first" && eltData.queuedRequests.length === 0) { 3150 - eltData.queuedRequests.push(function () { 3151 - issueAjaxRequest(verb, path, elt, event, etc) 3152 - }); 3153 - } else if (queueStrategy === "all") { 3154 - eltData.queuedRequests.push(function () { 3155 - issueAjaxRequest(verb, path, elt, event, etc) 3156 - }); 3157 - } else if (queueStrategy === "last") { 3158 - eltData.queuedRequests = []; // dump existing queue 3159 - eltData.queuedRequests.push(function () { 3160 - issueAjaxRequest(verb, path, elt, event, etc) 3161 - }); 3162 - } 3163 - maybeCall(resolve); 3164 - return promise; 3165 - } 3166 - } 3167 - 3168 - var xhr = new XMLHttpRequest(); 3169 - eltData.xhr = xhr; 3170 - eltData.abortable = abortable; 3171 - var endRequestLock = function(){ 3172 - eltData.xhr = null; 3173 - eltData.abortable = false; 3174 - if (eltData.queuedRequests != null && 3175 - eltData.queuedRequests.length > 0) { 3176 - var queuedRequest = eltData.queuedRequests.shift(); 3177 - queuedRequest(); 3178 - } 3179 - } 3180 - var promptQuestion = getClosestAttributeValue(elt, "hx-prompt"); 3181 - if (promptQuestion) { 3182 - var promptResponse = prompt(promptQuestion); 3183 - // prompt returns null if cancelled and empty string if accepted with no entry 3184 - if (promptResponse === null || 3185 - !triggerEvent(elt, 'htmx:prompt', {prompt: promptResponse, target:target})) { 3186 - maybeCall(resolve); 3187 - endRequestLock(); 3188 - return promise; 3189 - } 3190 - } 3191 - 3192 - if (confirmQuestion && !confirmed) { 3193 - if(!confirm(confirmQuestion)) { 3194 - maybeCall(resolve); 3195 - endRequestLock() 3196 - return promise; 3197 - } 3198 - } 3199 - 3200 - 3201 - var headers = getHeaders(elt, target, promptResponse); 3202 - 3203 - if (verb !== 'get' && !usesFormData(elt)) { 3204 - headers['Content-Type'] = 'application/x-www-form-urlencoded'; 3205 - } 3206 - 3207 - if (etc.headers) { 3208 - headers = mergeObjects(headers, etc.headers); 3209 - } 3210 - var results = getInputValues(elt, verb); 3211 - var errors = results.errors; 3212 - var rawParameters = results.values; 3213 - if (etc.values) { 3214 - rawParameters = mergeObjects(rawParameters, etc.values); 3215 - } 3216 - var expressionVars = getExpressionVars(elt); 3217 - var allParameters = mergeObjects(rawParameters, expressionVars); 3218 - var filteredParameters = filterValues(allParameters, elt); 3219 - 3220 - if (htmx.config.getCacheBusterParam && verb === 'get') { 3221 - filteredParameters['org.htmx.cache-buster'] = getRawAttribute(target, "id") || "true"; 3222 - } 3223 - 3224 - // behavior of anchors w/ empty href is to use the current URL 3225 - if (path == null || path === "") { 3226 - path = getDocument().location.href; 3227 - } 3228 - 3229 - 3230 - var requestAttrValues = getValuesForElement(elt, 'hx-request'); 3231 - 3232 - var eltIsBoosted = getInternalData(elt).boosted; 3233 - 3234 - var useUrlParams = htmx.config.methodsThatUseUrlParams.indexOf(verb) >= 0 3235 - 3236 - var requestConfig = { 3237 - boosted: eltIsBoosted, 3238 - useUrlParams: useUrlParams, 3239 - parameters: filteredParameters, 3240 - unfilteredParameters: allParameters, 3241 - headers:headers, 3242 - target:target, 3243 - verb:verb, 3244 - errors:errors, 3245 - withCredentials: etc.credentials || requestAttrValues.credentials || htmx.config.withCredentials, 3246 - timeout: etc.timeout || requestAttrValues.timeout || htmx.config.timeout, 3247 - path:path, 3248 - triggeringEvent:event 3249 - }; 3250 - 3251 - if(!triggerEvent(elt, 'htmx:configRequest', requestConfig)){ 3252 - maybeCall(resolve); 3253 - endRequestLock(); 3254 - return promise; 3255 - } 3256 - 3257 - // copy out in case the object was overwritten 3258 - path = requestConfig.path; 3259 - verb = requestConfig.verb; 3260 - headers = requestConfig.headers; 3261 - filteredParameters = requestConfig.parameters; 3262 - errors = requestConfig.errors; 3263 - useUrlParams = requestConfig.useUrlParams; 3264 - 3265 - if(errors && errors.length > 0){ 3266 - triggerEvent(elt, 'htmx:validation:halted', requestConfig) 3267 - maybeCall(resolve); 3268 - endRequestLock(); 3269 - return promise; 3270 - } 3271 - 3272 - var splitPath = path.split("#"); 3273 - var pathNoAnchor = splitPath[0]; 3274 - var anchor = splitPath[1]; 3275 - 3276 - var finalPath = path 3277 - if (useUrlParams) { 3278 - finalPath = pathNoAnchor; 3279 - var values = Object.keys(filteredParameters).length !== 0; 3280 - if (values) { 3281 - if (finalPath.indexOf("?") < 0) { 3282 - finalPath += "?"; 3283 - } else { 3284 - finalPath += "&"; 3285 - } 3286 - finalPath += urlEncode(filteredParameters); 3287 - if (anchor) { 3288 - finalPath += "#" + anchor; 3289 - } 3290 - } 3291 - } 3292 - 3293 - if (!verifyPath(elt, finalPath, requestConfig)) { 3294 - triggerErrorEvent(elt, 'htmx:invalidPath', requestConfig) 3295 - maybeCall(reject); 3296 - return promise; 3297 - }; 3298 - 3299 - xhr.open(verb.toUpperCase(), finalPath, true); 3300 - xhr.overrideMimeType("text/html"); 3301 - xhr.withCredentials = requestConfig.withCredentials; 3302 - xhr.timeout = requestConfig.timeout; 3303 - 3304 - // request headers 3305 - if (requestAttrValues.noHeaders) { 3306 - // ignore all headers 3307 - } else { 3308 - for (var header in headers) { 3309 - if (headers.hasOwnProperty(header)) { 3310 - var headerValue = headers[header]; 3311 - safelySetHeaderValue(xhr, header, headerValue); 3312 - } 3313 - } 3314 - } 3315 - 3316 - var responseInfo = { 3317 - xhr: xhr, target: target, requestConfig: requestConfig, etc: etc, boosted: eltIsBoosted, select: select, 3318 - pathInfo: { 3319 - requestPath: path, 3320 - finalRequestPath: finalPath, 3321 - anchor: anchor 3322 - } 3323 - }; 3324 - 3325 - xhr.onload = function () { 3326 - try { 3327 - var hierarchy = hierarchyForElt(elt); 3328 - responseInfo.pathInfo.responsePath = getPathFromResponse(xhr); 3329 - responseHandler(elt, responseInfo); 3330 - removeRequestIndicators(indicators, disableElts); 3331 - triggerEvent(elt, 'htmx:afterRequest', responseInfo); 3332 - triggerEvent(elt, 'htmx:afterOnLoad', responseInfo); 3333 - // if the body no longer contains the element, trigger the event on the closest parent 3334 - // remaining in the DOM 3335 - if (!bodyContains(elt)) { 3336 - var secondaryTriggerElt = null; 3337 - while (hierarchy.length > 0 && secondaryTriggerElt == null) { 3338 - var parentEltInHierarchy = hierarchy.shift(); 3339 - if (bodyContains(parentEltInHierarchy)) { 3340 - secondaryTriggerElt = parentEltInHierarchy; 3341 - } 3342 - } 3343 - if (secondaryTriggerElt) { 3344 - triggerEvent(secondaryTriggerElt, 'htmx:afterRequest', responseInfo); 3345 - triggerEvent(secondaryTriggerElt, 'htmx:afterOnLoad', responseInfo); 3346 - } 3347 - } 3348 - maybeCall(resolve); 3349 - endRequestLock(); 3350 - } catch (e) { 3351 - triggerErrorEvent(elt, 'htmx:onLoadError', mergeObjects({error:e}, responseInfo)); 3352 - throw e; 3353 - } 3354 - } 3355 - xhr.onerror = function () { 3356 - removeRequestIndicators(indicators, disableElts); 3357 - triggerErrorEvent(elt, 'htmx:afterRequest', responseInfo); 3358 - triggerErrorEvent(elt, 'htmx:sendError', responseInfo); 3359 - maybeCall(reject); 3360 - endRequestLock(); 3361 - } 3362 - xhr.onabort = function() { 3363 - removeRequestIndicators(indicators, disableElts); 3364 - triggerErrorEvent(elt, 'htmx:afterRequest', responseInfo); 3365 - triggerErrorEvent(elt, 'htmx:sendAbort', responseInfo); 3366 - maybeCall(reject); 3367 - endRequestLock(); 3368 - } 3369 - xhr.ontimeout = function() { 3370 - removeRequestIndicators(indicators, disableElts); 3371 - triggerErrorEvent(elt, 'htmx:afterRequest', responseInfo); 3372 - triggerErrorEvent(elt, 'htmx:timeout', responseInfo); 3373 - maybeCall(reject); 3374 - endRequestLock(); 3375 - } 3376 - if(!triggerEvent(elt, 'htmx:beforeRequest', responseInfo)){ 3377 - maybeCall(resolve); 3378 - endRequestLock() 3379 - return promise 3380 - } 3381 - var indicators = addRequestIndicatorClasses(elt); 3382 - var disableElts = disableElements(elt); 3383 - 3384 - forEach(['loadstart', 'loadend', 'progress', 'abort'], function(eventName) { 3385 - forEach([xhr, xhr.upload], function (target) { 3386 - target.addEventListener(eventName, function(event){ 3387 - triggerEvent(elt, "htmx:xhr:" + eventName, { 3388 - lengthComputable:event.lengthComputable, 3389 - loaded:event.loaded, 3390 - total:event.total 3391 - }); 3392 - }) 3393 - }); 3394 - }); 3395 - triggerEvent(elt, 'htmx:beforeSend', responseInfo); 3396 - var params = useUrlParams ? null : encodeParamsForBody(xhr, elt, filteredParameters) 3397 - xhr.send(params); 3398 - return promise; 3399 - } 3400 - 3401 - function determineHistoryUpdates(elt, responseInfo) { 3402 - 3403 - var xhr = responseInfo.xhr; 3404 - 3405 - //=========================================== 3406 - // First consult response headers 3407 - //=========================================== 3408 - var pathFromHeaders = null; 3409 - var typeFromHeaders = null; 3410 - if (hasHeader(xhr,/HX-Push:/i)) { 3411 - pathFromHeaders = xhr.getResponseHeader("HX-Push"); 3412 - typeFromHeaders = "push"; 3413 - } else if (hasHeader(xhr,/HX-Push-Url:/i)) { 3414 - pathFromHeaders = xhr.getResponseHeader("HX-Push-Url"); 3415 - typeFromHeaders = "push"; 3416 - } else if (hasHeader(xhr,/HX-Replace-Url:/i)) { 3417 - pathFromHeaders = xhr.getResponseHeader("HX-Replace-Url"); 3418 - typeFromHeaders = "replace"; 3419 - } 3420 - 3421 - // if there was a response header, that has priority 3422 - if (pathFromHeaders) { 3423 - if (pathFromHeaders === "false") { 3424 - return {} 3425 - } else { 3426 - return { 3427 - type: typeFromHeaders, 3428 - path : pathFromHeaders 3429 - } 3430 - } 3431 - } 3432 - 3433 - //=========================================== 3434 - // Next resolve via DOM values 3435 - //=========================================== 3436 - var requestPath = responseInfo.pathInfo.finalRequestPath; 3437 - var responsePath = responseInfo.pathInfo.responsePath; 3438 - 3439 - var pushUrl = getClosestAttributeValue(elt, "hx-push-url"); 3440 - var replaceUrl = getClosestAttributeValue(elt, "hx-replace-url"); 3441 - var elementIsBoosted = getInternalData(elt).boosted; 3442 - 3443 - var saveType = null; 3444 - var path = null; 3445 - 3446 - if (pushUrl) { 3447 - saveType = "push"; 3448 - path = pushUrl; 3449 - } else if (replaceUrl) { 3450 - saveType = "replace"; 3451 - path = replaceUrl; 3452 - } else if (elementIsBoosted) { 3453 - saveType = "push"; 3454 - path = responsePath || requestPath; // if there is no response path, go with the original request path 3455 - } 3456 - 3457 - if (path) { 3458 - // false indicates no push, return empty object 3459 - if (path === "false") { 3460 - return {}; 3461 - } 3462 - 3463 - // true indicates we want to follow wherever the server ended up sending us 3464 - if (path === "true") { 3465 - path = responsePath || requestPath; // if there is no response path, go with the original request path 3466 - } 3467 - 3468 - // restore any anchor associated with the request 3469 - if (responseInfo.pathInfo.anchor && 3470 - path.indexOf("#") === -1) { 3471 - path = path + "#" + responseInfo.pathInfo.anchor; 3472 - } 3473 - 3474 - return { 3475 - type:saveType, 3476 - path: path 3477 - } 3478 - } else { 3479 - return {}; 3480 - } 3481 - } 3482 - 3483 - function handleAjaxResponse(elt, responseInfo) { 3484 - var xhr = responseInfo.xhr; 3485 - var target = responseInfo.target; 3486 - var etc = responseInfo.etc; 3487 - var requestConfig = responseInfo.requestConfig; 3488 - var select = responseInfo.select; 3489 - 3490 - if (!triggerEvent(elt, 'htmx:beforeOnLoad', responseInfo)) return; 3491 - 3492 - if (hasHeader(xhr, /HX-Trigger:/i)) { 3493 - handleTrigger(xhr, "HX-Trigger", elt); 3494 - } 3495 - 3496 - if (hasHeader(xhr, /HX-Location:/i)) { 3497 - saveCurrentPageToHistory(); 3498 - var redirectPath = xhr.getResponseHeader("HX-Location"); 3499 - var swapSpec; 3500 - if (redirectPath.indexOf("{") === 0) { 3501 - swapSpec = parseJSON(redirectPath); 3502 - // what's the best way to throw an error if the user didn't include this 3503 - redirectPath = swapSpec['path']; 3504 - delete swapSpec['path']; 3505 - } 3506 - ajaxHelper('GET', redirectPath, swapSpec).then(function(){ 3507 - pushUrlIntoHistory(redirectPath); 3508 - }); 3509 - return; 3510 - } 3511 - 3512 - var shouldRefresh = hasHeader(xhr, /HX-Refresh:/i) && "true" === xhr.getResponseHeader("HX-Refresh"); 3513 - 3514 - if (hasHeader(xhr, /HX-Redirect:/i)) { 3515 - location.href = xhr.getResponseHeader("HX-Redirect"); 3516 - shouldRefresh && location.reload(); 3517 - return; 3518 - } 3519 - 3520 - if (shouldRefresh) { 3521 - location.reload(); 3522 - return; 3523 - } 3524 - 3525 - if (hasHeader(xhr,/HX-Retarget:/i)) { 3526 - if (xhr.getResponseHeader("HX-Retarget") === "this") { 3527 - responseInfo.target = elt; 3528 - } else { 3529 - responseInfo.target = querySelectorExt(elt, xhr.getResponseHeader("HX-Retarget")); 3530 - } 3531 - } 3532 - 3533 - var historyUpdate = determineHistoryUpdates(elt, responseInfo); 3534 - 3535 - // by default htmx only swaps on 200 return codes and does not swap 3536 - // on 204 'No Content' 3537 - // this can be ovverriden by responding to the htmx:beforeSwap event and 3538 - // overriding the detail.shouldSwap property 3539 - var shouldSwap = xhr.status >= 200 && xhr.status < 400 && xhr.status !== 204; 3540 - var serverResponse = xhr.response; 3541 - var isError = xhr.status >= 400; 3542 - var ignoreTitle = htmx.config.ignoreTitle 3543 - var beforeSwapDetails = mergeObjects({shouldSwap: shouldSwap, serverResponse:serverResponse, isError:isError, ignoreTitle:ignoreTitle }, responseInfo); 3544 - if (!triggerEvent(target, 'htmx:beforeSwap', beforeSwapDetails)) return; 3545 - 3546 - target = beforeSwapDetails.target; // allow re-targeting 3547 - serverResponse = beforeSwapDetails.serverResponse; // allow updating content 3548 - isError = beforeSwapDetails.isError; // allow updating error 3549 - ignoreTitle = beforeSwapDetails.ignoreTitle; // allow updating ignoring title 3550 - 3551 - responseInfo.target = target; // Make updated target available to response events 3552 - responseInfo.failed = isError; // Make failed property available to response events 3553 - responseInfo.successful = !isError; // Make successful property available to response events 3554 - 3555 - if (beforeSwapDetails.shouldSwap) { 3556 - if (xhr.status === 286) { 3557 - cancelPolling(elt); 3558 - } 3559 - 3560 - withExtensions(elt, function (extension) { 3561 - serverResponse = extension.transformResponse(serverResponse, xhr, elt); 3562 - }); 3563 - 3564 - // Save current page if there will be a history update 3565 - if (historyUpdate.type) { 3566 - saveCurrentPageToHistory(); 3567 - } 3568 - 3569 - var swapOverride = etc.swapOverride; 3570 - if (hasHeader(xhr,/HX-Reswap:/i)) { 3571 - swapOverride = xhr.getResponseHeader("HX-Reswap"); 3572 - } 3573 - var swapSpec = getSwapSpecification(elt, swapOverride); 3574 - 3575 - if (swapSpec.hasOwnProperty('ignoreTitle')) { 3576 - ignoreTitle = swapSpec.ignoreTitle; 3577 - } 3578 - 3579 - target.classList.add(htmx.config.swappingClass); 3580 - 3581 - // optional transition API promise callbacks 3582 - var settleResolve = null; 3583 - var settleReject = null; 3584 - 3585 - var doSwap = function () { 3586 - try { 3587 - var activeElt = document.activeElement; 3588 - var selectionInfo = {}; 3589 - try { 3590 - selectionInfo = { 3591 - elt: activeElt, 3592 - // @ts-ignore 3593 - start: activeElt ? activeElt.selectionStart : null, 3594 - // @ts-ignore 3595 - end: activeElt ? activeElt.selectionEnd : null 3596 - }; 3597 - } catch (e) { 3598 - // safari issue - see https://github.com/microsoft/playwright/issues/5894 3599 - } 3600 - 3601 - var selectOverride; 3602 - if (select) { 3603 - selectOverride = select; 3604 - } 3605 - 3606 - if (hasHeader(xhr, /HX-Reselect:/i)) { 3607 - selectOverride = xhr.getResponseHeader("HX-Reselect"); 3608 - } 3609 - 3610 - // if we need to save history, do so, before swapping so that relative resources have the correct base URL 3611 - if (historyUpdate.type) { 3612 - triggerEvent(getDocument().body, 'htmx:beforeHistoryUpdate', mergeObjects({ history: historyUpdate }, responseInfo)); 3613 - if (historyUpdate.type === "push") { 3614 - pushUrlIntoHistory(historyUpdate.path); 3615 - triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path: historyUpdate.path}); 3616 - } else { 3617 - replaceUrlInHistory(historyUpdate.path); 3618 - triggerEvent(getDocument().body, 'htmx:replacedInHistory', {path: historyUpdate.path}); 3619 - } 3620 - } 3621 - 3622 - var settleInfo = makeSettleInfo(target); 3623 - selectAndSwap(swapSpec.swapStyle, target, elt, serverResponse, settleInfo, selectOverride); 3624 - 3625 - if (selectionInfo.elt && 3626 - !bodyContains(selectionInfo.elt) && 3627 - getRawAttribute(selectionInfo.elt, "id")) { 3628 - var newActiveElt = document.getElementById(getRawAttribute(selectionInfo.elt, "id")); 3629 - var focusOptions = { preventScroll: swapSpec.focusScroll !== undefined ? !swapSpec.focusScroll : !htmx.config.defaultFocusScroll }; 3630 - if (newActiveElt) { 3631 - // @ts-ignore 3632 - if (selectionInfo.start && newActiveElt.setSelectionRange) { 3633 - // @ts-ignore 3634 - try { 3635 - newActiveElt.setSelectionRange(selectionInfo.start, selectionInfo.end); 3636 - } catch (e) { 3637 - // the setSelectionRange method is present on fields that don't support it, so just let this fail 3638 - } 3639 - } 3640 - newActiveElt.focus(focusOptions); 3641 - } 3642 - } 3643 - 3644 - target.classList.remove(htmx.config.swappingClass); 3645 - forEach(settleInfo.elts, function (elt) { 3646 - if (elt.classList) { 3647 - elt.classList.add(htmx.config.settlingClass); 3648 - } 3649 - triggerEvent(elt, 'htmx:afterSwap', responseInfo); 3650 - }); 3651 - 3652 - if (hasHeader(xhr, /HX-Trigger-After-Swap:/i)) { 3653 - var finalElt = elt; 3654 - if (!bodyContains(elt)) { 3655 - finalElt = getDocument().body; 3656 - } 3657 - handleTrigger(xhr, "HX-Trigger-After-Swap", finalElt); 3658 - } 3659 - 3660 - var doSettle = function () { 3661 - forEach(settleInfo.tasks, function (task) { 3662 - task.call(); 3663 - }); 3664 - forEach(settleInfo.elts, function (elt) { 3665 - if (elt.classList) { 3666 - elt.classList.remove(htmx.config.settlingClass); 3667 - } 3668 - triggerEvent(elt, 'htmx:afterSettle', responseInfo); 3669 - }); 3670 - 3671 - if (responseInfo.pathInfo.anchor) { 3672 - var anchorTarget = getDocument().getElementById(responseInfo.pathInfo.anchor); 3673 - if(anchorTarget) { 3674 - anchorTarget.scrollIntoView({block:'start', behavior: "auto"}); 3675 - } 3676 - } 3677 - 3678 - if(settleInfo.title && !ignoreTitle) { 3679 - var titleElt = find("title"); 3680 - if(titleElt) { 3681 - titleElt.innerHTML = settleInfo.title; 3682 - } else { 3683 - window.document.title = settleInfo.title; 3684 - } 3685 - } 3686 - 3687 - updateScrollState(settleInfo.elts, swapSpec); 3688 - 3689 - if (hasHeader(xhr, /HX-Trigger-After-Settle:/i)) { 3690 - var finalElt = elt; 3691 - if (!bodyContains(elt)) { 3692 - finalElt = getDocument().body; 3693 - } 3694 - handleTrigger(xhr, "HX-Trigger-After-Settle", finalElt); 3695 - } 3696 - maybeCall(settleResolve); 3697 - } 3698 - 3699 - if (swapSpec.settleDelay > 0) { 3700 - setTimeout(doSettle, swapSpec.settleDelay) 3701 - } else { 3702 - doSettle(); 3703 - } 3704 - } catch (e) { 3705 - triggerErrorEvent(elt, 'htmx:swapError', responseInfo); 3706 - maybeCall(settleReject); 3707 - throw e; 3708 - } 3709 - }; 3710 - 3711 - var shouldTransition = htmx.config.globalViewTransitions 3712 - if(swapSpec.hasOwnProperty('transition')){ 3713 - shouldTransition = swapSpec.transition; 3714 - } 3715 - 3716 - if(shouldTransition && 3717 - triggerEvent(elt, 'htmx:beforeTransition', responseInfo) && 3718 - typeof Promise !== "undefined" && document.startViewTransition){ 3719 - var settlePromise = new Promise(function (_resolve, _reject) { 3720 - settleResolve = _resolve; 3721 - settleReject = _reject; 3722 - }); 3723 - // wrap the original doSwap() in a call to startViewTransition() 3724 - var innerDoSwap = doSwap; 3725 - doSwap = function() { 3726 - document.startViewTransition(function () { 3727 - innerDoSwap(); 3728 - return settlePromise; 3729 - }); 3730 - } 3731 - } 3732 - 3733 - 3734 - if (swapSpec.swapDelay > 0) { 3735 - setTimeout(doSwap, swapSpec.swapDelay) 3736 - } else { 3737 - doSwap(); 3738 - } 3739 - } 3740 - if (isError) { 3741 - triggerErrorEvent(elt, 'htmx:responseError', mergeObjects({error: "Response Status Error Code " + xhr.status + " from " + responseInfo.pathInfo.requestPath}, responseInfo)); 3742 - } 3743 - } 3744 - 3745 - //==================================================================== 3746 - // Extensions API 3747 - //==================================================================== 3748 - 3749 - /** @type {Object<string, import("./htmx").HtmxExtension>} */ 3750 - var extensions = {}; 3751 - 3752 - /** 3753 - * extensionBase defines the default functions for all extensions. 3754 - * @returns {import("./htmx").HtmxExtension} 3755 - */ 3756 - function extensionBase() { 3757 - return { 3758 - init: function(api) {return null;}, 3759 - onEvent : function(name, evt) {return true;}, 3760 - transformResponse : function(text, xhr, elt) {return text;}, 3761 - isInlineSwap : function(swapStyle) {return false;}, 3762 - handleSwap : function(swapStyle, target, fragment, settleInfo) {return false;}, 3763 - encodeParameters : function(xhr, parameters, elt) {return null;} 3764 - } 3765 - } 3766 - 3767 - /** 3768 - * defineExtension initializes the extension and adds it to the htmx registry 3769 - * 3770 - * @param {string} name 3771 - * @param {import("./htmx").HtmxExtension} extension 3772 - */ 3773 - function defineExtension(name, extension) { 3774 - if(extension.init) { 3775 - extension.init(internalAPI) 3776 - } 3777 - extensions[name] = mergeObjects(extensionBase(), extension); 3778 - } 3779 - 3780 - /** 3781 - * removeExtension removes an extension from the htmx registry 3782 - * 3783 - * @param {string} name 3784 - */ 3785 - function removeExtension(name) { 3786 - delete extensions[name]; 3787 - } 3788 - 3789 - /** 3790 - * getExtensions searches up the DOM tree to return all extensions that can be applied to a given element 3791 - * 3792 - * @param {HTMLElement} elt 3793 - * @param {import("./htmx").HtmxExtension[]=} extensionsToReturn 3794 - * @param {import("./htmx").HtmxExtension[]=} extensionsToIgnore 3795 - */ 3796 - function getExtensions(elt, extensionsToReturn, extensionsToIgnore) { 3797 - 3798 - if (elt == undefined) { 3799 - return extensionsToReturn; 3800 - } 3801 - if (extensionsToReturn == undefined) { 3802 - extensionsToReturn = []; 3803 - } 3804 - if (extensionsToIgnore == undefined) { 3805 - extensionsToIgnore = []; 3806 - } 3807 - var extensionsForElement = getAttributeValue(elt, "hx-ext"); 3808 - if (extensionsForElement) { 3809 - forEach(extensionsForElement.split(","), function(extensionName){ 3810 - extensionName = extensionName.replace(/ /g, ''); 3811 - if (extensionName.slice(0, 7) == "ignore:") { 3812 - extensionsToIgnore.push(extensionName.slice(7)); 3813 - return; 3814 - } 3815 - if (extensionsToIgnore.indexOf(extensionName) < 0) { 3816 - var extension = extensions[extensionName]; 3817 - if (extension && extensionsToReturn.indexOf(extension) < 0) { 3818 - extensionsToReturn.push(extension); 3819 - } 3820 - } 3821 - }); 3822 - } 3823 - return getExtensions(parentElt(elt), extensionsToReturn, extensionsToIgnore); 3824 - } 3825 - 3826 - //==================================================================== 3827 - // Initialization 3828 - //==================================================================== 3829 - var isReady = false 3830 - getDocument().addEventListener('DOMContentLoaded', function() { 3831 - isReady = true 3832 - }) 3833 - 3834 - /** 3835 - * Execute a function now if DOMContentLoaded has fired, otherwise listen for it. 3836 - * 3837 - * This function uses isReady because there is no realiable way to ask the browswer whether 3838 - * the DOMContentLoaded event has already been fired; there's a gap between DOMContentLoaded 3839 - * firing and readystate=complete. 3840 - */ 3841 - function ready(fn) { 3842 - // Checking readyState here is a failsafe in case the htmx script tag entered the DOM by 3843 - // some means other than the initial page load. 3844 - if (isReady || getDocument().readyState === 'complete') { 3845 - fn(); 3846 - } else { 3847 - getDocument().addEventListener('DOMContentLoaded', fn); 3848 - } 3849 - } 3850 - 3851 - function insertIndicatorStyles() { 3852 - if (htmx.config.includeIndicatorStyles !== false) { 3853 - getDocument().head.insertAdjacentHTML("beforeend", 3854 - "<style>\ 3855 - ." + htmx.config.indicatorClass + "{opacity:0}\ 3856 - ." + htmx.config.requestClass + " ." + htmx.config.indicatorClass + "{opacity:1; transition: opacity 200ms ease-in;}\ 3857 - ." + htmx.config.requestClass + "." + htmx.config.indicatorClass + "{opacity:1; transition: opacity 200ms ease-in;}\ 3858 - </style>"); 3859 - } 3860 - } 3861 - 3862 - function getMetaConfig() { 3863 - var element = getDocument().querySelector('meta[name="htmx-config"]'); 3864 - if (element) { 3865 - // @ts-ignore 3866 - return parseJSON(element.content); 3867 - } else { 3868 - return null; 3869 - } 3870 - } 3871 - 3872 - function mergeMetaConfig() { 3873 - var metaConfig = getMetaConfig(); 3874 - if (metaConfig) { 3875 - htmx.config = mergeObjects(htmx.config , metaConfig) 3876 - } 3877 - } 3878 - 3879 - // initialize the document 3880 - ready(function () { 3881 - mergeMetaConfig(); 3882 - insertIndicatorStyles(); 3883 - var body = getDocument().body; 3884 - processNode(body); 3885 - var restoredElts = getDocument().querySelectorAll( 3886 - "[hx-trigger='restored'],[data-hx-trigger='restored']" 3887 - ); 3888 - body.addEventListener("htmx:abort", function (evt) { 3889 - var target = evt.target; 3890 - var internalData = getInternalData(target); 3891 - if (internalData && internalData.xhr) { 3892 - internalData.xhr.abort(); 3893 - } 3894 - }); 3895 - /** @type {(ev: PopStateEvent) => any} */ 3896 - const originalPopstate = window.onpopstate ? window.onpopstate.bind(window) : null; 3897 - /** @type {(ev: PopStateEvent) => any} */ 3898 - window.onpopstate = function (event) { 3899 - if (event.state && event.state.htmx) { 3900 - restoreHistory(); 3901 - forEach(restoredElts, function(elt){ 3902 - triggerEvent(elt, 'htmx:restored', { 3903 - 'document': getDocument(), 3904 - 'triggerEvent': triggerEvent 3905 - }); 3906 - }); 3907 - } else { 3908 - if (originalPopstate) { 3909 - originalPopstate(event); 3910 - } 3911 - } 3912 - }; 3913 - setTimeout(function () { 3914 - triggerEvent(body, 'htmx:load', {}); // give ready handlers a chance to load up before firing this event 3915 - body = null; // kill reference for gc 3916 - }, 0); 3917 - }) 3918 - 3919 - return htmx; 3920 - } 3921 - )() 3922 - }));
-1
public/script/lib/htmx.min.js
··· 1 - (function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else if(typeof module==="object"&&module.exports){module.exports=t()}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var Q={onLoad:B,process:zt,on:de,off:ge,trigger:ce,ajax:Nr,find:C,findAll:f,closest:v,values:function(e,t){var r=dr(e,t||"post");return r.values},remove:_,addClass:z,removeClass:n,toggleClass:$,takeClass:W,defineExtension:Ur,removeExtension:Fr,logAll:V,logNone:j,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,allowScriptTags:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get"],selfRequestsOnly:false,ignoreTitle:false,scrollIntoViewOnBoost:true,triggerSpecsCache:null},parseInterval:d,_:t,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=Q.config.wsBinaryType;return t},version:"1.9.11"};var r={addTriggerHandler:Lt,bodyContains:se,canAccessLocalStorage:U,findThisElement:xe,filterValues:yr,hasAttribute:o,getAttributeValue:te,getClosestAttributeValue:ne,getClosestMatch:c,getExpressionVars:Hr,getHeaders:xr,getInputValues:dr,getInternalData:ae,getSwapSpecification:wr,getTriggerSpecs:it,getTarget:ye,makeFragment:l,mergeObjects:le,makeSettleInfo:T,oobSwap:Ee,querySelectorExt:ue,selectAndSwap:je,settleImmediately:nr,shouldCancel:ut,triggerEvent:ce,triggerErrorEvent:fe,withExtensions:R};var w=["get","post","put","delete","patch"];var i=w.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");var S=e("head"),q=e("title"),H=e("svg",true);function e(e,t=false){return new RegExp(`<${e}(\\s[^>]*>|>)([\\s\\S]*?)<\\/${e}>`,t?"gim":"im")}function d(e){if(e==undefined){return undefined}let t=NaN;if(e.slice(-2)=="ms"){t=parseFloat(e.slice(0,-2))}else if(e.slice(-1)=="s"){t=parseFloat(e.slice(0,-1))*1e3}else if(e.slice(-1)=="m"){t=parseFloat(e.slice(0,-1))*1e3*60}else{t=parseFloat(e)}return isNaN(t)?undefined:t}function ee(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function te(e,t){return ee(e,t)||ee(e,"data-"+t)}function u(e){return e.parentElement}function re(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function L(e,t,r){var n=te(t,r);var i=te(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function ne(t,r){var n=null;c(t,function(e){return n=L(t,e,r)});if(n!=="unset"){return n}}function h(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function A(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function s(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=re().createDocumentFragment()}return i}function N(e){return/<body/.test(e)}function l(e){var t=!N(e);var r=A(e);var n=e;if(r==="head"){n=n.replace(S,"")}if(Q.config.useTemplateFragments&&t){var i=s("<body><template>"+n+"</template></body>",0);var a=i.querySelector("template").content;if(Q.config.allowScriptTags){oe(a.querySelectorAll("script"),function(e){if(Q.config.inlineScriptNonce){e.nonce=Q.config.inlineScriptNonce}e.htmxExecuted=navigator.userAgent.indexOf("Firefox")===-1})}else{oe(a.querySelectorAll("script"),function(e){_(e)})}return a}switch(r){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return s("<table>"+n+"</table>",1);case"col":return s("<table><colgroup>"+n+"</colgroup></table>",2);case"tr":return s("<table><tbody>"+n+"</tbody></table>",2);case"td":case"th":return s("<table><tbody><tr>"+n+"</tr></tbody></table>",3);case"script":case"style":return s("<div>"+n+"</div>",1);default:return s(n,0)}}function ie(e){if(e){e()}}function I(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function k(e){return I(e,"Function")}function P(e){return I(e,"Object")}function ae(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function M(e){var t=[];if(e){for(var r=0;r<e.length;r++){t.push(e[r])}}return t}function oe(e,t){if(e){for(var r=0;r<e.length;r++){t(e[r])}}}function X(e){var t=e.getBoundingClientRect();var r=t.top;var n=t.bottom;return r<window.innerHeight&&n>=0}function se(e){if(e.getRootNode&&e.getRootNode()instanceof window.ShadowRoot){return re().body.contains(e.getRootNode().host)}else{return re().body.contains(e)}}function D(e){return e.trim().split(/\s+/)}function le(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function E(e){try{return JSON.parse(e)}catch(e){b(e);return null}}function U(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function F(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!/^\/$/.test(t)){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function t(e){return Tr(re().body,function(){return eval(e)})}function B(t){var e=Q.on("htmx:load",function(e){t(e.detail.elt)});return e}function V(){Q.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function j(){Q.logger=null}function C(e,t){if(t){return e.querySelector(t)}else{return C(re(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(re(),e)}}function _(e,t){e=p(e);if(t){setTimeout(function(){_(e);e=null},t)}else{e.parentElement.removeChild(e)}}function z(e,t,r){e=p(e);if(r){setTimeout(function(){z(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=p(e);if(r){setTimeout(function(){n(e,t);e=null},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function $(e,t){e=p(e);e.classList.toggle(t)}function W(e,t){e=p(e);oe(e.parentElement.children,function(e){n(e,t)});z(e,t)}function v(e,t){e=p(e);if(e.closest){return e.closest(t)}else{do{if(e==null||h(e,t)){return e}}while(e=e&&u(e));return null}}function g(e,t){return e.substring(0,t.length)===t}function G(e,t){return e.substring(e.length-t.length)===t}function J(e){var t=e.trim();if(g(t,"<")&&G(t,"/>")){return t.substring(1,t.length-2)}else{return t}}function Z(e,t){if(t.indexOf("closest ")===0){return[v(e,J(t.substr(8)))]}else if(t.indexOf("find ")===0){return[C(e,J(t.substr(5)))]}else if(t==="next"){return[e.nextElementSibling]}else if(t.indexOf("next ")===0){return[K(e,J(t.substr(5)))]}else if(t==="previous"){return[e.previousElementSibling]}else if(t.indexOf("previous ")===0){return[Y(e,J(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else if(t==="body"){return[document.body]}else{return re().querySelectorAll(J(t))}}var K=function(e,t){var r=re().querySelectorAll(t);for(var n=0;n<r.length;n++){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_PRECEDING){return i}}};var Y=function(e,t){var r=re().querySelectorAll(t);for(var n=r.length-1;n>=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function ue(e,t){if(t){return Z(e,t)[0]}else{return Z(re().body,e)[0]}}function p(e){if(I(e,"String")){return C(e)}else{return e}}function ve(e,t,r){if(k(t)){return{target:re().body,event:e,listener:t}}else{return{target:p(e),event:t,listener:r}}}function de(t,r,n){jr(function(){var e=ve(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=k(r);return e?r:n}function ge(t,r,n){jr(function(){var e=ve(t,r,n);e.target.removeEventListener(e.event,e.listener)});return k(r)?r:n}var pe=re().createElement("output");function me(e,t){var r=ne(e,t);if(r){if(r==="this"){return[xe(e,t)]}else{var n=Z(e,r);if(n.length===0){b('The selector "'+r+'" on '+t+" returned no matches!");return[pe]}else{return n}}}}function xe(e,t){return c(e,function(e){return te(e,t)!=null})}function ye(e){var t=ne(e,"hx-target");if(t){if(t==="this"){return xe(e,"hx-target")}else{return ue(e,t)}}else{var r=ae(e);if(r.boosted){return re().body}else{return e}}}function be(e){var t=Q.config.attributesToSettle;for(var r=0;r<t.length;r++){if(e===t[r]){return true}}return false}function we(t,r){oe(t.attributes,function(e){if(!r.hasAttribute(e.name)&&be(e.name)){t.removeAttribute(e.name)}});oe(r.attributes,function(e){if(be(e.name)){t.setAttribute(e.name,e.value)}})}function Se(e,t){var r=Br(t);for(var n=0;n<r.length;n++){var i=r[n];try{if(i.isInlineSwap(e)){return true}}catch(e){b(e)}}return e==="outerHTML"}function Ee(e,i,a){var t="#"+ee(i,"id");var o="outerHTML";if(e==="true"){}else if(e.indexOf(":")>0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=re().querySelectorAll(t);if(r){oe(r,function(e){var t;var r=i.cloneNode(true);t=re().createDocumentFragment();t.appendChild(r);if(!Se(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!ce(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){Be(o,e,e,t,a)}oe(a.elts,function(e){ce(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);fe(re().body,"htmx:oobErrorNoTarget",{content:i})}return e}function Ce(e,t,r){var n=ne(e,"hx-select-oob");if(n){var i=n.split(",");for(var a=0;a<i.length;a++){var o=i[a].split(":",2);var s=o[0].trim();if(s.indexOf("#")===0){s=s.substring(1)}var l=o[1]||"true";var u=t.querySelector("#"+s);if(u){Ee(l,u,r)}}}oe(f(t,"[hx-swap-oob], [data-hx-swap-oob]"),function(e){var t=te(e,"hx-swap-oob");if(t!=null){Ee(t,e,r)}})}function Re(e){oe(f(e,"[hx-preserve], [data-hx-preserve]"),function(e){var t=te(e,"id");var r=re().getElementById(t);if(r!=null){e.parentNode.replaceChild(r,e)}})}function Te(o,e,s){oe(e.querySelectorAll("[id]"),function(e){var t=ee(e,"id");if(t&&t.length>0){var r=t.replace("'","\\'");var n=e.tagName.replace(":","\\:");var i=o.querySelector(n+"[id='"+r+"']");if(i&&i!==o){var a=e.cloneNode();we(e,i);s.tasks.push(function(){we(e,a)})}}})}function Oe(e){return function(){n(e,Q.config.addedClass);zt(e);Nt(e);qe(e);ce(e,"htmx:load")}}function qe(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function a(e,t,r,n){Te(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;z(i,Q.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(Oe(i))}}}function He(e,t){var r=0;while(r<e.length){t=(t<<5)-t+e.charCodeAt(r++)|0}return t}function Le(e){var t=0;if(e.attributes){for(var r=0;r<e.attributes.length;r++){var n=e.attributes[r];if(n.value){t=He(n.name,t);t=He(n.value,t)}}}return t}function Ae(e){var t=ae(e);if(t.onHandlers){for(var r=0;r<t.onHandlers.length;r++){const n=t.onHandlers[r];e.removeEventListener(n.event,n.listener)}delete t.onHandlers}}function Ne(e){var t=ae(e);if(t.timeout){clearTimeout(t.timeout)}if(t.webSocket){t.webSocket.close()}if(t.sseEventSource){t.sseEventSource.close()}if(t.listenerInfos){oe(t.listenerInfos,function(e){if(e.on){e.on.removeEventListener(e.trigger,e.listener)}})}Ae(e);oe(Object.keys(t),function(e){delete t[e]})}function m(e){ce(e,"htmx:beforeCleanupElement");Ne(e);if(e.children){oe(e.children,function(e){m(e)})}}function Ie(t,e,r){if(t.tagName==="BODY"){return Ue(t,e,r)}else{var n;var i=t.previousSibling;a(u(t),t,e,r);if(i==null){n=u(t).firstChild}else{n=i.nextSibling}r.elts=r.elts.filter(function(e){return e!=t});while(n&&n!==t){if(n.nodeType===Node.ELEMENT_NODE){r.elts.push(n)}n=n.nextElementSibling}m(t);u(t).removeChild(t)}}function ke(e,t,r){return a(e,e.firstChild,t,r)}function Pe(e,t,r){return a(u(e),e,t,r)}function Me(e,t,r){return a(e,null,t,r)}function Xe(e,t,r){return a(u(e),e.nextSibling,t,r)}function De(e,t,r){m(e);return u(e).removeChild(e)}function Ue(e,t,r){var n=e.firstChild;a(e,n,t,r);if(n){while(n.nextSibling){m(n.nextSibling);e.removeChild(n.nextSibling)}m(n);e.removeChild(n)}}function Fe(e,t,r){var n=r||ne(e,"hx-select");if(n){var i=re().createDocumentFragment();oe(t.querySelectorAll(n),function(e){i.appendChild(e)});t=i}return t}function Be(e,t,r,n,i){switch(e){case"none":return;case"outerHTML":Ie(r,n,i);return;case"afterbegin":ke(r,n,i);return;case"beforebegin":Pe(r,n,i);return;case"beforeend":Me(r,n,i);return;case"afterend":Xe(r,n,i);return;case"delete":De(r,n,i);return;default:var a=Br(t);for(var o=0;o<a.length;o++){var s=a[o];try{var l=s.handleSwap(e,r,n,i);if(l){if(typeof l.length!=="undefined"){for(var u=0;u<l.length;u++){var f=l[u];if(f.nodeType!==Node.TEXT_NODE&&f.nodeType!==Node.COMMENT_NODE){i.tasks.push(Oe(f))}}}return}}catch(e){b(e)}}if(e==="innerHTML"){Ue(r,n,i)}else{Be(Q.config.defaultSwapStyle,t,r,n,i)}}}function Ve(e){if(e.indexOf("<title")>-1){var t=e.replace(H,"");var r=t.match(q);if(r){return r[2]}}}function je(e,t,r,n,i,a){i.title=Ve(n);var o=l(n);if(o){Ce(r,o,i);o=Fe(r,o,a);Re(o);return Be(e,r,t,o,i)}}function _e(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=E(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!P(o)){o={value:o}}ce(r,a,o)}}}else{var s=n.split(",");for(var l=0;l<s.length;l++){ce(r,s[l].trim(),[])}}}var ze=/\s/;var x=/[\s,]/;var $e=/[_$a-zA-Z]/;var We=/[_$a-zA-Z0-9]/;var Ge=['"',"'","/"];var Je=/[^\s]/;var Ze=/[{(]/;var Ke=/[})]/;function Ye(e){var t=[];var r=0;while(r<e.length){if($e.exec(e.charAt(r))){var n=r;while(We.exec(e.charAt(r+1))){r++}t.push(e.substr(n,r-n+1))}else if(Ge.indexOf(e.charAt(r))!==-1){var i=e.charAt(r);var n=r;r++;while(r<e.length&&e.charAt(r)!==i){if(e.charAt(r)==="\\"){r++}r++}t.push(e.substr(n,r-n+1))}else{var a=e.charAt(r);t.push(a)}r++}return t}function Qe(e,t,r){return $e.exec(e.charAt(0))&&e!=="true"&&e!=="false"&&e!=="this"&&e!==r&&t!=="."}function et(e,t,r){if(t[0]==="["){t.shift();var n=1;var i=" return (function("+r+"){ return (";var a=null;while(t.length>0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=Tr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){fe(re().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if(Qe(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function y(e,t){var r="";while(e.length>0&&!t.test(e[0])){r+=e.shift()}return r}function tt(e){var t;if(e.length>0&&Ze.test(e[0])){e.shift();t=y(e,Ke).trim();e.shift()}else{t=y(e,x)}return t}var rt="input, textarea, select";function nt(e,t,r){var n=[];var i=Ye(t);do{y(i,Je);var a=i.length;var o=y(i,/[,\[\s]/);if(o!==""){if(o==="every"){var s={trigger:"every"};y(i,Je);s.pollInterval=d(y(i,/[,\[\s]/));y(i,Je);var l=et(e,i,"event");if(l){s.eventFilter=l}n.push(s)}else if(o.indexOf("sse:")===0){n.push({trigger:"sse",sseEvent:o.substr(4)})}else{var u={trigger:o};var l=et(e,i,"event");if(l){u.eventFilter=l}while(i.length>0&&i[0]!==","){y(i,Je);var f=i.shift();if(f==="changed"){u.changed=true}else if(f==="once"){u.once=true}else if(f==="consume"){u.consume=true}else if(f==="delay"&&i[0]===":"){i.shift();u.delay=d(y(i,x))}else if(f==="from"&&i[0]===":"){i.shift();if(Ze.test(i[0])){var c=tt(i)}else{var c=y(i,x);if(c==="closest"||c==="find"||c==="next"||c==="previous"){i.shift();var h=tt(i);if(h.length>0){c+=" "+h}}}u.from=c}else if(f==="target"&&i[0]===":"){i.shift();u.target=tt(i)}else if(f==="throttle"&&i[0]===":"){i.shift();u.throttle=d(y(i,x))}else if(f==="queue"&&i[0]===":"){i.shift();u.queue=y(i,x)}else if(f==="root"&&i[0]===":"){i.shift();u[f]=tt(i)}else if(f==="threshold"&&i[0]===":"){i.shift();u[f]=y(i,x)}else{fe(e,"htmx:syntax:error",{token:i.shift()})}}n.push(u)}}if(i.length===a){fe(e,"htmx:syntax:error",{token:i.shift()})}y(i,Je)}while(i[0]===","&&i.shift());if(r){r[t]=n}return n}function it(e){var t=te(e,"hx-trigger");var r=[];if(t){var n=Q.config.triggerSpecsCache;r=n&&n[t]||nt(e,t,n)}if(r.length>0){return r}else if(h(e,"form")){return[{trigger:"submit"}]}else if(h(e,'input[type="button"], input[type="submit"]')){return[{trigger:"click"}]}else if(h(e,rt)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function at(e){ae(e).cancelled=true}function ot(e,t,r){var n=ae(e);n.timeout=setTimeout(function(){if(se(e)&&n.cancelled!==true){if(!ct(r,e,Wt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}ot(e,t,r)}},r.pollInterval)}function st(e){return location.hostname===e.hostname&&ee(e,"href")&&ee(e,"href").indexOf("#")!==0}function lt(t,r,e){if(t.tagName==="A"&&st(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=ee(t,"href")}else{var a=ee(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=ee(t,"action")}e.forEach(function(e){ht(t,function(e,t){if(v(e,Q.config.disableSelector)){m(e);return}he(n,i,e,t)},r,e,true)})}}function ut(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(h(t,'input[type="submit"], button')&&v(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function ft(e,t){return ae(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function ct(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){fe(re().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function ht(a,o,e,s,l){var u=ae(a);var t;if(s.from){t=Z(a,s.from)}else{t=[a]}if(s.changed){t.forEach(function(e){var t=ae(e);t.lastValue=e.value})}oe(t,function(n){var i=function(e){if(!se(a)){n.removeEventListener(s.trigger,i);return}if(ft(a,e)){return}if(l||ut(e,a)){e.preventDefault()}if(ct(s,a,e)){return}var t=ae(e);t.triggerSpec=s;if(t.handledFor==null){t.handledFor=[]}if(t.handledFor.indexOf(a)<0){t.handledFor.push(a);if(s.consume){e.stopPropagation()}if(s.target&&e.target){if(!h(e.target,s.target)){return}}if(s.once){if(u.triggeredOnce){return}else{u.triggeredOnce=true}}if(s.changed){var r=ae(n);if(r.lastValue===n.value){return}r.lastValue=n.value}if(u.delayed){clearTimeout(u.delayed)}if(u.throttle){return}if(s.throttle>0){if(!u.throttle){o(a,e);u.throttle=setTimeout(function(){u.throttle=null},s.throttle)}}else if(s.delay>0){u.delayed=setTimeout(function(){o(a,e)},s.delay)}else{ce(a,"htmx:trigger");o(a,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:s.trigger,listener:i,on:n});n.addEventListener(s.trigger,i)})}var vt=false;var dt=null;function gt(){if(!dt){dt=function(){vt=true};window.addEventListener("scroll",dt);setInterval(function(){if(vt){vt=false;oe(re().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){pt(e)})}},200)}}function pt(t){if(!o(t,"data-hx-revealed")&&X(t)){t.setAttribute("data-hx-revealed","true");var e=ae(t);if(e.initHash){ce(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){ce(t,"revealed")},{once:true})}}}function mt(e,t,r){var n=D(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){xt(e,a[1],0)}if(a[0]==="send"){bt(e)}}}function xt(s,r,n){if(!se(s)){return}if(r.indexOf("/")==0){var e=location.hostname+(location.port?":"+location.port:"");if(location.protocol=="https:"){r="wss://"+e+r}else if(location.protocol=="http:"){r="ws://"+e+r}}var t=Q.createWebSocket(r);t.onerror=function(e){fe(s,"htmx:wsError",{error:e,socket:t});yt(s)};t.onclose=function(e){if([1006,1012,1013].indexOf(e.code)>=0){var t=wt(n);setTimeout(function(){xt(s,r,n+1)},t)}};t.onopen=function(e){n=0};ae(s).webSocket=t;t.addEventListener("message",function(e){if(yt(s)){return}var t=e.data;R(s,function(e){t=e.transformResponse(t,null,s)});var r=T(s);var n=l(t);var i=M(n.children);for(var a=0;a<i.length;a++){var o=i[a];Ee(te(o,"hx-swap-oob")||"true",o,r)}nr(r.tasks)})}function yt(e){if(!se(e)){ae(e).webSocket.close();return true}}function bt(u){var f=c(u,function(e){return ae(e).webSocket!=null});if(f){u.addEventListener(it(u)[0].trigger,function(e){var t=ae(f).webSocket;var r=xr(u,f);var n=dr(u,"post");var i=n.errors;var a=n.values;var o=Hr(u);var s=le(a,o);var l=yr(s,u);l["HEADERS"]=r;if(i&&i.length>0){ce(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(ut(e,u)){e.preventDefault()}})}else{fe(u,"htmx:noWebSocketSourceError")}}function wt(e){var t=Q.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}b('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function St(e,t,r){var n=D(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){Et(e,a[1])}if(a[0]==="swap"){Ct(e,a[1])}}}function Et(t,e){var r=Q.createEventSource(e);r.onerror=function(e){fe(t,"htmx:sseError",{error:e,source:r});Tt(t)};ae(t).sseEventSource=r}function Ct(a,o){var s=c(a,Ot);if(s){var l=ae(s).sseEventSource;var u=function(e){if(Tt(s)){return}if(!se(a)){l.removeEventListener(o,u);return}var t=e.data;R(a,function(e){t=e.transformResponse(t,null,a)});var r=wr(a);var n=ye(a);var i=T(a);je(r.swapStyle,n,a,t,i);nr(i.tasks);ce(a,"htmx:sseMessage",e)};ae(a).sseListener=u;l.addEventListener(o,u)}else{fe(a,"htmx:noSSESourceError")}}function Rt(e,t,r){var n=c(e,Ot);if(n){var i=ae(n).sseEventSource;var a=function(){if(!Tt(n)){if(se(e)){t(e)}else{i.removeEventListener(r,a)}}};ae(e).sseListener=a;i.addEventListener(r,a)}else{fe(e,"htmx:noSSESourceError")}}function Tt(e){if(!se(e)){ae(e).sseEventSource.close();return true}}function Ot(e){return ae(e).sseEventSource!=null}function qt(e,t,r,n){var i=function(){if(!r.loaded){r.loaded=true;t(e)}};if(n>0){setTimeout(i,n)}else{i()}}function Ht(t,i,e){var a=false;oe(w,function(r){if(o(t,"hx-"+r)){var n=te(t,"hx-"+r);a=true;i.path=n;i.verb=r;e.forEach(function(e){Lt(t,e,i,function(e,t){if(v(e,Q.config.disableSelector)){m(e);return}he(r,n,e,t)})})}});return a}function Lt(n,e,t,r){if(e.sseEvent){Rt(n,r,e.sseEvent)}else if(e.trigger==="revealed"){gt();ht(n,r,t,e);pt(n)}else if(e.trigger==="intersect"){var i={};if(e.root){i.root=ue(n,e.root)}if(e.threshold){i.threshold=parseFloat(e.threshold)}var a=new IntersectionObserver(function(e){for(var t=0;t<e.length;t++){var r=e[t];if(r.isIntersecting){ce(n,"intersect");break}}},i);a.observe(n);ht(n,r,t,e)}else if(e.trigger==="load"){if(!ct(e,n,Wt("load",{elt:n}))){qt(n,r,t,e.delay)}}else if(e.pollInterval>0){t.polling=true;ot(n,r,e)}else{ht(n,r,t,e)}}function At(e){if(!e.htmxExecuted&&Q.config.allowScriptTags&&(e.type==="text/javascript"||e.type==="module"||e.type==="")){var t=re().createElement("script");oe(e.attributes,function(e){t.setAttribute(e.name,e.value)});t.textContent=e.textContent;t.async=false;if(Q.config.inlineScriptNonce){t.nonce=Q.config.inlineScriptNonce}var r=e.parentElement;try{r.insertBefore(t,e)}catch(e){b(e)}finally{if(e.parentElement){e.parentElement.removeChild(e)}}}}function Nt(e){if(h(e,"script")){At(e)}oe(f(e,"script"),function(e){At(e)})}function It(e){var t=e.attributes;for(var r=0;r<t.length;r++){var n=t[r].name;if(g(n,"hx-on:")||g(n,"data-hx-on:")||g(n,"hx-on-")||g(n,"data-hx-on-")){return true}}return false}function kt(e){var t=null;var r=[];if(It(e)){r.push(e)}if(document.evaluate){var n=document.evaluate('.//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") or'+' starts-with(name(), "hx-on-") or starts-with(name(), "data-hx-on-") ]]',e);while(t=n.iterateNext())r.push(t)}else{var i=e.getElementsByTagName("*");for(var a=0;a<i.length;a++){if(It(i[a])){r.push(i[a])}}}return r}function Pt(e){if(e.querySelectorAll){var t=", [hx-boost] a, [data-hx-boost] a, a[hx-boost], a[data-hx-boost]";var r=e.querySelectorAll(i+t+", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws],"+" [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]");return r}else{return[]}}function Mt(e){var t=v(e.target,"button, input[type='submit']");var r=Dt(e);if(r){r.lastButtonClicked=t}}function Xt(e){var t=Dt(e);if(t){t.lastButtonClicked=null}}function Dt(e){var t=v(e.target,"button, input[type='submit']");if(!t){return}var r=p("#"+ee(t,"form"))||v(t,"form");if(!r){return}return ae(r)}function Ut(e){e.addEventListener("click",Mt);e.addEventListener("focusin",Mt);e.addEventListener("focusout",Xt)}function Ft(e){var t=Ye(e);var r=0;for(var n=0;n<t.length;n++){const i=t[n];if(i==="{"){r++}else if(i==="}"){r--}}return r}function Bt(t,e,r){var n=ae(t);if(!Array.isArray(n.onHandlers)){n.onHandlers=[]}var i;var a=function(e){return Tr(t,function(){if(!i){i=new Function("event",r)}i.call(t,e)})};t.addEventListener(e,a);n.onHandlers.push({event:e,listener:a})}function Vt(e){var t=te(e,"hx-on");if(t){var r={};var n=t.split("\n");var i=null;var a=0;while(n.length>0){var o=n.shift();var s=o.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/);if(a===0&&s){o.split(":");i=s[1].slice(0,-1);r[i]=s[2]}else{r[i]+=o}a+=Ft(o)}for(var l in r){Bt(e,l,r[l])}}}function jt(e){Ae(e);for(var t=0;t<e.attributes.length;t++){var r=e.attributes[t].name;var n=e.attributes[t].value;if(g(r,"hx-on")||g(r,"data-hx-on")){var i=r.indexOf("-on")+3;var a=r.slice(i,i+1);if(a==="-"||a===":"){var o=r.slice(i+1);if(g(o,":")){o="htmx"+o}else if(g(o,"-")){o="htmx:"+o.slice(1)}else if(g(o,"htmx-")){o="htmx:"+o.slice(5)}Bt(e,o,n)}}}}function _t(t){if(v(t,Q.config.disableSelector)){m(t);return}var r=ae(t);if(r.initHash!==Le(t)){Ne(t);r.initHash=Le(t);Vt(t);ce(t,"htmx:beforeProcessNode");if(t.value){r.lastValue=t.value}var e=it(t);var n=Ht(t,r,e);if(!n){if(ne(t,"hx-boost")==="true"){lt(t,r,e)}else if(o(t,"hx-trigger")){e.forEach(function(e){Lt(t,e,r,function(){})})}}if(t.tagName==="FORM"||ee(t,"type")==="submit"&&o(t,"form")){Ut(t)}var i=te(t,"hx-sse");if(i){St(t,r,i)}var a=te(t,"hx-ws");if(a){mt(t,r,a)}ce(t,"htmx:afterProcessNode")}}function zt(e){e=p(e);if(v(e,Q.config.disableSelector)){m(e);return}_t(e);oe(Pt(e),function(e){_t(e)});oe(kt(e),jt)}function $t(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}function Wt(e,t){var r;if(window.CustomEvent&&typeof window.CustomEvent==="function"){r=new CustomEvent(e,{bubbles:true,cancelable:true,detail:t})}else{r=re().createEvent("CustomEvent");r.initCustomEvent(e,true,true,t)}return r}function fe(e,t,r){ce(e,t,le({error:t},r))}function Gt(e){return e==="htmx:afterProcessNode"}function R(e,t){oe(Br(e),function(e){try{t(e)}catch(e){b(e)}})}function b(e){if(console.error){console.error(e)}else if(console.log){console.log("ERROR: ",e)}}function ce(e,t,r){e=p(e);if(r==null){r={}}r["elt"]=e;var n=Wt(t,r);if(Q.logger&&!Gt(t)){Q.logger(e,t,r)}if(r.error){b(r.error);ce(e,"htmx:error",{errorInfo:r})}var i=e.dispatchEvent(n);var a=$t(t);if(i&&a!==t){var o=Wt(a,n.detail);i=i&&e.dispatchEvent(o)}R(e,function(e){i=i&&(e.onEvent(t,n)!==false&&!n.defaultPrevented)});return i}var Jt=location.pathname+location.search;function Zt(){var e=re().querySelector("[hx-history-elt],[data-hx-history-elt]");return e||re().body}function Kt(e,t,r,n){if(!U()){return}if(Q.config.historyCacheSize<=0){localStorage.removeItem("htmx-history-cache");return}e=F(e);var i=E(localStorage.getItem("htmx-history-cache"))||[];for(var a=0;a<i.length;a++){if(i[a].url===e){i.splice(a,1);break}}var o={url:e,content:t,title:r,scroll:n};ce(re().body,"htmx:historyItemCreated",{item:o,cache:i});i.push(o);while(i.length>Q.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){fe(re().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Yt(e){if(!U()){return null}e=F(e);var t=E(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r<t.length;r++){if(t[r].url===e){return t[r]}}return null}function Qt(e){var t=Q.config.requestClass;var r=e.cloneNode(true);oe(f(r,"."+t),function(e){n(e,t)});return r.innerHTML}function er(){var e=Zt();var t=Jt||location.pathname+location.search;var r;try{r=re().querySelector('[hx-history="false" i],[data-hx-history="false" i]')}catch(e){r=re().querySelector('[hx-history="false"],[data-hx-history="false"]')}if(!r){ce(re().body,"htmx:beforeHistorySave",{path:t,historyElt:e});Kt(t,Qt(e),re().title,window.scrollY)}if(Q.config.historyEnabled)history.replaceState({htmx:true},re().title,window.location.href)}function tr(e){if(Q.config.getCacheBusterParam){e=e.replace(/org\.htmx\.cache-buster=[^&]*&?/,"");if(G(e,"&")||G(e,"?")){e=e.slice(0,-1)}}if(Q.config.historyEnabled){history.pushState({htmx:true},"",e)}Jt=e}function rr(e){if(Q.config.historyEnabled)history.replaceState({htmx:true},"",e);Jt=e}function nr(e){oe(e,function(e){e.call()})}function ir(a){var e=new XMLHttpRequest;var o={path:a,xhr:e};ce(re().body,"htmx:historyCacheMiss",o);e.open("GET",a,true);e.setRequestHeader("HX-Request","true");e.setRequestHeader("HX-History-Restore-Request","true");e.setRequestHeader("HX-Current-URL",re().location.href);e.onload=function(){if(this.status>=200&&this.status<400){ce(re().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Zt();var r=T(t);var n=Ve(this.response);if(n){var i=C("title");if(i){i.innerHTML=n}else{window.document.title=n}}Ue(t,e,r);nr(r.tasks);Jt=a;ce(re().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{fe(re().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function ar(e){er();e=e||location.pathname+location.search;var t=Yt(e);if(t){var r=l(t.content);var n=Zt();var i=T(n);Ue(n,r,i);nr(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Jt=e;ce(re().body,"htmx:historyRestore",{path:e,item:t})}else{if(Q.config.refreshOnHistoryMiss){window.location.reload(true)}else{ir(e)}}}function or(e){var t=me(e,"hx-indicator");if(t==null){t=[e]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,Q.config.requestClass)});return t}function sr(e){var t=me(e,"hx-disabled-elt");if(t==null){t=[]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.setAttribute("disabled","")});return t}function lr(e,t){oe(e,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,Q.config.requestClass)}});oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.removeAttribute("disabled")}})}function ur(e,t){for(var r=0;r<e.length;r++){var n=e[r];if(n.isSameNode(t)){return true}}return false}function fr(e){if(e.name===""||e.name==null||e.disabled||v(e,"fieldset[disabled]")){return false}if(e.type==="button"||e.type==="submit"||e.tagName==="image"||e.tagName==="reset"||e.tagName==="file"){return false}if(e.type==="checkbox"||e.type==="radio"){return e.checked}return true}function cr(e,t,r){if(e!=null&&t!=null){var n=r[e];if(n===undefined){r[e]=t}else if(Array.isArray(n)){if(Array.isArray(t)){r[e]=n.concat(t)}else{n.push(t)}}else{if(Array.isArray(t)){r[e]=[n].concat(t)}else{r[e]=[n,t]}}}}function hr(t,r,n,e,i){if(e==null||ur(t,e)){return}else{t.push(e)}if(fr(e)){var a=ee(e,"name");var o=e.value;if(e.multiple&&e.tagName==="SELECT"){o=M(e.querySelectorAll("option:checked")).map(function(e){return e.value})}if(e.files){o=M(e.files)}cr(a,o,r);if(i){vr(e,n)}}if(h(e,"form")){var s=e.elements;oe(s,function(e){hr(t,r,n,e,i)})}}function vr(e,t){if(e.willValidate){ce(e,"htmx:validation:validate");if(!e.checkValidity()){t.push({elt:e,message:e.validationMessage,validity:e.validity});ce(e,"htmx:validation:failed",{message:e.validationMessage,validity:e.validity})}}}function dr(e,t){var r=[];var n={};var i={};var a=[];var o=ae(e);if(o.lastButtonClicked&&!se(o.lastButtonClicked)){o.lastButtonClicked=null}var s=h(e,"form")&&e.noValidate!==true||te(e,"hx-validate")==="true";if(o.lastButtonClicked){s=s&&o.lastButtonClicked.formNoValidate!==true}if(t!=="get"){hr(r,i,a,v(e,"form"),s)}hr(r,n,a,e,s);if(o.lastButtonClicked||e.tagName==="BUTTON"||e.tagName==="INPUT"&&ee(e,"type")==="submit"){var l=o.lastButtonClicked||e;var u=ee(l,"name");cr(u,l.value,i)}var f=me(e,"hx-include");oe(f,function(e){hr(r,n,a,e,s);if(!h(e,"form")){oe(e.querySelectorAll(rt),function(e){hr(r,n,a,e,s)})}});n=le(n,i);return{errors:a,values:n}}function gr(e,t,r){if(e!==""){e+="&"}if(String(r)==="[object Object]"){r=JSON.stringify(r)}var n=encodeURIComponent(r);e+=encodeURIComponent(t)+"="+n;return e}function pr(e){var t="";for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){oe(n,function(e){t=gr(t,r,e)})}else{t=gr(t,r,n)}}}return t}function mr(e){var t=new FormData;for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){oe(n,function(e){t.append(r,e)})}else{t.append(r,n)}}}return t}function xr(e,t,r){var n={"HX-Request":"true","HX-Trigger":ee(e,"id"),"HX-Trigger-Name":ee(e,"name"),"HX-Target":te(t,"id"),"HX-Current-URL":re().location.href};Rr(e,"hx-headers",false,n);if(r!==undefined){n["HX-Prompt"]=r}if(ae(e).boosted){n["HX-Boosted"]="true"}return n}function yr(t,e){var r=ne(e,"hx-params");if(r){if(r==="none"){return{}}else if(r==="*"){return t}else if(r.indexOf("not ")===0){oe(r.substr(4).split(","),function(e){e=e.trim();delete t[e]});return t}else{var n={};oe(r.split(","),function(e){e=e.trim();n[e]=t[e]});return n}}else{return t}}function br(e){return ee(e,"href")&&ee(e,"href").indexOf("#")>=0}function wr(e,t){var r=t?t:ne(e,"hx-swap");var n={swapStyle:ae(e).boosted?"innerHTML":Q.config.defaultSwapStyle,swapDelay:Q.config.defaultSwapDelay,settleDelay:Q.config.defaultSettleDelay};if(Q.config.scrollIntoViewOnBoost&&ae(e).boosted&&!br(e)){n["show"]="top"}if(r){var i=D(r);if(i.length>0){for(var a=0;a<i.length;a++){var o=i[a];if(o.indexOf("swap:")===0){n["swapDelay"]=d(o.substr(5))}else if(o.indexOf("settle:")===0){n["settleDelay"]=d(o.substr(7))}else if(o.indexOf("transition:")===0){n["transition"]=o.substr(11)==="true"}else if(o.indexOf("ignoreTitle:")===0){n["ignoreTitle"]=o.substr(12)==="true"}else if(o.indexOf("scroll:")===0){var s=o.substr(7);var l=s.split(":");var u=l.pop();var f=l.length>0?l.join(":"):null;n["scroll"]=u;n["scrollTarget"]=f}else if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var f=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=f}else if(o.indexOf("focus-scroll:")===0){var v=o.substr("focus-scroll:".length);n["focusScroll"]=v=="true"}else if(a==0){n["swapStyle"]=o}else{b("Unknown modifier in hx-swap: "+o)}}}}return n}function Sr(e){return ne(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&ee(e,"enctype")==="multipart/form-data"}function Er(t,r,n){var i=null;R(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(Sr(r)){return mr(n)}else{return pr(n)}}}function T(e){return{tasks:[],elts:[e]}}function Cr(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=ue(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=ue(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:Q.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:Q.config.scrollBehavior})}}}function Rr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=te(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=Tr(e,function(){return Function("return ("+a+")")()},{})}else{s=E(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return Rr(u(e),t,r,n)}function Tr(e,t,r){if(Q.config.allowEval){return t()}else{fe(e,"htmx:evalDisallowedError");return r}}function Or(e,t){return Rr(e,"hx-vars",true,t)}function qr(e,t){return Rr(e,"hx-vals",false,t)}function Hr(e){return le(Or(e),qr(e))}function Lr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function Ar(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){fe(re().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function O(e,t){return t.test(e.getAllResponseHeaders())}function Nr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||I(r,"String")){return he(e,t,null,null,{targetOverride:p(r),returnPromise:true})}else{return he(e,t,p(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:p(r.target),swapOverride:r.swap,select:r.select,returnPromise:true})}}else{return he(e,t,null,null,{returnPromise:true})}}function Ir(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function kr(e,t,r){var n;var i;if(typeof URL==="function"){i=new URL(t,document.location.href);var a=document.location.origin;n=a===i.origin}else{i=t;n=g(t,document.location.origin)}if(Q.config.selfRequestsOnly){if(!n){return false}}return ce(e,"htmx:validateUrl",le({url:i,sameHost:n},r))}function he(t,r,n,i,a,e){var o=null;var s=null;a=a!=null?a:{};if(a.returnPromise&&typeof Promise!=="undefined"){var l=new Promise(function(e,t){o=e;s=t})}if(n==null){n=re().body}var M=a.handler||Mr;var X=a.select||null;if(!se(n)){ie(o);return l}var u=a.targetOverride||ye(n);if(u==null||u==pe){fe(n,"htmx:targetError",{target:te(n,"hx-target")});ie(s);return l}var f=ae(n);var c=f.lastButtonClicked;if(c){var h=ee(c,"formaction");if(h!=null){r=h}var v=ee(c,"formmethod");if(v!=null){if(v.toLowerCase()!=="dialog"){t=v}}}var d=ne(n,"hx-confirm");if(e===undefined){var D=function(e){return he(t,r,n,i,a,!!e)};var U={target:u,elt:n,path:r,verb:t,triggeringEvent:i,etc:a,issueRequest:D,question:d};if(ce(n,"htmx:confirm",U)===false){ie(o);return l}}var g=n;var p=ne(n,"hx-sync");var m=null;var x=false;if(p){var F=p.split(":");var B=F[0].trim();if(B==="this"){g=xe(n,"hx-sync")}else{g=ue(n,B)}p=(F[1]||"drop").trim();f=ae(g);if(p==="drop"&&f.xhr&&f.abortable!==true){ie(o);return l}else if(p==="abort"){if(f.xhr){ie(o);return l}else{x=true}}else if(p==="replace"){ce(g,"htmx:abort")}else if(p.indexOf("queue")===0){var V=p.split(" ");m=(V[1]||"last").trim()}}if(f.xhr){if(f.abortable){ce(g,"htmx:abort")}else{if(m==null){if(i){var y=ae(i);if(y&&y.triggerSpec&&y.triggerSpec.queue){m=y.triggerSpec.queue}}if(m==null){m="last"}}if(f.queuedRequests==null){f.queuedRequests=[]}if(m==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(m==="all"){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(m==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){he(t,r,n,i,a)})}ie(o);return l}}var b=new XMLHttpRequest;f.xhr=b;f.abortable=x;var w=function(){f.xhr=null;f.abortable=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var j=ne(n,"hx-prompt");if(j){var S=prompt(j);if(S===null||!ce(n,"htmx:prompt",{prompt:S,target:u})){ie(o);w();return l}}if(d&&!e){if(!confirm(d)){ie(o);w();return l}}var E=xr(n,u,S);if(t!=="get"&&!Sr(n)){E["Content-Type"]="application/x-www-form-urlencoded"}if(a.headers){E=le(E,a.headers)}var _=dr(n,t);var C=_.errors;var R=_.values;if(a.values){R=le(R,a.values)}var z=Hr(n);var $=le(R,z);var T=yr($,n);if(Q.config.getCacheBusterParam&&t==="get"){T["org.htmx.cache-buster"]=ee(u,"id")||"true"}if(r==null||r===""){r=re().location.href}var O=Rr(n,"hx-request");var W=ae(n).boosted;var q=Q.config.methodsThatUseUrlParams.indexOf(t)>=0;var H={boosted:W,useUrlParams:q,parameters:T,unfilteredParameters:$,headers:E,target:u,verb:t,errors:C,withCredentials:a.credentials||O.credentials||Q.config.withCredentials,timeout:a.timeout||O.timeout||Q.config.timeout,path:r,triggeringEvent:i};if(!ce(n,"htmx:configRequest",H)){ie(o);w();return l}r=H.path;t=H.verb;E=H.headers;T=H.parameters;C=H.errors;q=H.useUrlParams;if(C&&C.length>0){ce(n,"htmx:validation:halted",H);ie(o);w();return l}var G=r.split("#");var J=G[0];var L=G[1];var A=r;if(q){A=J;var Z=Object.keys(T).length!==0;if(Z){if(A.indexOf("?")<0){A+="?"}else{A+="&"}A+=pr(T);if(L){A+="#"+L}}}if(!kr(n,A,H)){fe(n,"htmx:invalidPath",H);ie(s);return l}b.open(t.toUpperCase(),A,true);b.overrideMimeType("text/html");b.withCredentials=H.withCredentials;b.timeout=H.timeout;if(O.noHeaders){}else{for(var N in E){if(E.hasOwnProperty(N)){var K=E[N];Lr(b,N,K)}}}var I={xhr:b,target:u,requestConfig:H,etc:a,boosted:W,select:X,pathInfo:{requestPath:r,finalRequestPath:A,anchor:L}};b.onload=function(){try{var e=Ir(n);I.pathInfo.responsePath=Ar(b);M(n,I);lr(k,P);ce(n,"htmx:afterRequest",I);ce(n,"htmx:afterOnLoad",I);if(!se(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(se(r)){t=r}}if(t){ce(t,"htmx:afterRequest",I);ce(t,"htmx:afterOnLoad",I)}}ie(o);w()}catch(e){fe(n,"htmx:onLoadError",le({error:e},I));throw e}};b.onerror=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendError",I);ie(s);w()};b.onabort=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendAbort",I);ie(s);w()};b.ontimeout=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:timeout",I);ie(s);w()};if(!ce(n,"htmx:beforeRequest",I)){ie(o);w();return l}var k=or(n);var P=sr(n);oe(["loadstart","loadend","progress","abort"],function(t){oe([b,b.upload],function(e){e.addEventListener(t,function(e){ce(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});ce(n,"htmx:beforeSend",I);var Y=q?null:Er(b,n,T);b.send(Y);return l}function Pr(e,t){var r=t.xhr;var n=null;var i=null;if(O(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(O(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(O(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=ne(e,"hx-push-url");var l=ne(e,"hx-replace-url");var u=ae(e).boosted;var f=null;var c=null;if(s){f="push";c=s}else if(l){f="replace";c=l}else if(u){f="push";c=o||a}if(c){if(c==="false"){return{}}if(c==="true"){c=o||a}if(t.pathInfo.anchor&&c.indexOf("#")===-1){c=c+"#"+t.pathInfo.anchor}return{type:f,path:c}}else{return{}}}function Mr(l,u){var f=u.xhr;var c=u.target;var e=u.etc;var t=u.requestConfig;var h=u.select;if(!ce(l,"htmx:beforeOnLoad",u))return;if(O(f,/HX-Trigger:/i)){_e(f,"HX-Trigger",l)}if(O(f,/HX-Location:/i)){er();var r=f.getResponseHeader("HX-Location");var v;if(r.indexOf("{")===0){v=E(r);r=v["path"];delete v["path"]}Nr("GET",r,v).then(function(){tr(r)});return}var n=O(f,/HX-Refresh:/i)&&"true"===f.getResponseHeader("HX-Refresh");if(O(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");n&&location.reload();return}if(n){location.reload();return}if(O(f,/HX-Retarget:/i)){if(f.getResponseHeader("HX-Retarget")==="this"){u.target=l}else{u.target=ue(l,f.getResponseHeader("HX-Retarget"))}}var d=Pr(l,u);var i=f.status>=200&&f.status<400&&f.status!==204;var g=f.response;var a=f.status>=400;var p=Q.config.ignoreTitle;var o=le({shouldSwap:i,serverResponse:g,isError:a,ignoreTitle:p},u);if(!ce(c,"htmx:beforeSwap",o))return;c=o.target;g=o.serverResponse;a=o.isError;p=o.ignoreTitle;u.target=c;u.failed=a;u.successful=!a;if(o.shouldSwap){if(f.status===286){at(l)}R(l,function(e){g=e.transformResponse(g,f,l)});if(d.type){er()}var s=e.swapOverride;if(O(f,/HX-Reswap:/i)){s=f.getResponseHeader("HX-Reswap")}var v=wr(l,s);if(v.hasOwnProperty("ignoreTitle")){p=v.ignoreTitle}c.classList.add(Q.config.swappingClass);var m=null;var x=null;var y=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r;if(h){r=h}if(O(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}if(d.type){ce(re().body,"htmx:beforeHistoryUpdate",le({history:d},u));if(d.type==="push"){tr(d.path);ce(re().body,"htmx:pushedIntoHistory",{path:d.path})}else{rr(d.path);ce(re().body,"htmx:replacedInHistory",{path:d.path})}}var n=T(c);je(v.swapStyle,c,l,g,n,r);if(t.elt&&!se(t.elt)&&ee(t.elt,"id")){var i=document.getElementById(ee(t.elt,"id"));var a={preventScroll:v.focusScroll!==undefined?!v.focusScroll:!Q.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(Q.config.swappingClass);oe(n.elts,function(e){if(e.classList){e.classList.add(Q.config.settlingClass)}ce(e,"htmx:afterSwap",u)});if(O(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!se(l)){o=re().body}_e(f,"HX-Trigger-After-Swap",o)}var s=function(){oe(n.tasks,function(e){e.call()});oe(n.elts,function(e){if(e.classList){e.classList.remove(Q.config.settlingClass)}ce(e,"htmx:afterSettle",u)});if(u.pathInfo.anchor){var e=re().getElementById(u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title&&!p){var t=C("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}Cr(n.elts,v);if(O(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!se(l)){r=re().body}_e(f,"HX-Trigger-After-Settle",r)}ie(m)};if(v.settleDelay>0){setTimeout(s,v.settleDelay)}else{s()}}catch(e){fe(l,"htmx:swapError",u);ie(x);throw e}};var b=Q.config.globalViewTransitions;if(v.hasOwnProperty("transition")){b=v.transition}if(b&&ce(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var w=new Promise(function(e,t){m=e;x=t});var S=y;y=function(){document.startViewTransition(function(){S();return w})}}if(v.swapDelay>0){setTimeout(y,v.swapDelay)}else{y()}}if(a){fe(l,"htmx:responseError",le({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var Xr={};function Dr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Ur(e,t){if(t.init){t.init(r)}Xr[e]=le(Dr(),t)}function Fr(e){delete Xr[e]}function Br(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=te(e,"hx-ext");if(t){oe(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=Xr[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Br(u(e),r,n)}var Vr=false;re().addEventListener("DOMContentLoaded",function(){Vr=true});function jr(e){if(Vr||re().readyState==="complete"){e()}else{re().addEventListener("DOMContentLoaded",e)}}function _r(){if(Q.config.includeIndicatorStyles!==false){re().head.insertAdjacentHTML("beforeend","<style> ."+Q.config.indicatorClass+"{opacity:0} ."+Q.config.requestClass+" ."+Q.config.indicatorClass+"{opacity:1; transition: opacity 200ms ease-in;} ."+Q.config.requestClass+"."+Q.config.indicatorClass+"{opacity:1; transition: opacity 200ms ease-in;} </style>")}}function zr(){var e=re().querySelector('meta[name="htmx-config"]');if(e){return E(e.content)}else{return null}}function $r(){var e=zr();if(e){Q.config=le(Q.config,e)}}jr(function(){$r();_r();var e=re().body;zt(e);var t=re().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ae(t);if(r&&r.xhr){r.xhr.abort()}});const r=window.onpopstate?window.onpopstate.bind(window):null;window.onpopstate=function(e){if(e.state&&e.state.htmx){ar();oe(t,function(e){ce(e,"htmx:restored",{document:re(),triggerEvent:ce})})}else{if(r){r(e)}}};setTimeout(function(){ce(e,"htmx:load",{});e=null},0)});return Q}()});