diff --git a/package-lock.json b/package-lock.json
index 9074f763..185a2acb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,15 +1,16 @@
{
"name": "cht-user-management",
- "version": "1.3.16",
+ "version": "1.3.17",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cht-user-management",
- "version": "1.3.16",
+ "version": "1.3.17",
"license": "ISC",
"dependencies": {
"@fastify/autoload": "^5.8.0",
+ "@fastify/compress": "^7.0.3",
"@fastify/cookie": "^9.2.0",
"@fastify/env": "^4.2.0",
"@fastify/formbody": "^7.4.0",
@@ -25,8 +26,9 @@
"axios-retry": "^4.0.0",
"csv": "^6.3.5",
"dotenv": "^16.3.1",
- "fastify": "^4.23.2",
+ "fastify": "^4.27.0",
"fastify-sse-v2": "^3.1.2",
+ "html-minifier": "^4.0.0",
"jsonwebtoken": "^9.0.2",
"jszip": "^3.10.1",
"libphonenumber-js": "^1.10.48",
@@ -42,6 +44,7 @@
"@types/chai": "^4.3.11",
"@types/chai-as-promised": "^7.1.8",
"@types/commander": "^2.12.2",
+ "@types/html-minifier": "^4.0.5",
"@types/mocha": "^10.0.6",
"@types/rewire": "^2.5.30",
"@types/sinon": "^17.0.2",
@@ -204,6 +207,36 @@
"node": ">=14"
}
},
+ "node_modules/@fastify/compress": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/@fastify/compress/-/compress-7.0.3.tgz",
+ "integrity": "sha512-xa9fo5/DgK1s0bkS6xrYgNn8HmofO5tJvbCDk8QuXshSgLd2cFZANv1ox/Qv7zswS7JroHwTlCVv/XGTVO98tg==",
+ "dependencies": {
+ "@fastify/accept-negotiator": "^1.1.0",
+ "fastify-plugin": "^4.5.0",
+ "mime-db": "^1.52.0",
+ "minipass": "^7.0.2",
+ "peek-stream": "^1.1.3",
+ "pump": "^3.0.0",
+ "pumpify": "^2.0.1",
+ "readable-stream": "^4.5.2"
+ }
+ },
+ "node_modules/@fastify/compress/node_modules/readable-stream": {
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
+ "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
+ "dependencies": {
+ "abort-controller": "^3.0.0",
+ "buffer": "^6.0.3",
+ "events": "^3.3.0",
+ "process": "^0.11.10",
+ "string_decoder": "^1.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
"node_modules/@fastify/cookie": {
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/@fastify/cookie/-/cookie-9.2.0.tgz",
@@ -592,6 +625,16 @@
"@types/chai": "*"
}
},
+ "node_modules/@types/clean-css": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/@types/clean-css/-/clean-css-4.2.11.tgz",
+ "integrity": "sha512-Y8n81lQVTAfP2TOdtJJEsCoYl1AnOkqDqMvXb9/7pfgZZ7r8YrEyurrAvAoAjHOGXKRybay+5CsExqIH6liccw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "source-map": "^0.6.0"
+ }
+ },
"node_modules/@types/commander": {
"version": "2.12.2",
"resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz",
@@ -602,6 +645,17 @@
"commander": "*"
}
},
+ "node_modules/@types/html-minifier": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@types/html-minifier/-/html-minifier-4.0.5.tgz",
+ "integrity": "sha512-LfE7f7MFd+YUfZnlBz8W43P4NgSObWiqyKapANsWCj63Aqeqli8/9gVsGP4CwC8jPpTTYlTopKCk9rJSuht/ew==",
+ "dev": true,
+ "dependencies": {
+ "@types/clean-css": "*",
+ "@types/relateurl": "*",
+ "@types/uglify-js": "*"
+ }
+ },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -647,6 +701,12 @@
"undici-types": "~5.26.4"
}
},
+ "node_modules/@types/relateurl": {
+ "version": "0.2.33",
+ "resolved": "https://registry.npmjs.org/@types/relateurl/-/relateurl-0.2.33.tgz",
+ "integrity": "sha512-bTQCKsVbIdzLqZhLkF5fcJQreE4y1ro4DIyVrlDNSCJRRwHhB8Z+4zXXa8jN6eDvc2HbRsEYgbvrnGvi54EpSw==",
+ "dev": true
+ },
"node_modules/@types/rewire": {
"version": "2.5.30",
"resolved": "https://registry.npmjs.org/@types/rewire/-/rewire-2.5.30.tgz",
@@ -674,6 +734,15 @@
"integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==",
"dev": true
},
+ "node_modules/@types/uglify-js": {
+ "version": "3.17.5",
+ "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.5.tgz",
+ "integrity": "sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ==",
+ "dev": true,
+ "dependencies": {
+ "source-map": "^0.6.1"
+ }
+ },
"node_modules/@types/uuid": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz",
@@ -1054,13 +1123,14 @@
}
},
"node_modules/avvio": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.2.1.tgz",
- "integrity": "sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==",
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.3.0.tgz",
+ "integrity": "sha512-VBVH0jubFr9LdFASy/vNtm5giTrnbVquWBhT0fyizuNK2rQ7e7ONU2plZQWUNqtE1EmxFEb+kbSkFRkstiaS9Q==",
"dependencies": {
+ "@fastify/error": "^3.3.0",
"archy": "^1.0.0",
"debug": "^4.0.0",
- "fastq": "^1.6.1"
+ "fastq": "^1.17.1"
}
},
"node_modules/axios": {
@@ -1174,8 +1244,7 @@
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
"node_modules/callsites": {
"version": "3.1.0",
@@ -1186,6 +1255,15 @@
"node": ">=6"
}
},
+ "node_modules/camel-case": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
+ "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==",
+ "dependencies": {
+ "no-case": "^2.2.0",
+ "upper-case": "^1.1.1"
+ }
+ },
"node_modules/camelcase": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
@@ -1307,6 +1385,17 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/clean-css": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz",
+ "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==",
+ "dependencies": {
+ "source-map": "~0.6.0"
+ },
+ "engines": {
+ "node": ">= 4.0"
+ }
+ },
"node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@@ -1567,6 +1656,44 @@
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
"dev": true
},
+ "node_modules/duplexify": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+ "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+ "dependencies": {
+ "end-of-stream": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "node_modules/duplexify/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/duplexify/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/duplexify/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -2040,9 +2167,9 @@
}
},
"node_modules/fast-redact": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz",
- "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==",
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz",
+ "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==",
"engines": {
"node": ">=6"
}
@@ -2058,20 +2185,30 @@
"integrity": "sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw=="
},
"node_modules/fastify": {
- "version": "4.25.2",
- "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.25.2.tgz",
- "integrity": "sha512-SywRouGleDHvRh054onj+lEZnbC1sBCLkR0UY3oyJwjD4BdZJUrxBqfkfCaqn74pVCwBaRHGuL3nEWeHbHzAfw==",
+ "version": "4.27.0",
+ "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.27.0.tgz",
+ "integrity": "sha512-ci9IXzbigB8dyi0mSy3faa3Bsj0xWAPb9JeT4KRzubdSb6pNhcADRUaXCBml6V1Ss/a05kbtQls5LBmhHydoTA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
"dependencies": {
"@fastify/ajv-compiler": "^3.5.0",
"@fastify/error": "^3.4.0",
"@fastify/fast-json-stringify-compiler": "^4.3.0",
"abstract-logging": "^2.0.1",
- "avvio": "^8.2.1",
+ "avvio": "^8.3.0",
"fast-content-type-parse": "^1.1.0",
"fast-json-stringify": "^5.8.0",
- "find-my-way": "^7.7.0",
+ "find-my-way": "^8.0.0",
"light-my-request": "^5.11.0",
- "pino": "^8.17.0",
+ "pino": "^9.0.0",
"process-warning": "^3.0.0",
"proxy-addr": "^2.0.7",
"rfdc": "^1.3.0",
@@ -2137,13 +2274,13 @@
}
},
"node_modules/find-my-way": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-7.7.0.tgz",
- "integrity": "sha512-+SrHpvQ52Q6W9f3wJoJBbAQULJuNEEQwBvlvYwACDhBTLOTMiQ0HYWh4+vC3OivGP2ENcTI1oKlFA2OepJNjhQ==",
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.0.tgz",
+ "integrity": "sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA==",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-querystring": "^1.0.0",
- "safe-regex2": "^2.0.0"
+ "safe-regex2": "^3.1.0"
},
"engines": {
"node": ">=14"
@@ -2418,7 +2555,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
- "dev": true,
"bin": {
"he": "bin/he"
}
@@ -2428,6 +2564,31 @@
"resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz",
"integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="
},
+ "node_modules/html-minifier": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz",
+ "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==",
+ "dependencies": {
+ "camel-case": "^3.0.0",
+ "clean-css": "^4.2.1",
+ "commander": "^2.19.0",
+ "he": "^1.2.0",
+ "param-case": "^2.1.1",
+ "relateurl": "^0.2.7",
+ "uglify-js": "^3.5.1"
+ },
+ "bin": {
+ "html-minifier": "cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/html-minifier/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ },
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@@ -2986,6 +3147,11 @@
"get-func-name": "^2.0.1"
}
},
+ "node_modules/lower-case": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
+ "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA=="
+ },
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -3191,6 +3357,14 @@
"path-to-regexp": "^6.2.1"
}
},
+ "node_modules/no-case": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
+ "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
+ "dependencies": {
+ "lower-case": "^1.1.1"
+ }
+ },
"node_modules/node-cleanup": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz",
@@ -3291,6 +3465,14 @@
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
+ "node_modules/param-case": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
+ "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==",
+ "dependencies": {
+ "no-case": "^2.2.0"
+ }
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -3391,6 +3573,16 @@
"through": "~2.3"
}
},
+ "node_modules/peek-stream": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz",
+ "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "duplexify": "^3.5.0",
+ "through2": "^2.0.3"
+ }
+ },
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@@ -3404,30 +3596,30 @@
}
},
"node_modules/pino": {
- "version": "8.17.2",
- "resolved": "https://registry.npmjs.org/pino/-/pino-8.17.2.tgz",
- "integrity": "sha512-LA6qKgeDMLr2ux2y/YiUt47EfgQ+S9LznBWOJdN3q1dx2sv0ziDLUBeVpyVv17TEcGCBuWf0zNtg3M5m1NhhWQ==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/pino/-/pino-9.0.0.tgz",
+ "integrity": "sha512-uI1ThkzTShNSwvsUM6b4ND8ANzWURk9zTELMztFkmnCQeR/4wkomJ+echHee5GMWGovoSfjwdeu80DsFIt7mbA==",
"dependencies": {
"atomic-sleep": "^1.0.0",
"fast-redact": "^3.1.1",
"on-exit-leak-free": "^2.1.0",
- "pino-abstract-transport": "v1.1.0",
+ "pino-abstract-transport": "^1.2.0",
"pino-std-serializers": "^6.0.0",
"process-warning": "^3.0.0",
"quick-format-unescaped": "^4.0.3",
"real-require": "^0.2.0",
"safe-stable-stringify": "^2.3.1",
"sonic-boom": "^3.7.0",
- "thread-stream": "^2.0.0"
+ "thread-stream": "^2.6.0"
},
"bin": {
"pino": "bin.js"
}
},
"node_modules/pino-abstract-transport": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz",
- "integrity": "sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz",
+ "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==",
"dependencies": {
"readable-stream": "^4.0.0",
"split2": "^4.0.0"
@@ -3560,6 +3752,27 @@
"once": "^1.3.1"
}
},
+ "node_modules/pumpify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz",
+ "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==",
+ "dependencies": {
+ "duplexify": "^4.1.1",
+ "inherits": "^2.0.3",
+ "pump": "^3.0.0"
+ }
+ },
+ "node_modules/pumpify/node_modules/duplexify": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz",
+ "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==",
+ "dependencies": {
+ "end-of-stream": "^1.4.1",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1",
+ "stream-shift": "^1.0.2"
+ }
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -3647,6 +3860,14 @@
"url": "https://github.com/sponsors/mysticatea"
}
},
+ "node_modules/relateurl": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+ "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -3691,11 +3912,11 @@
}
},
"node_modules/ret": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz",
- "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==",
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.4.3.tgz",
+ "integrity": "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==",
"engines": {
- "node": ">=4"
+ "node": ">=10"
}
},
"node_modules/reusify": {
@@ -3779,11 +4000,11 @@
]
},
"node_modules/safe-regex2": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz",
- "integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-3.1.0.tgz",
+ "integrity": "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==",
"dependencies": {
- "ret": "~0.2.0"
+ "ret": "~0.4.0"
}
},
"node_modules/safe-stable-stringify": {
@@ -3927,7 +4148,6 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -3979,6 +4199,11 @@
"duplexer": "~0.1.1"
}
},
+ "node_modules/stream-shift": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz",
+ "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ=="
+ },
"node_modules/stream-transform": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-3.3.0.tgz",
@@ -4119,9 +4344,9 @@
"dev": true
},
"node_modules/thread-stream": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.1.tgz",
- "integrity": "sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz",
+ "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==",
"dependencies": {
"real-require": "^0.2.0"
}
@@ -4132,6 +4357,42 @@
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"dev": true
},
+ "node_modules/through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dependencies": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "node_modules/through2/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/through2/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/through2/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -4303,11 +4564,27 @@
"node": ">=14.17"
}
},
+ "node_modules/uglify-js": {
+ "version": "3.17.4",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
+ "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
+ "node_modules/upper-case": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
+ "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA=="
+ },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -4392,6 +4669,14 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
diff --git a/package.json b/package.json
index 6320096e..39b4084d 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,10 @@
{
"name": "cht-user-management",
- "version": "1.3.16",
+ "version": "1.3.17",
"main": "dist/index.js",
"dependencies": {
"@fastify/autoload": "^5.8.0",
+ "@fastify/compress": "^7.0.3",
"@fastify/cookie": "^9.2.0",
"@fastify/env": "^4.2.0",
"@fastify/formbody": "^7.4.0",
@@ -19,8 +20,9 @@
"axios-retry": "^4.0.0",
"csv": "^6.3.5",
"dotenv": "^16.3.1",
- "fastify": "^4.23.2",
+ "fastify": "^4.27.0",
"fastify-sse-v2": "^3.1.2",
+ "html-minifier": "^4.0.0",
"jsonwebtoken": "^9.0.2",
"jszip": "^3.10.1",
"libphonenumber-js": "^1.10.48",
@@ -34,8 +36,9 @@
"devDependencies": {
"@medic/eslint-config": "^1.1.0",
"@types/chai": "^4.3.11",
- "@types/commander": "^2.12.2",
"@types/chai-as-promised": "^7.1.8",
+ "@types/commander": "^2.12.2",
+ "@types/html-minifier": "^4.0.5",
"@types/mocha": "^10.0.6",
"@types/rewire": "^2.5.30",
"@types/sinon": "^17.0.2",
diff --git a/src/liquid/app/fragment_home.html b/src/liquid/app/fragment_home.html
index 4af292f8..7ba65887 100644
--- a/src/liquid/app/fragment_home.html
+++ b/src/liquid/app/fragment_home.html
@@ -1,13 +1,6 @@
-
+
{% include "place/directive.html" %}
- {% include "place/list.html" %}
+ {% include "place/list_lazy.html" %}
\ No newline at end of file
diff --git a/src/liquid/components/button_upload.html b/src/liquid/components/button_upload.html
index 5d5f7459..7e89fe70 100644
--- a/src/liquid/components/button_upload.html
+++ b/src/liquid/components/button_upload.html
@@ -1,3 +1,3 @@
-
+
group_add Upload
\ No newline at end of file
diff --git a/src/liquid/components/place_item.html b/src/liquid/components/place_item.html
new file mode 100644
index 00000000..80d1f4ae
--- /dev/null
+++ b/src/liquid/components/place_item.html
@@ -0,0 +1,88 @@
+
+ {% for hierarchy in contactType.hierarchy %}
+ {% capture propertyName %}hierarchy_{{ hierarchy.property_name }}{% endcapture %}
+ {%
+ include "components/list_cell.html"
+ propertyName=propertyName
+ property=hierarchy
+ values=place.hierarchyProperties
+ linkTo=place.resolvedHierarchy[hierarchy.level]
+ %}
+ {% endfor %}
+
+ {% for property in contactType.place_properties %}
+ {% if property.type != 'generated' %}
+ {% capture propertyName %}place_{{ property.property_name }}{% endcapture %}
+ {%
+ include "components/list_cell.html"
+ propertyName=propertyName
+ property=property
+ values=place.properties
+ %}
+ {% endif %}
+ {% endfor %}
+
+ {% for contact_property in contactType.contact_properties %}
+ {% if contact_property.type != 'generated' %}
+ {% capture propertyName %}contact_{{ contact_property.property_name }}{% endcapture %}
+ {%
+ include "components/list_cell.html"
+ propertyName=propertyName
+ property=contact_property
+ values=place.contact.properties
+ %}
+ {% endif %}
+ {% endfor %}
+
+ {% if contactType.user_role.size > 1 %}
+ {% capture propertyName %}user_{{ contactType.userRoleProperty.property_name }}{% endcapture %}
+ {%
+ include "components/list_cell.html"
+ propertyName=propertyName
+ property=contactType.userRoleProperty
+ values=place.userRoleProperties
+ %}
+ {% endif %}
+
+
+ {% capture tag_text %}{% if place.validationErrors == empty %}{{ place.state }}{% else %}invalid{% endif %}{%
+ endcapture %}
+ {% capture tag_class %}
+ {% if place.state == 'failure' %}is-danger
+ {% elsif place.state == 'success' %}is-success
+ {% elsif place.validationErrors != empty %}is-warning
+ {% endif %}
+ {% if place.uploadError %}has-tooltip-arrow has-tooltipl-multiline{% endif %}
+ {% endcapture %}
+
+ {{ tag_text }}
+
+
+
+
+ {% if place.creationDetails.password %}
+ {% capture explanation %}Username: {{ place.creationDetails.username }} Password: {{ place.creationDetails.password }}{% endcapture %}
+
+ key
+
+ {% else %}
+
+ edit
+
+
+ refresh
+
+ {% if place.validationErrors == empty %}
+
+ upload
+
+ {%endif%}
+ {%endif%}
+
+ delete
+
+
\ No newline at end of file
diff --git a/src/liquid/components/table_header.html b/src/liquid/components/table_header.html
new file mode 100644
index 00000000..e90f20a9
--- /dev/null
+++ b/src/liquid/components/table_header.html
@@ -0,0 +1,22 @@
+
+
+ {% for hierarchy in contactType.hierarchy %}
+ {{ hierarchy.friendly_name }}
+ {% endfor %}
+ {% for property in contactType.place_properties %}
+ {% if property.type != 'generated' %}
+ {{property.friendly_name}}
+ {% endif %}
+ {% endfor %}
+ {% for contact_property in contactType.contact_properties %}
+ {% if contact_property.type != 'generated' %}
+ {{contact_property.friendly_name}}
+ {% endif %}
+ {% endfor %}
+ {% if contactType.user_role.size > 1 %}
+ {{ contactType.userRoleProperty.friendly_name }}
+ {% endif %}
+
+
+
+
\ No newline at end of file
diff --git a/src/liquid/place/bulk_create_form.html b/src/liquid/place/bulk_create_form.html
index 73eaeed3..105842cf 100644
--- a/src/liquid/place/bulk_create_form.html
+++ b/src/liquid/place/bulk_create_form.html
@@ -4,8 +4,10 @@
hx-encoding='multipart/form-data'
autocomplete="off"
hx-post="/place?op=bulk&type={{contactType.name}}"
+ hx-disabled-elt="button#place_create_submit, a#cancel"
+ hx-indicator="#place_create_submit_progress"
hx-target="this"
- hx-swap="outerHTML"
+ hx-swap="outerHTML"
>
@@ -39,6 +41,9 @@
Cancel
+
diff --git a/src/liquid/place/directive.html b/src/liquid/place/directive.html
index 8e62067c..d8c23307 100644
--- a/src/liquid/place/directive.html
+++ b/src/liquid/place/directive.html
@@ -1,7 +1,8 @@
-
+
-
+
{% if directiveModel.inProgressCount > 0 %}
{% include "place/directive_3_in_progress.html" %}
{% elsif directiveModel.stagedCount > 0 %}
diff --git a/src/liquid/place/directive_2_prompt_upload.html b/src/liquid/place/directive_2_prompt_upload.html
index da1efc62..daeacd34 100644
--- a/src/liquid/place/directive_2_prompt_upload.html
+++ b/src/liquid/place/directive_2_prompt_upload.html
@@ -8,7 +8,7 @@
diff --git a/src/liquid/place/list.html b/src/liquid/place/list.html
index e5c82978..1cfc0afa 100644
--- a/src/liquid/place/list.html
+++ b/src/liquid/place/list.html
@@ -1,4 +1,4 @@
-
+
{% for contactType in contactTypes %}
diff --git a/src/liquid/place/list_event.html b/src/liquid/place/list_event.html
deleted file mode 100644
index fab2ab40..00000000
--- a/src/liquid/place/list_event.html
+++ /dev/null
@@ -1,2 +0,0 @@
-{% include "place/directive.html" %}
-{% include "place/list.html" %}
\ No newline at end of file
diff --git a/src/liquid/place/list_lazy.html b/src/liquid/place/list_lazy.html
new file mode 100644
index 00000000..1f2e8f69
--- /dev/null
+++ b/src/liquid/place/list_lazy.html
@@ -0,0 +1,15 @@
+
+ {% for contactType in contactTypes %}
+
+
\ No newline at end of file
diff --git a/src/public/htmx.min.js b/src/public/htmx.min.js
index 5ac90417..de5f0f1a 100644
--- a/src/public/htmx.min.js
+++ b/src/public/htmx.min.js
@@ -1 +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 Y={onLoad:t,process:Pt,on:Z,off:K,trigger:fe,ajax:wr,find:E,findAll:f,closest:v,values:function(e,t){var r=nr(e,t||"post");return r.values},remove:U,addClass:B,removeClass:n,toggleClass:V,takeClass:j,defineExtension:qr,removeExtension:Hr,logAll:X,logNone:F,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},parseInterval:d,_:e,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=Y.config.wsBinaryType;return t},version:"1.9.6"};var r={addTriggerHandler:St,bodyContains:oe,canAccessLocalStorage:M,findThisElement:de,filterValues:lr,hasAttribute:o,getAttributeValue:ee,getClosestAttributeValue:re,getClosestMatch:c,getExpressionVars:xr,getHeaders:sr,getInputValues:nr,getInternalData:ie,getSwapSpecification:fr,getTriggerSpecs:Ze,getTarget:ge,makeFragment:l,mergeObjects:se,makeSettleInfo:T,oobSwap:ye,querySelectorExt:le,selectAndSwap:Fe,settleImmediately:Wt,shouldCancel:tt,triggerEvent:fe,triggerErrorEvent:ue,withExtensions:C};var b=["get","post","put","delete","patch"];var w=b.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");function d(e){if(e==undefined){return undefined}if(e.slice(-2)=="ms"){return parseFloat(e.slice(0,-2))||undefined}if(e.slice(-1)=="s"){return parseFloat(e.slice(0,-1))*1e3||undefined}if(e.slice(-1)=="m"){return parseFloat(e.slice(0,-1))*1e3*60||undefined}return parseFloat(e)||undefined}function Q(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function ee(e,t){return Q(e,t)||Q(e,"data-"+t)}function u(e){return e.parentElement}function te(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function O(e,t,r){var n=ee(t,r);var i=ee(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function re(t,r){var n=null;c(t,function(e){return n=O(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 q(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 i(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=te().createDocumentFragment()}return i}function H(e){return e.match(/
"+e+" ",0);return r.querySelector("template").content}else{var n=q(e);switch(n){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return i("
",1);case"col":return i("
",2);case"tr":return i("
",2);case"td":case"th":return i("
",3);case"script":case"style":return i("
"+e+"
",1);default:return i(e,0)}}}function ne(e){if(e){e()}}function L(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function A(e){return L(e,"Function")}function N(e){return L(e,"Object")}function ie(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function I(e){var t=[];if(e){for(var r=0;r
=0}function oe(e){if(e.getRootNode&&e.getRootNode()instanceof window.ShadowRoot){return te().body.contains(e.getRootNode().host)}else{return te().body.contains(e)}}function k(e){return e.trim().split(/\s+/)}function se(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function S(e){try{return JSON.parse(e)}catch(e){y(e);return null}}function M(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function D(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!t.match("^/$")){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function e(e){return gr(te().body,function(){return eval(e)})}function t(t){var e=Y.on("htmx:load",function(e){t(e.detail.elt)});return e}function X(){Y.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function F(){Y.logger=null}function E(e,t){if(t){return e.querySelector(t)}else{return E(te(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(te(),e)}}function U(e,t){e=s(e);if(t){setTimeout(function(){U(e);e=null},t)}else{e.parentElement.removeChild(e)}}function B(e,t,r){e=s(e);if(r){setTimeout(function(){B(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=s(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 V(e,t){e=s(e);e.classList.toggle(t)}function j(e,t){e=s(e);ae(e.parentElement.children,function(e){n(e,t)});B(e,t)}function v(e,t){e=s(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 _(e,t){return e.substring(e.length-t.length)===t}function z(e){var t=e.trim();if(g(t,"<")&&_(t,"/>")){return t.substring(1,t.length-2)}else{return t}}function W(e,t){if(t.indexOf("closest ")===0){return[v(e,z(t.substr(8)))]}else if(t.indexOf("find ")===0){return[E(e,z(t.substr(5)))]}else if(t.indexOf("next ")===0){return[$(e,z(t.substr(5)))]}else if(t.indexOf("previous ")===0){return[G(e,z(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else if(t==="body"){return[document.body]}else{return te().querySelectorAll(z(t))}}var $=function(e,t){var r=te().querySelectorAll(t);for(var n=0;n=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function le(e,t){if(t){return W(e,t)[0]}else{return W(te().body,e)[0]}}function s(e){if(L(e,"String")){return E(e)}else{return e}}function J(e,t,r){if(A(t)){return{target:te().body,event:e,listener:t}}else{return{target:s(e),event:t,listener:r}}}function Z(t,r,n){Nr(function(){var e=J(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=A(r);return e?r:n}function K(t,r,n){Nr(function(){var e=J(t,r,n);e.target.removeEventListener(e.event,e.listener)});return A(r)?r:n}var he=te().createElement("output");function ve(e,t){var r=re(e,t);if(r){if(r==="this"){return[de(e,t)]}else{var n=W(e,r);if(n.length===0){y('The selector "'+r+'" on '+t+" returned no matches!");return[he]}else{return n}}}}function de(e,t){return c(e,function(e){return ee(e,t)!=null})}function ge(e){var t=re(e,"hx-target");if(t){if(t==="this"){return de(e,"hx-target")}else{return le(e,t)}}else{var r=ie(e);if(r.boosted){return te().body}else{return e}}}function me(e){var t=Y.config.attributesToSettle;for(var r=0;r0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=te().querySelectorAll(t);if(r){ae(r,function(e){var t;var r=i.cloneNode(true);t=te().createDocumentFragment();t.appendChild(r);if(!xe(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!fe(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){De(o,e,e,t,a)}ae(a.elts,function(e){fe(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);ue(te().body,"htmx:oobErrorNoTarget",{content:i})}return e}function be(e,t,r){var n=re(e,"hx-select-oob");if(n){var i=n.split(",");for(let e=0;e0){var r=t.replace("'","\\'");var n=e.tagName.replace(":","\\:");var i=o.querySelector(n+"[id='"+r+"']");if(i&&i!==o){var a=e.cloneNode();pe(e,i);s.tasks.push(function(){pe(e,a)})}}})}function Ee(e){return function(){n(e,Y.config.addedClass);Pt(e);Ct(e);Ce(e);fe(e,"htmx:load")}}function Ce(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function a(e,t,r,n){Se(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;B(i,Y.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(Ee(i))}}}function Te(e,t){var r=0;while(r-1){var t=e.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,"");var r=t.match(/]*>|>)([\s\S]*?)<\/title>/im);if(r){return r[2]}}}function Fe(e,t,r,n,i,a){i.title=Xe(n);var o=l(n);if(o){be(r,o,i);o=Me(r,o,a);we(o);return De(e,r,t,o,i)}}function Ue(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=S(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!N(o)){o={value:o}}fe(r,a,o)}}}else{var s=n.split(",");for(var l=0;l0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=gr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){ue(te().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if($e(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function x(e,t){var r="";while(e.length>0&&!e[0].match(t)){r+=e.shift()}return r}var Je="input, textarea, select";function Ze(e){var t=ee(e,"hx-trigger");var r=[];if(t){var n=We(t);do{x(n,ze);var i=n.length;var a=x(n,/[,\[\s]/);if(a!==""){if(a==="every"){var o={trigger:"every"};x(n,ze);o.pollInterval=d(x(n,/[,\[\s]/));x(n,ze);var s=Ge(e,n,"event");if(s){o.eventFilter=s}r.push(o)}else if(a.indexOf("sse:")===0){r.push({trigger:"sse",sseEvent:a.substr(4)})}else{var l={trigger:a};var s=Ge(e,n,"event");if(s){l.eventFilter=s}while(n.length>0&&n[0]!==","){x(n,ze);var u=n.shift();if(u==="changed"){l.changed=true}else if(u==="once"){l.once=true}else if(u==="consume"){l.consume=true}else if(u==="delay"&&n[0]===":"){n.shift();l.delay=d(x(n,p))}else if(u==="from"&&n[0]===":"){n.shift();var f=x(n,p);if(f==="closest"||f==="find"||f==="next"||f==="previous"){n.shift();f+=" "+x(n,p)}l.from=f}else if(u==="target"&&n[0]===":"){n.shift();l.target=x(n,p)}else if(u==="throttle"&&n[0]===":"){n.shift();l.throttle=d(x(n,p))}else if(u==="queue"&&n[0]===":"){n.shift();l.queue=x(n,p)}else if((u==="root"||u==="threshold")&&n[0]===":"){n.shift();l[u]=x(n,p)}else{ue(e,"htmx:syntax:error",{token:n.shift()})}}r.push(l)}}if(n.length===i){ue(e,"htmx:syntax:error",{token:n.shift()})}x(n,ze)}while(n[0]===","&&n.shift())}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,Je)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function Ke(e){ie(e).cancelled=true}function Ye(e,t,r){var n=ie(e);n.timeout=setTimeout(function(){if(oe(e)&&n.cancelled!==true){if(!nt(r,e,Mt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}Ye(e,t,r)}},r.pollInterval)}function Qe(e){return location.hostname===e.hostname&&Q(e,"href")&&Q(e,"href").indexOf("#")!==0}function et(t,r,e){if(t.tagName==="A"&&Qe(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=Q(t,"href")}else{var a=Q(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=Q(t,"action")}e.forEach(function(e){it(t,function(e,t){if(v(e,Y.config.disableSelector)){m(e);return}ce(n,i,e,t)},r,e,true)})}}function tt(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 rt(e,t){return ie(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function nt(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){ue(te().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function it(a,o,e,s,l){var u=ie(a);var t;if(s.from){t=W(a,s.from)}else{t=[a]}if(s.changed){t.forEach(function(e){var t=ie(e);t.lastValue=e.value})}ae(t,function(n){var i=function(e){if(!oe(a)){n.removeEventListener(s.trigger,i);return}if(rt(a,e)){return}if(l||tt(e,a)){e.preventDefault()}if(nt(s,a,e)){return}var t=ie(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=ie(n);if(r.lastValue===n.value){return}r.lastValue=n.value}if(u.delayed){clearTimeout(u.delayed)}if(u.throttle){return}if(s.throttle){if(!u.throttle){o(a,e);u.throttle=setTimeout(function(){u.throttle=null},s.throttle)}}else if(s.delay){u.delayed=setTimeout(function(){o(a,e)},s.delay)}else{fe(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 at=false;var ot=null;function st(){if(!ot){ot=function(){at=true};window.addEventListener("scroll",ot);setInterval(function(){if(at){at=false;ae(te().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){lt(e)})}},200)}}function lt(t){if(!o(t,"data-hx-revealed")&&P(t)){t.setAttribute("data-hx-revealed","true");var e=ie(t);if(e.initHash){fe(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){fe(t,"revealed")},{once:true})}}}function ut(e,t,r){var n=k(r);for(var i=0;i=0){var t=vt(n);setTimeout(function(){ft(s,r,n+1)},t)}};t.onopen=function(e){n=0};ie(s).webSocket=t;t.addEventListener("message",function(e){if(ct(s)){return}var t=e.data;C(s,function(e){t=e.transformResponse(t,null,s)});var r=T(s);var n=l(t);var i=I(n.children);for(var a=0;a0){fe(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(tt(e,u)){e.preventDefault()}})}else{ue(u,"htmx:noWebSocketSourceError")}}function vt(e){var t=Y.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()}y('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function dt(e,t,r){var n=k(r);for(var i=0;i0){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+=Ht(o)}for(var l in r){Lt(e,l,r[l])}}}function Nt(t){Oe(t);for(var e=0;eY.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){ue(te().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Bt(e){if(!M()){return null}e=D(e);var t=S(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r=200&&this.status<400){fe(te().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Ft();var r=T(t);var n=Xe(this.response);if(n){var i=E("title");if(i){i.innerHTML=n}else{window.document.title=n}}ke(t,e,r);Wt(r.tasks);Xt=a;fe(te().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{ue(te().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function Gt(e){jt();e=e||location.pathname+location.search;var t=Bt(e);if(t){var r=l(t.content);var n=Ft();var i=T(n);ke(n,r,i);Wt(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Xt=e;fe(te().body,"htmx:historyRestore",{path:e,item:t})}else{if(Y.config.refreshOnHistoryMiss){window.location.reload(true)}else{$t(e)}}}function Jt(e){var t=ve(e,"hx-indicator");if(t==null){t=[e]}ae(t,function(e){var t=ie(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,Y.config.requestClass)});return t}function Zt(e){var t=ve(e,"hx-disabled-elt");if(t==null){t=[]}ae(t,function(e){var t=ie(e);t.requestCount=(t.requestCount||0)+1;e.setAttribute("disabled","")});return t}function Kt(e,t){ae(e,function(e){var t=ie(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,Y.config.requestClass)}});ae(t,function(e){var t=ie(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.removeAttribute("disabled")}})}function Yt(e,t){for(var r=0;r=0}function fr(e,t){var r=t?t:re(e,"hx-swap");var n={swapStyle:ie(e).boosted?"innerHTML":Y.config.defaultSwapStyle,swapDelay:Y.config.defaultSwapDelay,settleDelay:Y.config.defaultSettleDelay};if(ie(e).boosted&&!ur(e)){n["show"]="top"}if(r){var i=k(r);if(i.length>0){for(var a=0;a0?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{y("Unknown modifier in hx-swap: "+o)}}}}return n}function cr(e){return re(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&Q(e,"enctype")==="multipart/form-data"}function hr(t,r,n){var i=null;C(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(cr(r)){return or(n)}else{return ar(n)}}}function T(e){return{tasks:[],elts:[e]}}function vr(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=le(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=le(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:Y.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:Y.config.scrollBehavior})}}}function dr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=ee(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=gr(e,function(){return Function("return ("+a+")")()},{})}else{s=S(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return dr(u(e),t,r,n)}function gr(e,t,r){if(Y.config.allowEval){return t()}else{ue(e,"htmx:evalDisallowedError");return r}}function mr(e,t){return dr(e,"hx-vars",true,t)}function pr(e,t){return dr(e,"hx-vals",false,t)}function xr(e){return se(mr(e),pr(e))}function yr(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 br(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){ue(te().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function R(e,t){return e.getAllResponseHeaders().match(t)}function wr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||L(r,"String")){return ce(e,t,null,null,{targetOverride:s(r),returnPromise:true})}else{return ce(e,t,s(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:s(r.target),swapOverride:r.swap,returnPromise:true})}}else{return ce(e,t,null,null,{returnPromise:true})}}function Sr(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function Er(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(Y.config.selfRequestsOnly){if(!n){return false}}return fe(e,"htmx:validateUrl",se({url:i,sameHost:n},r))}function ce(e,t,n,r,i,M){var a=null;var o=null;i=i!=null?i:{};if(i.returnPromise&&typeof Promise!=="undefined"){var s=new Promise(function(e,t){a=e;o=t})}if(n==null){n=te().body}var D=i.handler||Tr;if(!oe(n)){ne(a);return s}var l=i.targetOverride||ge(n);if(l==null||l==he){ue(n,"htmx:targetError",{target:ee(n,"hx-target")});ne(o);return s}var u=ie(n);var f=u.lastButtonClicked;if(f){var c=Q(f,"formaction");if(c!=null){t=c}var h=Q(f,"formmethod");if(h!=null){e=h}}if(!M){var X=function(){return ce(e,t,n,r,i,true)};var F={target:l,elt:n,path:t,verb:e,triggeringEvent:r,etc:i,issueRequest:X};if(fe(n,"htmx:confirm",F)===false){ne(a);return s}}var v=n;var d=re(n,"hx-sync");var g=null;var m=false;if(d){var p=d.split(":");var x=p[0].trim();if(x==="this"){v=de(n,"hx-sync")}else{v=le(n,x)}d=(p[1]||"drop").trim();u=ie(v);if(d==="drop"&&u.xhr&&u.abortable!==true){ne(a);return s}else if(d==="abort"){if(u.xhr){ne(a);return s}else{m=true}}else if(d==="replace"){fe(v,"htmx:abort")}else if(d.indexOf("queue")===0){var U=d.split(" ");g=(U[1]||"last").trim()}}if(u.xhr){if(u.abortable){fe(v,"htmx:abort")}else{if(g==null){if(r){var y=ie(r);if(y&&y.triggerSpec&&y.triggerSpec.queue){g=y.triggerSpec.queue}}if(g==null){g="last"}}if(u.queuedRequests==null){u.queuedRequests=[]}if(g==="first"&&u.queuedRequests.length===0){u.queuedRequests.push(function(){ce(e,t,n,r,i)})}else if(g==="all"){u.queuedRequests.push(function(){ce(e,t,n,r,i)})}else if(g==="last"){u.queuedRequests=[];u.queuedRequests.push(function(){ce(e,t,n,r,i)})}ne(a);return s}}var b=new XMLHttpRequest;u.xhr=b;u.abortable=m;var w=function(){u.xhr=null;u.abortable=false;if(u.queuedRequests!=null&&u.queuedRequests.length>0){var e=u.queuedRequests.shift();e()}};var B=re(n,"hx-prompt");if(B){var S=prompt(B);if(S===null||!fe(n,"htmx:prompt",{prompt:S,target:l})){ne(a);w();return s}}var V=re(n,"hx-confirm");if(V){if(!confirm(V)){ne(a);w();return s}}var E=sr(n,l,S);if(i.headers){E=se(E,i.headers)}var j=nr(n,e);var C=j.errors;var T=j.values;if(i.values){T=se(T,i.values)}var _=xr(n);var z=se(T,_);var R=lr(z,n);if(e!=="get"&&!cr(n)){E["Content-Type"]="application/x-www-form-urlencoded"}if(Y.config.getCacheBusterParam&&e==="get"){R["org.htmx.cache-buster"]=Q(l,"id")||"true"}if(t==null||t===""){t=te().location.href}var O=dr(n,"hx-request");var W=ie(n).boosted;var q=Y.config.methodsThatUseUrlParams.indexOf(e)>=0;var H={boosted:W,useUrlParams:q,parameters:R,unfilteredParameters:z,headers:E,target:l,verb:e,errors:C,withCredentials:i.credentials||O.credentials||Y.config.withCredentials,timeout:i.timeout||O.timeout||Y.config.timeout,path:t,triggeringEvent:r};if(!fe(n,"htmx:configRequest",H)){ne(a);w();return s}t=H.path;e=H.verb;E=H.headers;R=H.parameters;C=H.errors;q=H.useUrlParams;if(C&&C.length>0){fe(n,"htmx:validation:halted",H);ne(a);w();return s}var $=t.split("#");var G=$[0];var L=$[1];var A=t;if(q){A=G;var J=Object.keys(R).length!==0;if(J){if(A.indexOf("?")<0){A+="?"}else{A+="&"}A+=ar(R);if(L){A+="#"+L}}}if(!Er(n,A,H)){ue(n,"htmx:invalidPath",H);ne(o);return s}b.open(e.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 Z=E[N];yr(b,N,Z)}}}var I={xhr:b,target:l,requestConfig:H,etc:i,boosted:W,pathInfo:{requestPath:t,finalRequestPath:A,anchor:L}};b.onload=function(){try{var e=Sr(n);I.pathInfo.responsePath=br(b);D(n,I);Kt(P,k);fe(n,"htmx:afterRequest",I);fe(n,"htmx:afterOnLoad",I);if(!oe(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(oe(r)){t=r}}if(t){fe(t,"htmx:afterRequest",I);fe(t,"htmx:afterOnLoad",I)}}ne(a);w()}catch(e){ue(n,"htmx:onLoadError",se({error:e},I));throw e}};b.onerror=function(){Kt(P,k);ue(n,"htmx:afterRequest",I);ue(n,"htmx:sendError",I);ne(o);w()};b.onabort=function(){Kt(P,k);ue(n,"htmx:afterRequest",I);ue(n,"htmx:sendAbort",I);ne(o);w()};b.ontimeout=function(){Kt(P,k);ue(n,"htmx:afterRequest",I);ue(n,"htmx:timeout",I);ne(o);w()};if(!fe(n,"htmx:beforeRequest",I)){ne(a);w();return s}var P=Jt(n);var k=Zt(n);ae(["loadstart","loadend","progress","abort"],function(t){ae([b,b.upload],function(e){e.addEventListener(t,function(e){fe(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});fe(n,"htmx:beforeSend",I);var K=q?null:hr(b,n,R);b.send(K);return s}function Cr(e,t){var r=t.xhr;var n=null;var i=null;if(R(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(R(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(R(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=re(e,"hx-push-url");var l=re(e,"hx-replace-url");var u=ie(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 Tr(l,u){var f=u.xhr;var c=u.target;var e=u.etc;var t=u.requestConfig;if(!fe(l,"htmx:beforeOnLoad",u))return;if(R(f,/HX-Trigger:/i)){Ue(f,"HX-Trigger",l)}if(R(f,/HX-Location:/i)){jt();var r=f.getResponseHeader("HX-Location");var h;if(r.indexOf("{")===0){h=S(r);r=h["path"];delete h["path"]}wr("GET",r,h).then(function(){_t(r)});return}var n=R(f,/HX-Refresh:/i)&&"true"===f.getResponseHeader("HX-Refresh");if(R(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");n&&location.reload();return}if(n){location.reload();return}if(R(f,/HX-Retarget:/i)){u.target=te().querySelector(f.getResponseHeader("HX-Retarget"))}var v=Cr(l,u);var i=f.status>=200&&f.status<400&&f.status!==204;var d=f.response;var a=f.status>=400;var g=Y.config.ignoreTitle;var o=se({shouldSwap:i,serverResponse:d,isError:a,ignoreTitle:g},u);if(!fe(c,"htmx:beforeSwap",o))return;c=o.target;d=o.serverResponse;a=o.isError;g=o.ignoreTitle;u.target=c;u.failed=a;u.successful=!a;if(o.shouldSwap){if(f.status===286){Ke(l)}C(l,function(e){d=e.transformResponse(d,f,l)});if(v.type){jt()}var s=e.swapOverride;if(R(f,/HX-Reswap:/i)){s=f.getResponseHeader("HX-Reswap")}var h=fr(l,s);if(h.hasOwnProperty("ignoreTitle")){g=h.ignoreTitle}c.classList.add(Y.config.swappingClass);var m=null;var p=null;var x=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(R(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}var n=T(c);Fe(h.swapStyle,c,l,d,n,r);if(t.elt&&!oe(t.elt)&&Q(t.elt,"id")){var i=document.getElementById(Q(t.elt,"id"));var a={preventScroll:h.focusScroll!==undefined?!h.focusScroll:!Y.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(Y.config.swappingClass);ae(n.elts,function(e){if(e.classList){e.classList.add(Y.config.settlingClass)}fe(e,"htmx:afterSwap",u)});if(R(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!oe(l)){o=te().body}Ue(f,"HX-Trigger-After-Swap",o)}var s=function(){ae(n.tasks,function(e){e.call()});ae(n.elts,function(e){if(e.classList){e.classList.remove(Y.config.settlingClass)}fe(e,"htmx:afterSettle",u)});if(v.type){if(v.type==="push"){_t(v.path);fe(te().body,"htmx:pushedIntoHistory",{path:v.path})}else{zt(v.path);fe(te().body,"htmx:replacedInHistory",{path:v.path})}}if(u.pathInfo.anchor){var e=E("#"+u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title&&!g){var t=E("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}vr(n.elts,h);if(R(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!oe(l)){r=te().body}Ue(f,"HX-Trigger-After-Settle",r)}ne(m)};if(h.settleDelay>0){setTimeout(s,h.settleDelay)}else{s()}}catch(e){ue(l,"htmx:swapError",u);ne(p);throw e}};var y=Y.config.globalViewTransitions;if(h.hasOwnProperty("transition")){y=h.transition}if(y&&fe(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var b=new Promise(function(e,t){m=e;p=t});var w=x;x=function(){document.startViewTransition(function(){w();return b})}}if(h.swapDelay>0){setTimeout(x,h.swapDelay)}else{x()}}if(a){ue(l,"htmx:responseError",se({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var Rr={};function Or(){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 qr(e,t){if(t.init){t.init(r)}Rr[e]=se(Or(),t)}function Hr(e){delete Rr[e]}function Lr(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=ee(e,"hx-ext");if(t){ae(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=Rr[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Lr(u(e),r,n)}var Ar=false;te().addEventListener("DOMContentLoaded",function(){Ar=true});function Nr(e){if(Ar||te().readyState==="complete"){e()}else{te().addEventListener("DOMContentLoaded",e)}}function Ir(){if(Y.config.includeIndicatorStyles!==false){te().head.insertAdjacentHTML("beforeend","")}}function Pr(){var e=te().querySelector('meta[name="htmx-config"]');if(e){return S(e.content)}else{return null}}function kr(){var e=Pr();if(e){Y.config=se(Y.config,e)}}Nr(function(){kr();Ir();var e=te().body;Pt(e);var t=te().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ie(t);if(r&&r.xhr){r.xhr.abort()}});var r=window.onpopstate;window.onpopstate=function(e){if(e.state&&e.state.htmx){Gt();ae(t,function(e){fe(e,"htmx:restored",{document:te(),triggerEvent:fe})})}else{if(r){r(e)}}};setTimeout(function(){fe(e,"htmx:load",{});e=null},0)});return Y}()});
\ No newline at end of file
+(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:F,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:Br,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.12"};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){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/"+n+" ",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("",1);case"col":return s("",2);case"tr":return s("",2);case"td":case"th":return s("",3);case"script":case"style":return s(""+n+"
",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=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 B(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 F(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=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;r0){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"]){Fe(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;a0){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-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=Be(r,o,a);Re(o);return Fe(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;l0){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=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;a0){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;i0){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;t0){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;if(!t){return false}for(var r=0;r0){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+=Bt(o)}for(var l in r){Ft(e,l,r[l])}}}function jt(e){Ae(e);for(var t=0;tQ.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=B(e);var t=E(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r=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=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;a0?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 B=p.split(":");var F=B[0].trim();if(F==="this"){g=xe(n,"hx-sync")}else{g=ue(n,F)}p=(B[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 Br(e){delete Xr[e]}function Fr(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 Fr(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","")}}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}()});
\ No newline at end of file
diff --git a/src/public/spinner.gif b/src/public/spinner.gif
new file mode 100644
index 00000000..32ac2b46
Binary files /dev/null and b/src/public/spinner.gif differ
diff --git a/src/public/sse.js b/src/public/sse.js
index 943d80ac..c037189e 100644
--- a/src/public/sse.js
+++ b/src/public/sse.js
@@ -5,185 +5,162 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
*/
-(function() {
-
+(function () {
/** @type {import("../htmx").HtmxInternalApi} */
- var api;
+ var api
- htmx.defineExtension("sse", {
+ htmx.defineExtension('sse', {
/**
* Init saves the provided reference to the internal HTMX API.
- *
- * @param {import("../htmx").HtmxInternalApi} api
+ *
+ * @param {import("../htmx").HtmxInternalApi} api
* @returns void
*/
- init: function(apiRef) {
+ init: function (apiRef) {
// store a reference to the internal API.
- api = apiRef;
+ api = apiRef
// set a function in the public API for creating new EventSource objects
if (htmx.createEventSource == undefined) {
- htmx.createEventSource = createEventSource;
+ htmx.createEventSource = createEventSource
}
},
/**
* onEvent handles all events passed to this extension.
- *
- * @param {string} name
- * @param {Event} evt
+ *
+ * @param {string} name
+ * @param {Event} evt
* @returns void
*/
- onEvent: function(name, evt) {
-
+ onEvent: function (name, evt) {
+ var parent = evt.target || evt.detail.elt
switch (name) {
-
- case "htmx:beforeCleanupElement":
- var internalData = api.getInternalData(evt.target)
+ case 'htmx:beforeCleanupElement':
+ var internalData = api.getInternalData(parent)
// Try to remove remove an EventSource when elements are removed
if (internalData.sseEventSource) {
- internalData.sseEventSource.close();
+ internalData.sseEventSource.close()
}
- return;
+ return
// Try to create EventSources when elements are processed
- case "htmx:afterProcessNode":
- ensureEventSourceOnElement(evt.target);
- registerSSE(evt.target);
+ case 'htmx:afterProcessNode':
+ ensureEventSourceOnElement(parent)
}
}
- });
+ })
- ///////////////////////////////////////////////
+ /// ////////////////////////////////////////////
// HELPER FUNCTIONS
- ///////////////////////////////////////////////
-
+ /// ////////////////////////////////////////////
/**
* createEventSource is the default method for creating new EventSource objects.
* it is hoisted into htmx.config.createEventSource to be overridden by the user, if needed.
- *
- * @param {string} url
+ *
+ * @param {string} url
* @returns EventSource
*/
function createEventSource(url) {
- return new EventSource(url, { withCredentials: true });
- }
-
- function splitOnWhitespace(trigger) {
- return trigger.trim().split(/\s+/);
- }
-
- function getLegacySSEURL(elt) {
- var legacySSEValue = api.getAttributeValue(elt, "hx-sse");
- if (legacySSEValue) {
- var values = splitOnWhitespace(legacySSEValue);
- for (var i = 0; i < values.length; i++) {
- var value = values[i].split(/:(.+)/);
- if (value[0] === "connect") {
- return value[1];
- }
- }
- }
- }
-
- function getLegacySSESwaps(elt) {
- var legacySSEValue = api.getAttributeValue(elt, "hx-sse");
- var returnArr = [];
- if (legacySSEValue != null) {
- var values = splitOnWhitespace(legacySSEValue);
- for (var i = 0; i < values.length; i++) {
- var value = values[i].split(/:(.+)/);
- if (value[0] === "swap") {
- returnArr.push(value[1]);
- }
- }
- }
- return returnArr;
+ return new EventSource(url, { withCredentials: true })
}
/**
- * registerSSE looks for attributes that can contain sse events, right
+ * registerSSE looks for attributes that can contain sse events, right
* now hx-trigger and sse-swap and adds listeners based on these attributes too
* the closest event source
*
* @param {HTMLElement} elt
*/
function registerSSE(elt) {
- // Find closest existing event source
- var sourceElement = api.getClosestMatch(elt, hasEventSource);
- if (sourceElement == null) {
- // api.triggerErrorEvent(elt, "htmx:noSSESourceError")
- return null; // no eventsource in parentage, orphaned element
- }
-
- // Set internalData and source
- var internalData = api.getInternalData(sourceElement);
- var source = internalData.sseEventSource;
-
// Add message handlers for every `sse-swap` attribute
- queryAttributeOnThisOrChildren(elt, "sse-swap").forEach(function(child) {
-
- var sseSwapAttr = api.getAttributeValue(child, "sse-swap");
- if (sseSwapAttr) {
- var sseEventNames = sseSwapAttr.split(",");
- } else {
- var sseEventNames = getLegacySSESwaps(child);
+ queryAttributeOnThisOrChildren(elt, 'sse-swap').forEach(function (child) {
+ // Find closest existing event source
+ var sourceElement = api.getClosestMatch(child, hasEventSource)
+ if (sourceElement == null) {
+ // api.triggerErrorEvent(elt, "htmx:noSSESourceError")
+ return null // no eventsource in parentage, orphaned element
}
- for (var i = 0; i < sseEventNames.length; i++) {
- var sseEventName = sseEventNames[i].trim();
- var listener = function(event) {
+ // Set internalData and source
+ var internalData = api.getInternalData(sourceElement)
+ var source = internalData.sseEventSource
+
+ var sseSwapAttr = api.getAttributeValue(child, 'sse-swap')
+ var sseEventNames = sseSwapAttr.split(',')
+ for (var i = 0; i < sseEventNames.length; i++) {
+ var sseEventName = sseEventNames[i].trim()
+ var listener = function (event) {
// If the source is missing then close SSE
if (maybeCloseSSESource(sourceElement)) {
- return;
+ return
}
// If the body no longer contains the element, remove the listener
if (!api.bodyContains(child)) {
- source.removeEventListener(sseEventName, listener);
+ source.removeEventListener(sseEventName, listener)
+ return
}
// swap the response into the DOM and trigger a notification
- swap(child, event.data);
- api.triggerEvent(elt, "htmx:sseMessage", event);
- };
+ if (!api.triggerEvent(elt, 'htmx:sseBeforeMessage', event)) {
+ return
+ }
+ swap(child, event.data)
+ api.triggerEvent(elt, 'htmx:sseMessage', event)
+ }
// Register the new listener
- api.getInternalData(child).sseEventListener = listener;
- source.addEventListener(sseEventName, listener);
+ api.getInternalData(child).sseEventListener = listener
+ source.addEventListener(sseEventName, listener)
}
- });
+ })
// Add message handlers for every `hx-trigger="sse:*"` attribute
- queryAttributeOnThisOrChildren(elt, "hx-trigger").forEach(function(child) {
+ queryAttributeOnThisOrChildren(elt, 'hx-trigger').forEach(function (child) {
+ // Find closest existing event source
+ var sourceElement = api.getClosestMatch(child, hasEventSource)
+ if (sourceElement == null) {
+ // api.triggerErrorEvent(elt, "htmx:noSSESourceError")
+ return null // no eventsource in parentage, orphaned element
+ }
+
+ // Set internalData and source
+ var internalData = api.getInternalData(sourceElement)
+ var source = internalData.sseEventSource
- var sseEventName = api.getAttributeValue(child, "hx-trigger");
+ var sseEventName = api.getAttributeValue(child, 'hx-trigger')
if (sseEventName == null) {
- return;
+ return
}
// Only process hx-triggers for events with the "sse:" prefix
- if (sseEventName.slice(0, 4) != "sse:") {
- return;
+ if (sseEventName.slice(0, 4) != 'sse:') {
+ return
}
-
- // remove the sse: prefix from here on out
- sseEventName = sseEventName.substr(4);
- var listener = function() {
+ var listener = function (event) {
if (maybeCloseSSESource(sourceElement)) {
return
}
if (!api.bodyContains(child)) {
- source.removeEventListener(sseEventName, listener);
+ source.removeEventListener(sseEventName, listener)
}
+
+ // Trigger events to be handled by the rest of htmx
+ htmx.trigger(child, sseEventName, event)
+ htmx.trigger(child, 'htmx:sseMessage', event)
}
- });
+
+ // Register the new listener
+ api.getInternalData(elt).sseEventListener = listener
+ source.addEventListener(sseEventName.slice(4), listener)
+ })
}
/**
@@ -195,161 +172,130 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
* @returns {EventSource | null}
*/
function ensureEventSourceOnElement(elt, retryCount) {
-
if (elt == null) {
- return null;
+ return null
}
// handle extension source creation attribute
- queryAttributeOnThisOrChildren(elt, "sse-connect").forEach(function(child) {
- var sseURL = api.getAttributeValue(child, "sse-connect");
+ queryAttributeOnThisOrChildren(elt, 'sse-connect').forEach(function (child) {
+ var sseURL = api.getAttributeValue(child, 'sse-connect')
if (sseURL == null) {
- return;
+ return
}
- ensureEventSource(child, sseURL, retryCount);
- });
-
- // handle legacy sse, remove for HTMX2
- queryAttributeOnThisOrChildren(elt, "hx-sse").forEach(function(child) {
- var sseURL = getLegacySSEURL(child);
- if (sseURL == null) {
- return;
- }
-
- ensureEventSource(child, sseURL, retryCount);
- });
+ ensureEventSource(child, sseURL, retryCount)
+ })
+ registerSSE(elt)
}
function ensureEventSource(elt, url, retryCount) {
- var source = htmx.createEventSource(url);
-
- source.onerror = function(err) {
+ var source = htmx.createEventSource(url)
+ source.onerror = function (err) {
// Log an error event
- api.triggerErrorEvent(elt, "htmx:sseError", { error: err, source: source });
+ api.triggerErrorEvent(elt, 'htmx:sseError', { error: err, source })
// If parent no longer exists in the document, then clean up this EventSource
if (maybeCloseSSESource(elt)) {
- return;
+ return
}
// Otherwise, try to reconnect the EventSource
if (source.readyState === EventSource.CLOSED) {
- retryCount = retryCount || 0;
- var timeout = Math.random() * (2 ^ retryCount) * 500;
- window.setTimeout(function() {
- ensureEventSourceOnElement(elt, Math.min(7, retryCount + 1));
- }, timeout);
+ retryCount = retryCount || 0
+ var timeout = Math.random() * (2 ^ retryCount) * 500
+ window.setTimeout(function () {
+ ensureEventSourceOnElement(elt, Math.min(7, retryCount + 1))
+ }, timeout)
}
- };
+ }
- source.onopen = function(evt) {
- api.triggerEvent(elt, "htmx:sseOpen", { source: source });
+ source.onopen = function (evt) {
+ api.triggerEvent(elt, 'htmx:sseOpen', { source })
}
- api.getInternalData(elt).sseEventSource = source;
+ api.getInternalData(elt).sseEventSource = source
}
/**
* maybeCloseSSESource confirms that the parent element still exists.
* If not, then any associated SSE source is closed and the function returns true.
- *
- * @param {HTMLElement} elt
+ *
+ * @param {HTMLElement} elt
* @returns boolean
*/
function maybeCloseSSESource(elt) {
if (!api.bodyContains(elt)) {
- var source = api.getInternalData(elt).sseEventSource;
+ var source = api.getInternalData(elt).sseEventSource
if (source != undefined) {
- source.close();
+ source.close()
// source = null
- return true;
+ return true
}
}
- return false;
+ return false
}
/**
* queryAttributeOnThisOrChildren returns all nodes that contain the requested attributeName, INCLUDING THE PROVIDED ROOT ELEMENT.
- *
- * @param {HTMLElement} elt
- * @param {string} attributeName
+ *
+ * @param {HTMLElement} elt
+ * @param {string} attributeName
*/
function queryAttributeOnThisOrChildren(elt, attributeName) {
-
- var result = [];
+ var result = []
// If the parent element also contains the requested attribute, then add it to the results too.
if (api.hasAttribute(elt, attributeName)) {
- result.push(elt);
+ result.push(elt)
}
// Search all child nodes that match the requested attribute
- elt.querySelectorAll("[" + attributeName + "], [data-" + attributeName + "]").forEach(function(node) {
- result.push(node);
- });
+ elt.querySelectorAll('[' + attributeName + '], [data-' + attributeName + ']').forEach(function (node) {
+ result.push(node)
+ })
- return result;
+ return result
}
/**
* @param {HTMLElement} elt
- * @param {string} content
+ * @param {string} content
*/
function swap(elt, content) {
+ api.withExtensions(elt, function (extension) {
+ content = extension.transformResponse(content, null, elt)
+ })
- api.withExtensions(elt, function(extension) {
- content = extension.transformResponse(content, null, elt);
- });
-
- var swapSpec = api.getSwapSpecification(elt);
- var target = api.getTarget(elt);
- var settleInfo = api.makeSettleInfo(elt);
-
- api.selectAndSwap(swapSpec.swapStyle, target, elt, content, settleInfo);
-
- settleInfo.elts.forEach(function(elt) {
- if (elt.classList) {
- elt.classList.add(htmx.config.settlingClass);
- }
- api.triggerEvent(elt, 'htmx:beforeSettle');
- });
-
- // Handle settle tasks (with delay if requested)
- if (swapSpec.settleDelay > 0) {
- setTimeout(doSettle(settleInfo), swapSpec.settleDelay);
- } else {
- doSettle(settleInfo)();
- }
+ var swapSpec = api.getSwapSpecification(elt)
+ var target = api.getTarget(elt)
+ api.swap(target, content, swapSpec)
}
/**
- * doSettle mirrors much of the functionality in htmx that
+ * doSettle mirrors much of the functionality in htmx that
* settles elements after their content has been swapped.
* TODO: this should be published by htmx, and not duplicated here
- * @param {import("../htmx").HtmxSettleInfo} settleInfo
+ * @param {import("../htmx").HtmxSettleInfo} settleInfo
* @returns () => void
*/
function doSettle(settleInfo) {
+ return function () {
+ settleInfo.tasks.forEach(function (task) {
+ task.call()
+ })
- return function() {
- settleInfo.tasks.forEach(function(task) {
- task.call();
- });
-
- settleInfo.elts.forEach(function(elt) {
+ settleInfo.elts.forEach(function (elt) {
if (elt.classList) {
- elt.classList.remove(htmx.config.settlingClass);
+ elt.classList.remove(htmx.config.settlingClass)
}
- api.triggerEvent(elt, 'htmx:afterSettle');
- });
+ api.triggerEvent(elt, 'htmx:afterSettle')
+ })
}
}
function hasEventSource(node) {
- return api.getInternalData(node).sseEventSource != null;
+ return api.getInternalData(node).sseEventSource != null
}
-
-})();
+})()
diff --git a/src/routes/add-place.ts b/src/routes/add-place.ts
index 73d8a605..d281b7e8 100644
--- a/src/routes/add-place.ts
+++ b/src/routes/add-place.ts
@@ -74,9 +74,7 @@ export default async function addPlace(fastify: FastifyInstance) {
},
});
}
-
- // back to places list
- resp.header('HX-Redirect', `/`);
+ resp.header('HX-Redirect', '/');
return;
}
diff --git a/src/routes/app.ts b/src/routes/app.ts
index 745bda5a..1e15f68e 100644
--- a/src/routes/app.ts
+++ b/src/routes/app.ts
@@ -23,10 +23,6 @@ export default async function sessionCache(fastify: FastifyInstance) {
const placeData = contactTypes.map((item) => {
return {
...item,
- places: sessionCache.getPlaces({
- type: item.name,
- filter: directiveModel.filter,
- }),
hierarchy: Config.getHierarchyWithReplacement(item, 'desc'),
userRoleProperty: Config.getUserRoleConfig(item),
};
@@ -44,14 +40,35 @@ export default async function sessionCache(fastify: FastifyInstance) {
return resp.view('src/liquid/app/view.html', tmplData);
});
+
+ fastify.get('/app/list', async (req, resp) => {
+ const contactTypes = Config.contactTypes();
+ const sessionCache: SessionCache = req.sessionCache;
+ const directiveModel = new DirectiveModel(sessionCache, req.cookies.filter);
+ const placeData = contactTypes.map((item) => {
+ return {
+ ...item,
+ places: sessionCache.getPlaces({
+ type: item.name,
+ filter: directiveModel.filter,
+ }),
+ hierarchy: Config.getHierarchyWithReplacement(item, 'desc'),
+ userRoleProperty: Config.getUserRoleConfig(item),
+ };
+ });
+ const tmplData = {
+ contactTypes: placeData,
+ };
+ return resp.view('src/liquid/place/list.html', tmplData);
+ });
- fastify.post('/app/remove-all', async (req) => {
+ fastify.post('/app/remove-all', async (req, resp) => {
const sessionCache: SessionCache = req.sessionCache;
sessionCache.removeAll();
- fastify.uploadManager.triggerRefresh(undefined);
+ resp.header('HX-Redirect', '/');
});
- fastify.post('/app/refresh-all', async (req) => {
+ fastify.post('/app/refresh-all', async (req, resp) => {
const sessionCache: SessionCache = req.sessionCache;
const chtApi = new ChtApi(req.chtSession);
@@ -60,22 +77,24 @@ export default async function sessionCache(fastify: FastifyInstance) {
const places = sessionCache.getPlaces({ created: false });
await RemotePlaceResolver.resolve(places, sessionCache, chtApi, { fuzz: true });
places.forEach(p => p.validate());
-
- fastify.uploadManager.triggerRefresh(undefined);
+ resp.header('HX-Redirect', '/');
});
// initiates place creation via the job manager
- fastify.post('/app/apply-changes', async (req) => {
+ fastify.post('/app/apply-changes', async (req, resp) => {
const uploadManager: UploadManager = fastify.uploadManager;
const sessionCache: SessionCache = req.sessionCache;
+ const directiveModel = new DirectiveModel(sessionCache, req.cookies.filter);
const chtApi = new ChtApi(req.chtSession);
uploadManager.doUpload(sessionCache.getPlaces(), chtApi);
+
+ return resp.view('src/liquid/place/directive.html', {
+ directiveModel
+ });
});
fastify.post('/app/set-filter/:filter', async (req, resp) => {
- const uploadManager: UploadManager = fastify.uploadManager;
-
const params: any = req.params;
const filter = params.filter;
resp.setCookie('filter', filter, {
@@ -86,6 +105,6 @@ export default async function sessionCache(fastify: FastifyInstance) {
secure: true,
});
- uploadManager.triggerRefresh(undefined);
+ resp.header('HX-Redirect', '/');
});
}
diff --git a/src/routes/events.ts b/src/routes/events.ts
index 494b253c..e60b947d 100644
--- a/src/routes/events.ts
+++ b/src/routes/events.ts
@@ -4,43 +4,64 @@ import { Config } from '../config';
import DirectiveModel from '../services/directive-model';
import SessionCache from '../services/session-cache';
import { UploadManager } from '../services/upload-manager';
+import { minify } from 'html-minifier';
export default async function events(fastify: FastifyInstance) {
- fastify.get('/events/places/all', async (req, resp) => {
- const sessionCache: SessionCache = req.sessionCache;
- const contactTypes = Config.contactTypes();
- const directiveModel = new DirectiveModel(sessionCache, req.cookies.filter);
- const placeData = contactTypes.map(item => ({
- ...item,
- places: sessionCache.getPlaces({
- type: item.name,
- filter: directiveModel.filter,
- }),
- hierarchy: Config.getHierarchyWithReplacement(item, 'desc'),
- userRoleProperty: Config.getUserRoleConfig(item),
- }));
-
- return resp.view('src/liquid/place/list_event.html', {
- contactTypes: placeData,
- session: req.chtSession,
- directiveModel,
- });
- });
-
fastify.get('/events/connection', async (req, resp) => {
const uploadManager: UploadManager = fastify.uploadManager;
+ const sessionCache: SessionCache = req.sessionCache;
resp.hijack();
- const placesChangeListener = (arg: string = '*') => {
- resp.sse({ event: 'place_state_change', data: arg });
+
+ const updateDirective = async () => {
+ const directiveModel = new DirectiveModel(
+ sessionCache,
+ req.cookies.filter
+ );
+ const html = await fastify.view('src/liquid/place/directive.html', {
+ directiveModel,
+ });
+ resp.sse({
+ event: `directive`,
+ data: minify(html, {
+ html5: true,
+ collapseWhitespace: true,
+ }),
+ });
};
-
- uploadManager.on('refresh_table', placesChangeListener);
- uploadManager.on('refresh_table_row', placesChangeListener);
+
+ const placeChangeListener = async (arg: string) => {
+ const place = sessionCache.getPlace(arg);
+ if (!place) {
+ resp.sse({ event: `update-${arg}`, data: ' ' });
+ } else {
+ const html = await fastify.view(
+ 'src/liquid/components/place_item.html',
+ {
+ contactType: {
+ ...place.type,
+ hierarchy: Config.getHierarchyWithReplacement(place.type, 'desc'),
+ userRoleProperty: Config.getUserRoleConfig(place.type),
+ },
+ place: place,
+ }
+ );
+
+ resp.sse({
+ event: `update-${arg}`,
+ data: minify(html, {
+ html5: true,
+ collapseWhitespace: true,
+ }),
+ });
+ }
+ await updateDirective();
+ };
+
+ uploadManager.on('refresh_table_row', placeChangeListener);
req.socket.on('close', () => {
- uploadManager.removeListener('refresh_table', placesChangeListener);
- uploadManager.removeListener('refresh_table_row', placesChangeListener);
+ uploadManager.removeListener('refresh_table_row', placeChangeListener);
});
});
}
diff --git a/src/server.ts b/src/server.ts
index 71ed26b2..c3fc4131 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -4,6 +4,7 @@ import cookie from '@fastify/cookie';
import formbody from '@fastify/formbody';
import multipart from '@fastify/multipart';
import fastifyStatic from '@fastify/static';
+import fastifyCompress from '@fastify/compress';
import view from '@fastify/view';
import { Liquid } from 'liquidjs';
import { FastifySSEPlugin } from 'fastify-sse-v2';
@@ -18,9 +19,16 @@ const build = (opts: FastifyServerOptions): FastifyInstance => {
fastify.register(multipart);
fastify.register(FastifySSEPlugin);
fastify.register(cookie);
+ fastify.register(fastifyCompress);
fastify.register(view, {
engine: {
- liquid: new Liquid({ extname: '.html', root: 'src/liquid', jekyllInclude: true, dynamicPartials: true }),
+ liquid: new Liquid({
+ extname: '.html',
+ root: 'src/liquid',
+ cache: process.env.NODE_ENV === 'production',
+ jekyllInclude: true,
+ dynamicPartials: true
+ }),
},
});
fastify.register(autoload, {
diff --git a/src/services/upload-manager.ts b/src/services/upload-manager.ts
index 8a4a907e..01c760ed 100644
--- a/src/services/upload-manager.ts
+++ b/src/services/upload-manager.ts
@@ -82,24 +82,14 @@ export class UploadManager extends EventEmitter {
}
}
- public triggerRefresh(place_id: string | undefined) {
- if (place_id) {
- this.emit('refresh_table_row', place_id);
- } else {
- this.emit('refresh_table');
- }
+ public triggerRefresh(place_id: string) {
+ this.emit('refresh_table_row', place_id);
}
private eventedPlaceStateChange = (subject: Place | Place[], state: PlaceUploadState) => {
if (!Array.isArray(subject)) {
subject = [subject];
}
-
- if (subject.length > 1) {
- this.triggerRefresh(undefined);
- return;
- }
-
subject.forEach(place => {
place.state = state;
this.triggerRefresh(place.id);