diff --git a/Gemfile b/Gemfile
index 27a54190605efab798e8d8b5b2b07fdd62735d62..675f79b943e4207082eb3ee1552f4f4c3fa449a5 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,6 +4,7 @@ source "https://rubygems.org"
gem "blather"
gem "braintree"
+gem "countries"
gem "dhall", ">= 0.5.3.fixed"
gem "em-http-request"
gem "em_promise.rb"
diff --git a/assets/css/loader/loader.scss b/assets/css/loader/loader.scss
new file mode 100644
index 0000000000000000000000000000000000000000..b87c95e26813d8077a0162c008624a370d2cebdc
--- /dev/null
+++ b/assets/css/loader/loader.scss
@@ -0,0 +1,39 @@
+.lds-ring,
+.lds-ring div {
+ box-sizing: border-box;
+}
+.lds-ring {
+ display: inline-block;
+ position: relative;
+ width: 80px;
+ height: 80px;
+}
+.lds-ring div {
+ box-sizing: border-box;
+ display: block;
+ position: absolute;
+ width: 64px;
+ height: 64px;
+ margin: 8px;
+ border: 8px solid currentColor;
+ border-radius: 50%;
+ animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
+ border-color: currentColor transparent transparent transparent;
+}
+.lds-ring div:nth-child(1) {
+ animation-delay: -0.45s;
+}
+.lds-ring div:nth-child(2) {
+ animation-delay: -0.3s;
+}
+.lds-ring div:nth-child(3) {
+ animation-delay: -0.15s;
+}
+@keyframes lds-ring {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
diff --git a/assets/css/tom_select/_dropdown.scss b/assets/css/tom_select/_dropdown.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e17119228170d8f9c9a92346e9289fbbd972a4bf
--- /dev/null
+++ b/assets/css/tom_select/_dropdown.scss
@@ -0,0 +1,104 @@
+
+
+.#{$select-ns}-dropdown {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ width: 100%;
+ z-index: 10;
+
+ border: $select-dropdown-border;
+ background: $select-color-dropdown;
+ margin: 0.25rem 0 0 0;
+ border-top: 0 none;
+ box-sizing: border-box;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
+ border-radius: 0 0 $select-border-radius $select-border-radius;
+
+
+ [data-selectable] {
+ cursor: pointer;
+ overflow: hidden;
+ .highlight {
+ background: $select-color-highlight;
+ border-radius: 1px;
+ }
+ }
+
+ .option,
+ .optgroup-header,
+ .no-results,
+ .create {
+ padding: $select-padding-dropdown-item-y $select-padding-dropdown-item-x;
+ }
+
+ .option, [data-disabled], [data-disabled] [data-selectable].option {
+ cursor: inherit;
+ opacity: 0.5;
+ }
+
+ [data-selectable].option {
+ opacity: 1;
+ cursor: pointer;
+ }
+
+ .optgroup:first-child .optgroup-header {
+ border-top: 0 none;
+ }
+
+ .optgroup-header {
+ color: $select-color-optgroup-text;
+ background: $select-color-optgroup;
+ cursor: default;
+ }
+
+ .create:hover,
+ .option:hover,
+ .active {
+ background-color: $select-color-dropdown-item-active;
+ color: $select-color-dropdown-item-active-text;
+ &.create {
+ color: $select-color-dropdown-item-create-active-text;
+ }
+ }
+
+ .create {
+ color: $select-color-dropdown-item-create-text;
+ }
+
+ .spinner{
+ display: inline-block;
+ width: $select-spinner-size;
+ height: $select-spinner-size;
+ margin: $select-padding-dropdown-item-y $select-padding-dropdown-item-x;
+
+
+ &:after {
+ content: " ";
+ display: block;
+ width: $select-spinner-size * .8;
+ height: $select-spinner-size * .8;
+ margin: $select-spinner-size * .1;
+ border-radius: 50%;
+ border: $select-spinner-border-size solid $select-spinner-border-color;
+ border-color: $select-spinner-border-color transparent $select-spinner-border-color transparent;
+ animation: lds-dual-ring 1.2s linear infinite;
+ }
+ @keyframes lds-dual-ring {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+ }
+}
+
+.#{$select-ns}-dropdown-content {
+ overflow-y: auto;
+ overflow-x: hidden;
+ max-height: $select-max-height-dropdown;
+ overflow-scrolling: touch;
+ scroll-behavior: smooth;
+}
diff --git a/assets/css/tom_select/_items.scss b/assets/css/tom_select/_items.scss
new file mode 100644
index 0000000000000000000000000000000000000000..8a03bda27ac36c5a2fffb7f6258d43e6d28a6281
--- /dev/null
+++ b/assets/css/tom_select/_items.scss
@@ -0,0 +1,115 @@
+
+
+.#{$select-ns}-control {
+
+ border: $select-border;
+ padding: $select-padding-y $select-padding-x;
+ width: 100%;
+ overflow: hidden;
+ position: relative;
+ z-index: 1;
+ box-sizing: border-box;
+ box-shadow: $select-shadow-input;
+ border-radius: $select-border-radius;
+ display: flex;
+ flex-wrap: wrap;
+
+ .#{$select-ns}-wrapper.multi.has-items & {
+ $padding-x: $select-padding-x;
+ $padding-top: calc( #{$select-padding-y} - #{$select-padding-item-y} - #{$select-width-item-border});
+ $padding-bottom: calc( #{$select-padding-y} - #{$select-padding-item-y} - #{$select-margin-item-y} - #{$select-width-item-border});
+ padding: $padding-top $padding-x $padding-bottom;
+ }
+
+ .full & {
+ background-color: $select-color-input-full;
+ }
+
+ .disabled &,
+ .disabled & * {
+ cursor: default !important;
+ }
+
+ .focus & {
+ box-shadow: $select-shadow-input-focus;
+ }
+
+ > * {
+ vertical-align: baseline;
+ display: inline-block;
+ }
+
+ .#{$select-ns}-wrapper.multi & > div {
+ cursor: pointer;
+ margin: 0 $select-margin-item-x $select-margin-item-y 0;
+ padding: $select-padding-item-y $select-padding-item-x;
+ background: $select-color-item;
+ color: $select-color-item-text;
+ border: $select-width-item-border solid $select-color-item-border;
+
+ &.active {
+ background: $select-color-item-active;
+ color: $select-color-item-active-text;
+ border: $select-width-item-border solid $select-color-item-active-border;
+ }
+ }
+
+ .#{$select-ns}-wrapper.multi.disabled & > div {
+ &, &.active {
+ color: lighten(desaturate($select-color-item-text, 100%), $select-lighten-disabled-item-text);
+ background: lighten(desaturate($select-color-item, 100%), $select-lighten-disabled-item);
+ border: $select-width-item-border solid lighten(desaturate($select-color-item-border, 100%), $select-lighten-disabled-item-border);
+ }
+ }
+
+ > input {
+ &::-ms-clear {
+ display: none;
+ }
+
+ flex: 1 1 auto;
+ min-width: 7rem;
+ display: inline-block !important;
+ padding: 0 !important;
+ min-height: 0 !important;
+ max-height: none !important;
+ max-width: 100% !important;
+ margin: 0 !important;
+ text-indent: 0 !important;
+ border: 0 none !important;
+ background: none !important;
+ line-height: inherit !important;
+ user-select: auto !important;
+ box-shadow: none !important;
+ &:focus { outline: none !important; }
+ }
+
+ .has-items & > input{
+ margin: $select-caret-margin !important;
+ }
+
+ &.rtl {
+ text-align: right;
+ &.single .#{$select-ns}-control:after {
+ left: $select-arrow-offset;
+ right: auto;
+ }
+ .#{$select-ns}-control > input {
+ margin: $select-caret-margin-rtl !important;
+ }
+ }
+
+ .disabled & {
+ opacity: $select-opacity-disabled;
+ background-color: $select-color-disabled;
+ }
+
+ // hide input, while retaining its focus, and maintain layout so users can still click on the space to bring the display back
+ // visibility:hidden can prevent the input from receiving focus
+ .input-hidden & > input{
+ opacity: 0;
+ position: absolute;
+ left: -10000px;
+ }
+
+}
diff --git a/assets/css/tom_select/plugins/_dropdown_input.scss b/assets/css/tom_select/plugins/_dropdown_input.scss
new file mode 100644
index 0000000000000000000000000000000000000000..089f72175a4b6a1cbb124dd81988c9f409ec47e5
--- /dev/null
+++ b/assets/css/tom_select/plugins/_dropdown_input.scss
@@ -0,0 +1,37 @@
+
+.plugin-dropdown_input{
+
+ &.focus.dropdown-active .#{$select-ns}-control{
+ box-shadow: none;
+ border: $select-border;
+ @if variable-exists(input-box-shadow) {
+ box-shadow: $input-box-shadow;
+ }
+ }
+
+ .dropdown-input {
+ border: 1px solid $select-color-border;
+ border-width: 0 0 1px 0;
+ display: block;
+ padding: $select-padding-y $select-padding-x;
+ box-shadow: $select-shadow-input;
+ width: 100%;
+ background: transparent;
+ }
+
+ &.focus ~ .#{$select-ns}-dropdown .dropdown-input{
+ @if variable-exists(input-focus-border-color) {
+ border-color: $input-focus-border-color;
+
+ outline: 0;
+ @if $enable-shadows {
+ box-shadow: $input-box-shadow, $input-focus-box-shadow;
+ } @else {
+ box-shadow: $input-focus-box-shadow;
+ }
+
+ }
+
+ }
+
+}
diff --git a/assets/css/tom_select/tom_select.scss b/assets/css/tom_select/tom_select.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a542d650395a231682de094766dfd8fe5374da54
--- /dev/null
+++ b/assets/css/tom_select/tom_select.scss
@@ -0,0 +1,169 @@
+/**
+ * tom-select.css (v2.0.0)
+ * Copyright (c) contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at:
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ *
+ */
+
+
+// base styles
+$select-ns: 'ts' !default;
+$select-font-family: inherit !default;
+$select-font-smoothing: inherit !default;
+$select-font-size: 1.2em !default;
+$select-line-height: 1.1 !default;
+
+$select-color-text: #303030 !default;
+$select-color-border: #d0d0d0 !default;
+$select-color-highlight: rgba(125,168,208,0.2) !default;
+$select-color-input: #fff !default;
+$select-color-input-full: $select-color-input !default;
+$select-color-disabled: #fafafa !default;
+$select-color-item: #f2f2f2 !default;
+$select-color-item-text: $select-color-text !default;
+$select-color-item-border: #d0d0d0 !default;
+$select-color-item-active: #e8e8e8 !default;
+$select-color-item-active-text: $select-color-text !default;
+$select-color-item-active-border: #cacaca !default;
+$select-color-dropdown: #fff !default;
+$select-color-dropdown-border: $select-color-border !default;
+$select-color-dropdown-border-top: #f0f0f0 !default;
+$select-color-dropdown-item-active: #f5fafd !default;
+$select-color-dropdown-item-active-text: #495c68 !default;
+$select-color-dropdown-item-create-text: rgba(red($select-color-text), green($select-color-text), blue($select-color-text), 0.5) !default;
+$select-color-dropdown-item-create-active-text: $select-color-dropdown-item-active-text !default;
+$select-color-optgroup: $select-color-dropdown !default;
+$select-color-optgroup-text: $select-color-text !default;
+$select-lighten-disabled-item: 30% !default;
+$select-lighten-disabled-item-text: 30% !default;
+$select-lighten-disabled-item-border: 30% !default;
+$select-opacity-disabled: 0.5 !default;
+
+$select-shadow-input: none !default;
+$select-shadow-input-focus: none !default;
+$select-border: 1px solid $select-color-border !default;
+$select-dropdown-border: 1px solid $select-color-dropdown-border !default;
+$select-border-radius: 3px !default;
+
+$select-width-item-border: 0 !default;
+$select-max-height-dropdown: 200px !default;
+
+$select-padding-x: 8px !default;
+$select-padding-y: 8px !default;
+$select-padding-item-x: 6px !default;
+$select-padding-item-y: 2px !default;
+$select-padding-dropdown-item-x: $select-padding-x !default;
+$select-padding-dropdown-item-y: 5px !default;
+$select-margin-item-x: 3px !default;
+$select-margin-item-y: 3px !default;
+
+$select-arrow-size: 5px !default;
+$select-arrow-color: #808080 !default;
+$select-arrow-offset: 15px !default;
+
+$select-caret-margin: 0 4px !default;
+$select-caret-margin-rtl: 0 4px 0 -2px !default;
+
+$select-spinner-size: 30px !default;
+$select-spinner-border-size: 5px !default;
+$select-spinner-border-color: $select-color-border !default;
+
+@mixin selectize-vertical-gradient($color-top, $color-bottom) {
+ background-color: mix($color-top, $color-bottom, 60%);
+ background-image: linear-gradient(to bottom, $color-top, $color-bottom);
+ background-repeat: repeat-x;
+}
+
+
+@mixin ts-caret(){
+
+ .#{$select-ns}-wrapper.single{
+
+ .#{$select-ns}-control {
+ padding-right: 2rem;
+
+ &, input {
+ cursor: pointer;
+ }
+
+ &:after {
+ content: ' ';
+ display: block;
+ position: absolute;
+ top: 50%;
+ right: $select-arrow-offset;
+ margin-top: round((-1 * $select-arrow-size / 2));
+ width: 0;
+ height: 0;
+ border-style: solid;
+ border-width: $select-arrow-size $select-arrow-size 0 $select-arrow-size;
+ border-color: $select-arrow-color transparent transparent transparent;
+ }
+ }
+
+ &.dropdown-active .#{$select-ns}-control::after {
+ margin-top: $select-arrow-size * -0.8;
+ border-width: 0 $select-arrow-size $select-arrow-size $select-arrow-size;
+ border-color: transparent transparent $select-arrow-color transparent;
+ }
+
+ &.input-active .#{$select-ns}-control,
+ &.input-active .#{$select-ns}-control input {
+ cursor: text;
+ }
+
+ }
+}
+
+//@import "./plugins/drag_drop.scss";
+//@import "./plugins/checkbox_options.scss";
+//@import "./plugins/clear_button.scss";
+//@import "./plugins/dropdown_header.scss";
+@import "./plugins/dropdown_input";
+//@import "./plugins/input_autogrow.scss";
+//@import "./plugins/optgroup_columns.scss";
+//@import "./plugins/remove_button.scss";
+
+
+.#{$select-ns}-wrapper {
+ position: relative;
+}
+
+.#{$select-ns}-dropdown,
+.#{$select-ns}-control,
+.#{$select-ns}-control input {
+ color: $select-color-text;
+ font-family: $select-font-family;
+ font-size: $select-font-size;
+ line-height: $select-line-height;
+ font-smoothing: $select-font-smoothing;
+}
+
+.#{$select-ns}-control,
+.#{$select-ns}-wrapper.single.input-active .#{$select-ns}-control {
+ background: $select-color-input;
+ cursor: text;
+}
+
+@import 'items';
+@import 'dropdown';
+
+.ts-hidden-accessible{
+ border: 0 !important;
+ clip: rect(0 0 0 0) !important;
+ clip-path: inset(50%) !important;
+ height: 1px !important;
+ overflow: hidden !important;
+ padding: 0 !important;
+ position: absolute !important;
+ width: 1px !important;
+ white-space: nowrap !important;
+}
diff --git a/assets/js/htmx/htmx.js b/assets/js/htmx/htmx.js
new file mode 100644
index 0000000000000000000000000000000000000000..24e6dc48260f90613c823b4cb2210922f36bc176
--- /dev/null
+++ b/assets/js/htmx/htmx.js
@@ -0,0 +1,2751 @@
+//AMD insanity
+(function (root, factory) {
+ //@ts-ignore
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ //@ts-ignore
+ define([], factory);
+ } else {
+ // Browser globals
+ root.htmx = factory();
+ }
+}(typeof self !== 'undefined' ? self : this, function () {
+return (function () {
+ 'use strict';
+
+ // Public API
+ var htmx = {
+ onLoad: onLoadHelper,
+ process: processNode,
+ on: addEventListenerImpl,
+ off: removeEventListenerImpl,
+ trigger : triggerEvent,
+ ajax : ajaxHelper,
+ find : find,
+ findAll : findAll,
+ closest : closest,
+ values : function(elt, type){
+ var inputValues = getInputValues(elt, type || "post");
+ return inputValues.values;
+ },
+ remove : removeElement,
+ addClass : addClassToElement,
+ removeClass : removeClassFromElement,
+ toggleClass : toggleClassOnElement,
+ takeClass : takeClassForElement,
+ defineExtension : defineExtension,
+ removeExtension : removeExtension,
+ logAll : logAll,
+ 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,
+ attributesToSettle:["class", "style", "width", "height"],
+ withCredentials:false,
+ timeout:0,
+ wsReconnectDelay: 'full-jitter',
+ disableSelector: "[hx-disable], [data-hx-disable]",
+ useTemplateFragments: false,
+ scrollBehavior: 'smooth',
+ },
+ parseInterval:parseInterval,
+ _:internalEval,
+ createEventSource: function(url){
+ return new EventSource(url, {withCredentials:true})
+ },
+ createWebSocket: function(url){
+ return new WebSocket(url, []);
+ },
+ version: "1.6.1"
+ };
+
+ var VERBS = ['get', 'post', 'put', 'delete', 'patch'];
+ var VERB_SELECTOR = VERBS.map(function(verb){
+ return "[hx-" + verb + "], [data-hx-" + verb + "]"
+ }).join(", ");
+
+ //====================================================================
+ // Utilities
+ //====================================================================
+
+ function parseInterval(str) {
+ if (str == undefined) {
+ return undefined
+ }
+ if (str.slice(-2) == "ms") {
+ return parseFloat(str.slice(0,-2)) || undefined
+ }
+ if (str.slice(-1) == "s") {
+ return (parseFloat(str.slice(0,-1)) * 1000) || undefined
+ }
+ return parseFloat(str) || undefined
+ }
+
+ function getRawAttribute(elt, name) {
+ return elt.getAttribute && elt.getAttribute(name);
+ }
+
+ // resolve with both hx and data-hx prefixes
+ function hasAttribute(elt, qualifiedName) {
+ return elt.hasAttribute && (elt.hasAttribute(qualifiedName) ||
+ elt.hasAttribute("data-" + qualifiedName));
+ }
+
+ function getAttributeValue(elt, qualifiedName) {
+ return getRawAttribute(elt, qualifiedName) || getRawAttribute(elt, "data-" + qualifiedName);
+ }
+
+ function parentElt(elt) {
+ return elt.parentElement;
+ }
+
+ function getDocument() {
+ return document;
+ }
+
+ function getClosestMatch(elt, condition) {
+ if (condition(elt)) {
+ return elt;
+ } else if (parentElt(elt)) {
+ return getClosestMatch(parentElt(elt), condition);
+ } else {
+ return null;
+ }
+ }
+
+ function getClosestAttributeValue(elt, attributeName) {
+ var closestAttr = null;
+ getClosestMatch(elt, function (e) {
+ return closestAttr = getAttributeValue(e, attributeName);
+ });
+ if (closestAttr !== "unset") {
+ return closestAttr;
+ }
+ }
+
+ function matches(elt, selector) {
+ // noinspection JSUnresolvedVariable
+ var matchesFunction = elt.matches ||
+ elt.matchesSelector || elt.msMatchesSelector || elt.mozMatchesSelector
+ || elt.webkitMatchesSelector || elt.oMatchesSelector;
+ return matchesFunction && matchesFunction.call(elt, selector);
+ }
+
+ function getStartTag(str) {
+ var tagMatcher = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i
+ var match = tagMatcher.exec( str );
+ if (match) {
+ return match[1].toLowerCase();
+ } else {
+ return "";
+ }
+ }
+
+ function parseHTML(resp, depth) {
+ var parser = new DOMParser();
+ var responseDoc = parser.parseFromString(resp, "text/html");
+ var responseNode = responseDoc.body;
+ while (depth > 0) {
+ depth--;
+ // @ts-ignore
+ responseNode = responseNode.firstChild;
+ }
+ if (responseNode == null) {
+ // @ts-ignore
+ responseNode = getDocument().createDocumentFragment();
+ }
+ return responseNode;
+ }
+
+ function makeFragment(resp) {
+ if (htmx.config.useTemplateFragments) {
+ var documentFragment = parseHTML("
" + resp + "", 0);
+ return documentFragment.querySelector('template').content;
+ } else {
+ var startTag = getStartTag(resp);
+ switch (startTag) {
+ case "thead":
+ case "tbody":
+ case "tfoot":
+ case "colgroup":
+ case "caption":
+ return parseHTML("", 1);
+ case "col":
+ return parseHTML("", 2);
+ case "tr":
+ return parseHTML("", 2);
+ case "td":
+ case "th":
+ return parseHTML("", 3);
+ case "script":
+ return parseHTML("" + resp + "
", 1);
+ default:
+ return parseHTML(resp, 0);
+ }
+ }
+ }
+
+ function maybeCall(func){
+ if(func) {
+ func();
+ }
+ }
+
+ function isType(o, type) {
+ return Object.prototype.toString.call(o) === "[object " + type + "]";
+ }
+
+ function isFunction(o) {
+ return isType(o, "Function");
+ }
+
+ function isRawObject(o) {
+ return isType(o, "Object");
+ }
+
+ function getInternalData(elt) {
+ var dataProp = 'htmx-internal-data';
+ var data = elt[dataProp];
+ if (!data) {
+ data = elt[dataProp] = {};
+ }
+ return data;
+ }
+
+ function toArray(arr) {
+ var returnArr = [];
+ if (arr) {
+ for (var i = 0; i < arr.length; i++) {
+ returnArr.push(arr[i]);
+ }
+ }
+ return returnArr
+ }
+
+ function forEach(arr, func) {
+ if (arr) {
+ for (var i = 0; i < arr.length; i++) {
+ func(arr[i]);
+ }
+ }
+ }
+
+ function isScrolledIntoView(el) {
+ var rect = el.getBoundingClientRect();
+ var elemTop = rect.top;
+ var elemBottom = rect.bottom;
+ return elemTop < window.innerHeight && elemBottom >= 0;
+ }
+
+ function bodyContains(elt) {
+ if (elt.getRootNode() instanceof ShadowRoot) {
+ return getDocument().body.contains(elt.getRootNode().host);
+ } else {
+ return getDocument().body.contains(elt);
+ }
+ }
+
+ function splitOnWhitespace(trigger) {
+ return trigger.trim().split(/\s+/);
+ }
+
+ function mergeObjects(obj1, obj2) {
+ for (var key in obj2) {
+ if (obj2.hasOwnProperty(key)) {
+ obj1[key] = obj2[key];
+ }
+ }
+ return obj1;
+ }
+
+ function parseJSON(jString) {
+ try {
+ return JSON.parse(jString);
+ } catch(error) {
+ logError(error);
+ return null;
+ }
+ }
+
+ //==========================================================================================
+ // public API
+ //==========================================================================================
+
+ function internalEval(str){
+ return maybeEval(getDocument().body, function () {
+ return eval(str);
+ });
+ }
+
+ function onLoadHelper(callback) {
+ var value = htmx.on("htmx:load", function(evt) {
+ callback(evt.detail.elt);
+ });
+ return value;
+ }
+
+ function logAll(){
+ htmx.logger = function(elt, event, data) {
+ if(console) {
+ console.log(event, elt, data);
+ }
+ }
+ }
+
+ function find(eltOrSelector, selector) {
+ if (selector) {
+ return eltOrSelector.querySelector(selector);
+ } else {
+ return find(getDocument(), eltOrSelector);
+ }
+ }
+
+ function findAll(eltOrSelector, selector) {
+ if (selector) {
+ return eltOrSelector.querySelectorAll(selector);
+ } else {
+ return findAll(getDocument(), eltOrSelector);
+ }
+ }
+
+ function removeElement(elt, delay) {
+ elt = resolveTarget(elt);
+ if (delay) {
+ setTimeout(function(){removeElement(elt);}, delay)
+ } else {
+ elt.parentElement.removeChild(elt);
+ }
+ }
+
+ function addClassToElement(elt, clazz, delay) {
+ elt = resolveTarget(elt);
+ if (delay) {
+ setTimeout(function(){addClassToElement(elt, clazz);}, delay)
+ } else {
+ elt.classList && elt.classList.add(clazz);
+ }
+ }
+
+ function removeClassFromElement(elt, clazz, delay) {
+ elt = resolveTarget(elt);
+ if (delay) {
+ setTimeout(function(){removeClassFromElement(elt, clazz);}, delay)
+ } else {
+ if (elt.classList) {
+ elt.classList.remove(clazz);
+ // if there are no classes left, remove the class attribute
+ if (elt.classList.length === 0) {
+ elt.removeAttribute("class");
+ }
+ }
+ }
+ }
+
+ function toggleClassOnElement(elt, clazz) {
+ elt = resolveTarget(elt);
+ elt.classList.toggle(clazz);
+ }
+
+ function takeClassForElement(elt, clazz) {
+ elt = resolveTarget(elt);
+ forEach(elt.parentElement.children, function(child){
+ removeClassFromElement(child, clazz);
+ })
+ addClassToElement(elt, clazz);
+ }
+
+ function closest(elt, selector) {
+ elt = resolveTarget(elt);
+ if (elt.closest) {
+ return elt.closest(selector);
+ } else {
+ do{
+ if (elt == null || matches(elt, selector)){
+ return elt;
+ }
+ }
+ while (elt = elt && parentElt(elt));
+ }
+ }
+
+ function querySelectorAllExt(elt, selector) {
+ if (selector.indexOf("closest ") === 0) {
+ return [closest(elt, selector.substr(8))];
+ } else if (selector.indexOf("find ") === 0) {
+ return [find(elt, selector.substr(5))];
+ } else if (selector === 'document') {
+ return [document];
+ } else if (selector === 'window') {
+ return [window];
+ } else {
+ return getDocument().querySelectorAll(selector);
+ }
+ }
+
+ function querySelectorExt(eltOrSelector, selector) {
+ if (selector) {
+ return querySelectorAllExt(eltOrSelector, selector)[0];
+ } else {
+ return querySelectorAllExt(getDocument().body, eltOrSelector)[0];
+ }
+ }
+
+ function resolveTarget(arg2) {
+ if (isType(arg2, 'String')) {
+ return find(arg2);
+ } else {
+ return arg2;
+ }
+ }
+
+ function processEventArgs(arg1, arg2, arg3) {
+ if (isFunction(arg2)) {
+ return {
+ target: getDocument().body,
+ event: arg1,
+ listener: arg2
+ }
+ } else {
+ return {
+ target: resolveTarget(arg1),
+ event: arg2,
+ listener: arg3
+ }
+ }
+
+ }
+
+ function addEventListenerImpl(arg1, arg2, arg3) {
+ ready(function(){
+ var eventArgs = processEventArgs(arg1, arg2, arg3);
+ eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener);
+ })
+ var b = isFunction(arg2);
+ return b ? arg2 : arg3;
+ }
+
+ function removeEventListenerImpl(arg1, arg2, arg3) {
+ ready(function(){
+ var eventArgs = processEventArgs(arg1, arg2, arg3);
+ eventArgs.target.removeEventListener(eventArgs.event, eventArgs.listener);
+ })
+ return isFunction(arg2) ? arg2 : arg3;
+ }
+
+ //====================================================================
+ // Node processing
+ //====================================================================
+
+ function getTarget(elt) {
+ var explicitTarget = getClosestMatch(elt, function(e){return getAttributeValue(e,"hx-target") !== null});
+ if (explicitTarget) {
+ var targetStr = getAttributeValue(explicitTarget, "hx-target");
+ if (targetStr === "this") {
+ return explicitTarget;
+ } else {
+ return querySelectorExt(elt, targetStr)
+ }
+ } else {
+ var data = getInternalData(elt);
+ if (data.boosted) {
+ return getDocument().body;
+ } else {
+ return elt;
+ }
+ }
+ }
+
+ function shouldSettleAttribute(name) {
+ var attributesToSettle = htmx.config.attributesToSettle;
+ for (var i = 0; i < attributesToSettle.length; i++) {
+ if (name === attributesToSettle[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function cloneAttributes(mergeTo, mergeFrom) {
+ forEach(mergeTo.attributes, function (attr) {
+ if (!mergeFrom.hasAttribute(attr.name) && shouldSettleAttribute(attr.name)) {
+ mergeTo.removeAttribute(attr.name)
+ }
+ });
+ forEach(mergeFrom.attributes, function (attr) {
+ if (shouldSettleAttribute(attr.name)) {
+ mergeTo.setAttribute(attr.name, attr.value);
+ }
+ });
+ }
+
+ function isInlineSwap(swapStyle, target) {
+ var extensions = getExtensions(target);
+ for (var i = 0; i < extensions.length; i++) {
+ var extension = extensions[i];
+ try {
+ if (extension.isInlineSwap(swapStyle)) {
+ return true;
+ }
+ } catch(e) {
+ logError(e);
+ }
+ }
+ return swapStyle === "outerHTML";
+ }
+
+ function oobSwap(oobValue, oobElement, settleInfo) {
+ var selector = "#" + oobElement.id;
+ var swapStyle = "outerHTML";
+ if (oobValue === "true") {
+ // do nothing
+ } else if (oobValue.indexOf(":") > 0) {
+ swapStyle = oobValue.substr(0, oobValue.indexOf(":"));
+ selector = oobValue.substr(oobValue.indexOf(":") + 1, oobValue.length);
+ } else {
+ swapStyle = oobValue;
+ }
+
+ var target = getDocument().querySelector(selector);
+ if (target) {
+ var fragment;
+ fragment = getDocument().createDocumentFragment();
+ fragment.appendChild(oobElement); // pulls the child out of the existing fragment
+ if (!isInlineSwap(swapStyle, target)) {
+ fragment = oobElement; // if this is not an inline swap, we use the content of the node, not the node itself
+ }
+ swap(swapStyle, target, target, fragment, settleInfo);
+ } else {
+ oobElement.parentNode.removeChild(oobElement);
+ triggerErrorEvent(getDocument().body, "htmx:oobErrorNoTarget", {content: oobElement})
+ }
+ return oobValue;
+ }
+
+ function handleOutOfBandSwaps(fragment, settleInfo) {
+ forEach(findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]'), function (oobElement) {
+ var oobValue = getAttributeValue(oobElement, "hx-swap-oob");
+ if (oobValue != null) {
+ oobSwap(oobValue, oobElement, settleInfo);
+ }
+ });
+ }
+
+ function handlePreservedElements(fragment) {
+ forEach(findAll(fragment, '[hx-preserve], [data-hx-preserve]'), function (preservedElt) {
+ var id = getAttributeValue(preservedElt, "id");
+ var oldElt = getDocument().getElementById(id);
+ if (oldElt != null) {
+ preservedElt.parentNode.replaceChild(oldElt, preservedElt);
+ }
+ });
+ }
+
+ function handleAttributes(parentNode, fragment, settleInfo) {
+ forEach(fragment.querySelectorAll("[id]"), function (newNode) {
+ if (newNode.id && newNode.id.length > 0) {
+ var oldNode = parentNode.querySelector(newNode.tagName + "[id='" + newNode.id + "']");
+ if (oldNode && oldNode !== parentNode) {
+ var newAttributes = newNode.cloneNode();
+ cloneAttributes(newNode, oldNode);
+ settleInfo.tasks.push(function () {
+ cloneAttributes(newNode, newAttributes);
+ });
+ }
+ }
+ });
+ }
+
+ function makeAjaxLoadTask(child) {
+ return function () {
+ removeClassFromElement(child, htmx.config.addedClass);
+ processNode(child);
+ processScripts(child);
+ processFocus(child)
+ triggerEvent(child, 'htmx:load');
+ };
+ }
+
+ function processFocus(child) {
+ var autofocus = "[autofocus]";
+ var autoFocusedElt = matches(child, autofocus) ? child : child.querySelector(autofocus)
+ if (autoFocusedElt != null) {
+ autoFocusedElt.focus();
+ }
+ }
+
+ function insertNodesBefore(parentNode, insertBefore, fragment, settleInfo) {
+ handleAttributes(parentNode, fragment, settleInfo);
+ while(fragment.childNodes.length > 0){
+ var child = fragment.firstChild;
+ addClassToElement(child, htmx.config.addedClass);
+ parentNode.insertBefore(child, insertBefore);
+ if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) {
+ settleInfo.tasks.push(makeAjaxLoadTask(child));
+ }
+ }
+ }
+
+ function cleanUpElement(element) {
+ var internalData = getInternalData(element);
+ if (internalData.webSocket) {
+ internalData.webSocket.close();
+ }
+ if (internalData.sseEventSource) {
+ internalData.sseEventSource.close();
+ }
+ if (internalData.listenerInfos) {
+ forEach(internalData.listenerInfos, function(info) {
+ if (element !== info.on) {
+ info.on.removeEventListener(info.trigger, info.listener);
+ }
+ });
+ }
+ if (element.children) { // IE
+ forEach(element.children, function(child) { cleanUpElement(child) });
+ }
+ }
+
+ function swapOuterHTML(target, fragment, settleInfo) {
+ if (target.tagName === "BODY") {
+ return swapInnerHTML(target, fragment, settleInfo);
+ } else {
+ var eltBeforeNewContent = target.previousSibling;
+ insertNodesBefore(parentElt(target), target, fragment, settleInfo);
+ if (eltBeforeNewContent == null) {
+ var newElt = parentElt(target).firstChild;
+ } else {
+ var newElt = eltBeforeNewContent.nextSibling;
+ }
+ getInternalData(target).replacedWith = newElt; // tuck away so we can fire events on it later
+ settleInfo.elts = [] // clear existing elements
+ while(newElt && newElt !== target) {
+ if (newElt.nodeType === Node.ELEMENT_NODE) {
+ settleInfo.elts.push(newElt);
+ }
+ newElt = newElt.nextElementSibling;
+ }
+ cleanUpElement(target);
+ parentElt(target).removeChild(target);
+ }
+ }
+
+ function swapAfterBegin(target, fragment, settleInfo) {
+ return insertNodesBefore(target, target.firstChild, fragment, settleInfo);
+ }
+
+ function swapBeforeBegin(target, fragment, settleInfo) {
+ return insertNodesBefore(parentElt(target), target, fragment, settleInfo);
+ }
+
+ function swapBeforeEnd(target, fragment, settleInfo) {
+ return insertNodesBefore(target, null, fragment, settleInfo);
+ }
+
+ function swapAfterEnd(target, fragment, settleInfo) {
+ return insertNodesBefore(parentElt(target), target.nextSibling, fragment, settleInfo);
+ }
+
+ function swapInnerHTML(target, fragment, settleInfo) {
+ var firstChild = target.firstChild;
+ insertNodesBefore(target, firstChild, fragment, settleInfo);
+ if (firstChild) {
+ while (firstChild.nextSibling) {
+ cleanUpElement(firstChild.nextSibling)
+ target.removeChild(firstChild.nextSibling);
+ }
+ cleanUpElement(firstChild)
+ target.removeChild(firstChild);
+ }
+ }
+
+ function maybeSelectFromResponse(elt, fragment) {
+ var selector = getClosestAttributeValue(elt, "hx-select");
+ if (selector) {
+ var newFragment = getDocument().createDocumentFragment();
+ forEach(fragment.querySelectorAll(selector), function (node) {
+ newFragment.appendChild(node);
+ });
+ fragment = newFragment;
+ }
+ return fragment;
+ }
+
+ function swap(swapStyle, elt, target, fragment, settleInfo) {
+ switch (swapStyle) {
+ case "none":
+ return;
+ case "outerHTML":
+ swapOuterHTML(target, fragment, settleInfo);
+ return;
+ case "afterbegin":
+ swapAfterBegin(target, fragment, settleInfo);
+ return;
+ case "beforebegin":
+ swapBeforeBegin(target, fragment, settleInfo);
+ return;
+ case "beforeend":
+ swapBeforeEnd(target, fragment, settleInfo);
+ return;
+ case "afterend":
+ swapAfterEnd(target, fragment, settleInfo);
+ return;
+ default:
+ var extensions = getExtensions(elt);
+ for (var i = 0; i < extensions.length; i++) {
+ var ext = extensions[i];
+ try {
+ var newElements = ext.handleSwap(swapStyle, target, fragment, settleInfo);
+ if (newElements) {
+ if (typeof newElements.length !== 'undefined') {
+ // if handleSwap returns an array (like) of elements, we handle them
+ for (var j = 0; j < newElements.length; j++) {
+ var child = newElements[j];
+ if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) {
+ settleInfo.tasks.push(makeAjaxLoadTask(child));
+ }
+ }
+ }
+ return;
+ }
+ } catch (e) {
+ logError(e);
+ }
+ }
+ swapInnerHTML(target, fragment, settleInfo);
+ }
+ }
+
+ function findTitle(content) {
+ if (content.indexOf(' -1) {
+ var contentWithSvgsRemoved = content.replace(/