{"version":3,"file":"admin-YJ3prU0T.js","sources":["../../../node_modules/@asgerb/apparatus/package/dist/admin.mjs","../../../node_modules/tom-select/dist/esm/tom-select.complete.js","../../../node_modules/@shopify/draggable/build/esm/shared/AbstractEvent/AbstractEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/shared/AbstractPlugin/AbstractPlugin.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Sensors/Sensor/Sensor.mjs","../../../node_modules/@shopify/draggable/build/esm/shared/utils/closest/closest.mjs","../../../node_modules/@shopify/draggable/build/esm/shared/utils/distance/distance.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Sensors/SensorEvent/SensorEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Sensors/MouseSensor/MouseSensor.mjs","../../../node_modules/@shopify/draggable/build/esm/shared/utils/touchCoords/touchCoords.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Sensors/TouchSensor/TouchSensor.mjs","../../../node_modules/@shopify/draggable/build/esm/Plugins/Collidable/CollidableEvent/CollidableEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/_virtual/_rollupPluginBabelHelpers.mjs","../../../node_modules/@shopify/draggable/build/esm/shared/utils/decorators/AutoBind.mjs","../../../node_modules/@shopify/draggable/build/esm/shared/utils/requestNextAnimationFrame/requestNextAnimationFrame.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/DragEvent/DragEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/Plugins/ResizeMirror/ResizeMirror.mjs","../../../node_modules/@shopify/draggable/build/esm/Plugins/Snappable/SnappableEvent/SnappableEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/Plugins/SwapAnimation/SwapAnimation.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Plugins/Announcement/Announcement.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Plugins/Focusable/Focusable.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Plugins/Mirror/MirrorEvent/MirrorEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Plugins/Mirror/Mirror.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Plugins/Scrollable/Scrollable.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Emitter/Emitter.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/DraggableEvent/DraggableEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/Draggable/Draggable.mjs","../../../node_modules/@shopify/draggable/build/esm/Droppable/DroppableEvent/DroppableEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/Swappable/SwappableEvent/SwappableEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/Sortable/SortableEvent/SortableEvent.mjs","../../../node_modules/@shopify/draggable/build/esm/Sortable/Sortable.mjs","../../../app/frontend/admin/controllers/extensions/tom_select_sortable.js","../../../app/frontend/admin/controllers/filterable_select_input_controller.js","../../../app/frontend/admin/controllers/resource_select_input_controller.js","../../../node_modules/@asgerb/apparatus/package/dist/controllers.mjs","../../../app/frontend/admin/controllers/index.js"],"sourcesContent":["var __accessCheck = (obj, member, msg) => {\n if (!member.has(obj))\n throw TypeError(\"Cannot \" + msg);\n};\nvar __privateAdd = (obj, member, value) => {\n if (member.has(obj))\n throw TypeError(\"Cannot add the same private member more than once\");\n member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\n};\nvar __privateMethod = (obj, member, method) => {\n __accessCheck(obj, member, \"access private method\");\n return method;\n};\nvar _childrenChange, childrenChange_fn;\nconst formSelector = \".Apparatus-Blocks-Editor__block--form\";\nclass ApparatusBlockEditor extends HTMLElement {\n constructor() {\n super();\n __privateAdd(this, _childrenChange);\n new MutationObserver(() => __privateMethod(this, _childrenChange, childrenChange_fn).call(this)).observe(this, {\n childList: true\n });\n }\n connectedCallback() {\n __privateMethod(this, _childrenChange, childrenChange_fn).call(this);\n }\n get editing() {\n return this.hasAttribute(\"editing\");\n }\n set editing(value) {\n if (!!value) {\n this.setAttribute(\"editing\", \"\");\n } else {\n this.removeAttribute(\"editing\");\n }\n }\n}\n_childrenChange = new WeakSet();\nchildrenChange_fn = function() {\n this.editing = !!this.querySelector(formSelector);\n};\ncustomElements.define(\"apparatus-block-editor\", ApparatusBlockEditor);\nclass DetailsMenuElement extends HTMLElement {\n get preload() {\n return this.hasAttribute(\"preload\");\n }\n set preload(value) {\n if (value) {\n this.setAttribute(\"preload\", \"\");\n } else {\n this.removeAttribute(\"preload\");\n }\n }\n get src() {\n return this.getAttribute(\"src\") || \"\";\n }\n set src(value) {\n this.setAttribute(\"src\", value);\n }\n connectedCallback() {\n if (!this.hasAttribute(\"role\"))\n this.setAttribute(\"role\", \"menu\");\n const details = this.parentElement;\n if (!details)\n return;\n const summary = details.querySelector(\"summary\");\n if (summary) {\n summary.setAttribute(\"aria-haspopup\", \"menu\");\n if (!summary.hasAttribute(\"role\"))\n summary.setAttribute(\"role\", \"button\");\n }\n const subscriptions = [\n fromEvent(details, \"compositionstart\", (e) => trackComposition$1(this, e)),\n fromEvent(details, \"compositionend\", (e) => trackComposition$1(this, e)),\n fromEvent(details, \"click\", (e) => shouldCommit(details, e)),\n fromEvent(details, \"change\", (e) => shouldCommit(details, e)),\n fromEvent(details, \"keydown\", (e) => keydown$1(details, this, e)),\n fromEvent(details, \"toggle\", () => loadFragment(details, this), { once: true }),\n fromEvent(details, \"toggle\", () => closeCurrentMenu(details)),\n this.preload ? fromEvent(details, \"mouseover\", () => loadFragment(details, this), { once: true }) : NullSubscription,\n ...focusOnOpen(details)\n ];\n states$1.set(this, { subscriptions, loaded: false, isComposing: false });\n }\n disconnectedCallback() {\n const state = states$1.get(this);\n if (!state)\n return;\n states$1.delete(this);\n for (const sub of state.subscriptions) {\n sub.unsubscribe();\n }\n }\n}\nconst states$1 = /* @__PURE__ */ new WeakMap();\nconst NullSubscription = {\n unsubscribe() {\n }\n};\nfunction fromEvent(target, eventName, onNext, options = false) {\n target.addEventListener(eventName, onNext, options);\n return {\n unsubscribe: () => {\n target.removeEventListener(eventName, onNext, options);\n }\n };\n}\nfunction loadFragment(details, menu) {\n const src = menu.getAttribute(\"src\");\n if (!src)\n return;\n const state = states$1.get(menu);\n if (!state)\n return;\n if (state.loaded)\n return;\n state.loaded = true;\n const loader = menu.querySelector(\"include-fragment\");\n if (loader && !loader.hasAttribute(\"src\")) {\n loader.addEventListener(\"loadend\", () => autofocus(details));\n loader.setAttribute(\"src\", src);\n }\n}\nfunction focusOnOpen(details) {\n let isMouse = false;\n const onmousedown = () => isMouse = true;\n const onkeydown = () => isMouse = false;\n const ontoggle = () => {\n if (!details.hasAttribute(\"open\"))\n return;\n if (autofocus(details))\n return;\n if (!isMouse)\n focusFirstItem(details);\n };\n return [\n fromEvent(details, \"mousedown\", onmousedown),\n fromEvent(details, \"keydown\", onkeydown),\n fromEvent(details, \"toggle\", ontoggle)\n ];\n}\nfunction closeCurrentMenu(details) {\n if (!details.hasAttribute(\"open\"))\n return;\n for (const menu of document.querySelectorAll(\"details[open] > details-menu\")) {\n const opened = menu.closest(\"details\");\n if (opened && opened !== details && !opened.contains(details)) {\n opened.removeAttribute(\"open\");\n }\n }\n}\nfunction autofocus(details) {\n if (!details.hasAttribute(\"open\"))\n return false;\n const input = details.querySelector(\"details-menu [autofocus]\");\n if (input) {\n input.focus();\n return true;\n } else {\n return false;\n }\n}\nfunction focusFirstItem(details) {\n const selected = document.activeElement;\n if (selected && isMenuItem(selected) && details.contains(selected))\n return;\n const target = sibling(details, true);\n if (target)\n target.focus();\n}\nfunction sibling(details, next) {\n const options = Array.from(details.querySelectorAll('[role^=\"menuitem\"]:not([hidden]):not([disabled])'));\n const selected = document.activeElement;\n const index = selected instanceof HTMLElement ? options.indexOf(selected) : -1;\n const found = next ? options[index + 1] : options[index - 1];\n const def = next ? options[0] : options[options.length - 1];\n return found || def;\n}\nconst ctrlBindings$1 = navigator.userAgent.match(/Macintosh/);\nfunction shouldCommit(details, event) {\n const target = event.target;\n if (!(target instanceof Element))\n return;\n if (target.closest(\"details\") !== details)\n return;\n if (event.type === \"click\") {\n const menuitem = target.closest('[role=\"menuitem\"], [role=\"menuitemradio\"]');\n if (!menuitem)\n return;\n const input = menuitem.querySelector(\"input\");\n if (menuitem.tagName === \"LABEL\" && target === input)\n return;\n const onlyCommitOnChangeEvent = menuitem.tagName === \"LABEL\" && input && !input.checked;\n if (!onlyCommitOnChangeEvent) {\n commit$1(menuitem, details);\n }\n } else if (event.type === \"change\") {\n const menuitem = target.closest('[role=\"menuitemradio\"], [role=\"menuitemcheckbox\"]');\n if (menuitem)\n commit$1(menuitem, details);\n }\n}\nfunction updateChecked(selected, details) {\n for (const el of details.querySelectorAll('[role=\"menuitemradio\"], [role=\"menuitemcheckbox\"]')) {\n const input = el.querySelector('input[type=\"radio\"], input[type=\"checkbox\"]');\n let checkState = (el === selected).toString();\n if (input instanceof HTMLInputElement) {\n checkState = input.indeterminate ? \"mixed\" : input.checked.toString();\n }\n el.setAttribute(\"aria-checked\", checkState);\n }\n}\nfunction commit$1(selected, details) {\n if (selected.hasAttribute(\"disabled\") || selected.getAttribute(\"aria-disabled\") === \"true\")\n return;\n const menu = selected.closest(\"details-menu\");\n if (!menu)\n return;\n const dispatched = menu.dispatchEvent(new CustomEvent(\"details-menu-select\", {\n cancelable: true,\n detail: { relatedTarget: selected }\n }));\n if (!dispatched)\n return;\n updateLabel(selected, details);\n updateChecked(selected, details);\n if (selected.getAttribute(\"role\") !== \"menuitemcheckbox\")\n close(details);\n menu.dispatchEvent(new CustomEvent(\"details-menu-selected\", {\n detail: { relatedTarget: selected }\n }));\n}\nfunction keydown$1(details, menu, event) {\n if (!(event instanceof KeyboardEvent))\n return;\n if (details.querySelector(\"details[open]\"))\n return;\n const state = states$1.get(menu);\n if (!state || state.isComposing)\n return;\n const isSummaryFocused = event.target instanceof Element && event.target.tagName === \"SUMMARY\";\n switch (event.key) {\n case \"Escape\":\n if (details.hasAttribute(\"open\")) {\n close(details);\n event.preventDefault();\n event.stopPropagation();\n }\n break;\n case \"ArrowDown\":\n {\n if (isSummaryFocused && !details.hasAttribute(\"open\")) {\n details.setAttribute(\"open\", \"\");\n }\n const target = sibling(details, true);\n if (target)\n target.focus();\n event.preventDefault();\n }\n break;\n case \"ArrowUp\":\n {\n if (isSummaryFocused && !details.hasAttribute(\"open\")) {\n details.setAttribute(\"open\", \"\");\n }\n const target = sibling(details, false);\n if (target)\n target.focus();\n event.preventDefault();\n }\n break;\n case \"n\":\n {\n if (ctrlBindings$1 && event.ctrlKey) {\n const target = sibling(details, true);\n if (target)\n target.focus();\n event.preventDefault();\n }\n }\n break;\n case \"p\":\n {\n if (ctrlBindings$1 && event.ctrlKey) {\n const target = sibling(details, false);\n if (target)\n target.focus();\n event.preventDefault();\n }\n }\n break;\n case \" \":\n case \"Enter\":\n {\n const selected = document.activeElement;\n if (selected instanceof HTMLElement && isMenuItem(selected) && selected.closest(\"details\") === details) {\n event.preventDefault();\n event.stopPropagation();\n selected.click();\n }\n }\n break;\n }\n}\nfunction isMenuItem(el) {\n const role = el.getAttribute(\"role\");\n return role === \"menuitem\" || role === \"menuitemcheckbox\" || role === \"menuitemradio\";\n}\nfunction close(details) {\n const wasOpen = details.hasAttribute(\"open\");\n if (!wasOpen)\n return;\n details.removeAttribute(\"open\");\n const summary = details.querySelector(\"summary\");\n if (summary)\n summary.focus();\n}\nfunction updateLabel(item, details) {\n const button = details.querySelector(\"[data-menu-button]\");\n if (!button)\n return;\n const text = labelText(item);\n if (text) {\n button.textContent = text;\n } else {\n const html = labelHTML(item);\n if (html)\n button.innerHTML = html;\n }\n}\nfunction labelText(el) {\n if (!el)\n return null;\n const textEl = el.hasAttribute(\"data-menu-button-text\") ? el : el.querySelector(\"[data-menu-button-text]\");\n if (!textEl)\n return null;\n return textEl.getAttribute(\"data-menu-button-text\") || textEl.textContent;\n}\nfunction labelHTML(el) {\n if (!el)\n return null;\n const contentsEl = el.hasAttribute(\"data-menu-button-contents\") ? el : el.querySelector(\"[data-menu-button-contents]\");\n return contentsEl ? contentsEl.innerHTML : null;\n}\nfunction trackComposition$1(menu, event) {\n const state = states$1.get(menu);\n if (!state)\n return;\n state.isComposing = event.type === \"compositionstart\";\n}\nif (!window.customElements.get(\"details-menu\")) {\n window.DetailsMenuElement = DetailsMenuElement;\n window.customElements.define(\"details-menu\", DetailsMenuElement);\n}\nclass FilterInputElement extends HTMLElement {\n constructor() {\n super();\n this.currentQuery = null;\n this.filter = null;\n this.debounceInputChange = debounce(() => filterResults(this, true));\n this.boundFilterResults = () => {\n filterResults(this, false);\n };\n }\n static get observedAttributes() {\n return [\"aria-owns\"];\n }\n attributeChangedCallback(name, oldValue) {\n if (oldValue && name === \"aria-owns\") {\n filterResults(this, false);\n }\n }\n connectedCallback() {\n const input = this.input;\n if (!input)\n return;\n input.setAttribute(\"autocomplete\", \"off\");\n input.setAttribute(\"spellcheck\", \"false\");\n input.addEventListener(\"focus\", this.boundFilterResults);\n input.addEventListener(\"change\", this.boundFilterResults);\n input.addEventListener(\"input\", this.debounceInputChange);\n }\n disconnectedCallback() {\n const input = this.input;\n if (!input)\n return;\n input.removeEventListener(\"focus\", this.boundFilterResults);\n input.removeEventListener(\"change\", this.boundFilterResults);\n input.removeEventListener(\"input\", this.debounceInputChange);\n }\n get input() {\n const input = this.querySelector(\"input\");\n return input instanceof HTMLInputElement ? input : null;\n }\n reset() {\n const input = this.input;\n if (input) {\n input.value = \"\";\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n }\n}\nasync function filterResults(filterInput, checkCurrentQuery = false) {\n const input = filterInput.input;\n if (!input)\n return;\n const query2 = input.value.trim();\n const id = filterInput.getAttribute(\"aria-owns\");\n if (!id)\n return;\n const container = document.getElementById(id);\n if (!container)\n return;\n const list = container.hasAttribute(\"data-filter-list\") ? container : container.querySelector(\"[data-filter-list]\");\n if (!list)\n return;\n filterInput.dispatchEvent(new CustomEvent(\"filter-input-start\", {\n bubbles: true\n }));\n if (checkCurrentQuery && filterInput.currentQuery === query2)\n return;\n filterInput.currentQuery = query2;\n const filter = filterInput.filter || matchSubstring;\n const total = list.childElementCount;\n let count = 0;\n let hideNew = false;\n for (const item of Array.from(list.children)) {\n if (!(item instanceof HTMLElement))\n continue;\n const itemText = getText(item);\n const result = filter(item, itemText, query2);\n if (result.hideNew === true)\n hideNew = result.hideNew;\n item.hidden = !result.match;\n if (result.match)\n count++;\n }\n const newItem = container.querySelector(\"[data-filter-new-item]\");\n const showCreateOption = !!newItem && query2.length > 0 && !hideNew;\n if (newItem instanceof HTMLElement) {\n newItem.hidden = !showCreateOption;\n if (showCreateOption)\n updateNewItem(newItem, query2);\n }\n toggleBlankslate(container, count > 0 || showCreateOption);\n filterInput.dispatchEvent(new CustomEvent(\"filter-input-updated\", {\n bubbles: true,\n detail: {\n count,\n total\n }\n }));\n}\nfunction matchSubstring(_item, itemText, query2) {\n const match = itemText.toLowerCase().indexOf(query2.toLowerCase()) !== -1;\n return {\n match,\n hideNew: itemText === query2\n };\n}\nfunction getText(filterableItem) {\n const target = filterableItem.querySelector(\"[data-filter-item-text]\") || filterableItem;\n return (target.textContent || \"\").trim();\n}\nfunction updateNewItem(newItem, query2) {\n const newItemText = newItem.querySelector(\"[data-filter-new-item-text]\");\n if (newItemText)\n newItemText.textContent = query2;\n const newItemValue = newItem.querySelector(\"[data-filter-new-item-value]\");\n if (newItemValue instanceof HTMLInputElement || newItemValue instanceof HTMLButtonElement) {\n newItemValue.value = query2;\n }\n}\nfunction toggleBlankslate(container, force) {\n const emptyState = container.querySelector(\"[data-filter-empty-state]\");\n if (emptyState instanceof HTMLElement)\n emptyState.hidden = force;\n}\nfunction debounce(callback) {\n let timeout;\n return function() {\n clearTimeout(timeout);\n timeout = setTimeout(() => {\n clearTimeout(timeout);\n callback();\n }, 300);\n };\n}\nif (!window.customElements.get(\"filter-input\")) {\n window.FilterInputElement = FilterInputElement;\n window.customElements.define(\"filter-input\", FilterInputElement);\n}\nvar __classPrivateFieldGet$3 = globalThis && globalThis.__classPrivateFieldGet || function(receiver, state, kind, f) {\n if (kind === \"a\" && !f)\n throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver))\n throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n};\nvar __classPrivateFieldSet$2 = globalThis && globalThis.__classPrivateFieldSet || function(receiver, state, value, kind, f) {\n if (kind === \"m\")\n throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f)\n throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver))\n throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;\n};\nvar _IncludeFragmentElement_instances, _IncludeFragmentElement_busy, _IncludeFragmentElement_observer, _IncludeFragmentElement_handleData, _IncludeFragmentElement_getData, _IncludeFragmentElement_getStringOrErrorData, _IncludeFragmentElement_task, _IncludeFragmentElement_fetchDataWithEvents;\nconst privateData = /* @__PURE__ */ new WeakMap();\nfunction isWildcard(accept) {\n return accept && !!accept.split(\",\").find((x) => x.match(/^\\s*\\*\\/\\*/));\n}\nlet cspTrustedTypesPolicyPromise = null;\nclass IncludeFragmentElement extends HTMLElement {\n constructor() {\n super(...arguments);\n _IncludeFragmentElement_instances.add(this);\n _IncludeFragmentElement_busy.set(this, false);\n _IncludeFragmentElement_observer.set(this, new IntersectionObserver((entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n const { target } = entry;\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_observer, \"f\").unobserve(target);\n if (!(target instanceof IncludeFragmentElement))\n return;\n if (target.loading === \"lazy\") {\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_handleData).call(this);\n }\n }\n }\n }, {\n rootMargin: \"0px 0px 256px 0px\",\n threshold: 0.01\n }));\n }\n static define(tag = \"include-fragment\", registry = customElements) {\n registry.define(tag, this);\n return this;\n }\n static setCSPTrustedTypesPolicy(policy) {\n cspTrustedTypesPolicyPromise = policy === null ? policy : Promise.resolve(policy);\n }\n static get observedAttributes() {\n return [\"src\", \"loading\"];\n }\n get src() {\n const src = this.getAttribute(\"src\");\n if (src) {\n const link = this.ownerDocument.createElement(\"a\");\n link.href = src;\n return link.href;\n } else {\n return \"\";\n }\n }\n set src(val) {\n this.setAttribute(\"src\", val);\n }\n get loading() {\n if (this.getAttribute(\"loading\") === \"lazy\")\n return \"lazy\";\n return \"eager\";\n }\n set loading(value) {\n this.setAttribute(\"loading\", value);\n }\n get accept() {\n return this.getAttribute(\"accept\") || \"\";\n }\n set accept(val) {\n this.setAttribute(\"accept\", val);\n }\n get data() {\n return __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_getStringOrErrorData).call(this);\n }\n attributeChangedCallback(attribute, oldVal) {\n if (attribute === \"src\") {\n if (this.isConnected && this.loading === \"eager\") {\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_handleData).call(this);\n }\n } else if (attribute === \"loading\") {\n if (this.isConnected && oldVal !== \"eager\" && this.loading === \"eager\") {\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_handleData).call(this);\n }\n }\n }\n connectedCallback() {\n if (!this.shadowRoot) {\n this.attachShadow({ mode: \"open\" });\n const style = document.createElement(\"style\");\n style.textContent = `:host {display: block;}`;\n this.shadowRoot.append(style, document.createElement(\"slot\"));\n }\n if (this.src && this.loading === \"eager\") {\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_handleData).call(this);\n }\n if (this.loading === \"lazy\") {\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_observer, \"f\").observe(this);\n }\n }\n request() {\n const src = this.src;\n if (!src) {\n throw new Error(\"missing src\");\n }\n return new Request(src, {\n method: \"GET\",\n credentials: \"same-origin\",\n headers: {\n Accept: this.accept || \"text/html\"\n }\n });\n }\n load() {\n return __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_getStringOrErrorData).call(this);\n }\n fetch(request) {\n return fetch(request);\n }\n refetch() {\n privateData.delete(this);\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_handleData).call(this);\n }\n}\n_IncludeFragmentElement_busy = /* @__PURE__ */ new WeakMap(), _IncludeFragmentElement_observer = /* @__PURE__ */ new WeakMap(), _IncludeFragmentElement_instances = /* @__PURE__ */ new WeakSet(), _IncludeFragmentElement_handleData = async function _IncludeFragmentElement_handleData2() {\n if (__classPrivateFieldGet$3(this, _IncludeFragmentElement_busy, \"f\"))\n return;\n __classPrivateFieldSet$2(this, _IncludeFragmentElement_busy, true, \"f\");\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_observer, \"f\").unobserve(this);\n try {\n const data = await __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_getData).call(this);\n if (data instanceof Error) {\n throw data;\n }\n const dataTreatedAsString = data;\n const template = document.createElement(\"template\");\n template.innerHTML = dataTreatedAsString;\n const fragment = document.importNode(template.content, true);\n const canceled = !this.dispatchEvent(new CustomEvent(\"include-fragment-replace\", {\n cancelable: true,\n detail: { fragment }\n }));\n if (canceled) {\n __classPrivateFieldSet$2(this, _IncludeFragmentElement_busy, false, \"f\");\n return;\n }\n this.replaceWith(fragment);\n this.dispatchEvent(new CustomEvent(\"include-fragment-replaced\"));\n } catch (_a) {\n this.classList.add(\"is-error\");\n } finally {\n __classPrivateFieldSet$2(this, _IncludeFragmentElement_busy, false, \"f\");\n }\n}, _IncludeFragmentElement_getData = async function _IncludeFragmentElement_getData2() {\n const src = this.src;\n const cachedData = privateData.get(this);\n if (cachedData && cachedData.src === src) {\n return cachedData.data;\n } else {\n let data;\n if (src) {\n data = __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_fetchDataWithEvents).call(this);\n } else {\n data = Promise.reject(new Error(\"missing src\"));\n }\n privateData.set(this, { src, data });\n return data;\n }\n}, _IncludeFragmentElement_getStringOrErrorData = async function _IncludeFragmentElement_getStringOrErrorData2() {\n const data = await __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_getData).call(this);\n if (data instanceof Error) {\n throw data;\n }\n return data.toString();\n}, _IncludeFragmentElement_task = async function _IncludeFragmentElement_task2(eventsToDispatch) {\n await new Promise((resolve) => setTimeout(resolve, 0));\n for (const eventType of eventsToDispatch) {\n this.dispatchEvent(new Event(eventType));\n }\n}, _IncludeFragmentElement_fetchDataWithEvents = async function _IncludeFragmentElement_fetchDataWithEvents2() {\n try {\n await __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_task).call(this, [\"loadstart\"]);\n const response = await this.fetch(this.request());\n if (response.status !== 200) {\n throw new Error(`Failed to load resource: the server responded with a status of ${response.status}`);\n }\n const ct = response.headers.get(\"Content-Type\");\n if (!isWildcard(this.accept) && (!ct || !ct.includes(this.accept ? this.accept : \"text/html\"))) {\n throw new Error(`Failed to load resource: expected ${this.accept || \"text/html\"} but was ${ct}`);\n }\n const responseText = await response.text();\n let data = responseText;\n if (cspTrustedTypesPolicyPromise) {\n const cspTrustedTypesPolicy = await cspTrustedTypesPolicyPromise;\n data = cspTrustedTypesPolicy.createHTML(responseText, response);\n }\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_task).call(this, [\"load\", \"loadend\"]);\n return data;\n } catch (error) {\n __classPrivateFieldGet$3(this, _IncludeFragmentElement_instances, \"m\", _IncludeFragmentElement_task).call(this, [\"error\", \"loadend\"]);\n throw error;\n }\n};\nconst root$1 = typeof globalThis !== \"undefined\" ? globalThis : window;\ntry {\n root$1.IncludeFragmentElement = IncludeFragmentElement.define();\n} catch (e) {\n if (!(root$1.DOMException && e instanceof DOMException && e.name === \"NotSupportedError\") && !(e instanceof ReferenceError)) {\n throw e;\n }\n}\nvar __classPrivateFieldGet$2 = globalThis && globalThis.__classPrivateFieldGet || function(receiver, state, kind, f) {\n if (kind === \"a\" && !f)\n throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver))\n throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n};\nvar _MarkdownHeaderButtonElement_instances, _MarkdownHeaderButtonElement_setLevelStyle;\nconst buttonSelectors = [\n \"[data-md-button]\",\n \"md-header\",\n \"md-bold\",\n \"md-italic\",\n \"md-quote\",\n \"md-code\",\n \"md-link\",\n \"md-image\",\n \"md-unordered-list\",\n \"md-ordered-list\",\n \"md-task-list\",\n \"md-mention\",\n \"md-ref\",\n \"md-strikethrough\"\n];\nfunction getButtons(toolbar) {\n const els = [];\n for (const button of toolbar.querySelectorAll(buttonSelectors.join(\", \"))) {\n if (button.hidden || button.offsetWidth <= 0 && button.offsetHeight <= 0)\n continue;\n if (button.closest(\"markdown-toolbar\") === toolbar)\n els.push(button);\n }\n return els;\n}\nfunction keydown(fn) {\n return function(event) {\n if (event.key === \" \" || event.key === \"Enter\") {\n fn(event);\n }\n };\n}\nconst styles = /* @__PURE__ */ new WeakMap();\nconst manualStyles = {\n \"header-1\": { prefix: \"# \" },\n \"header-2\": { prefix: \"## \" },\n \"header-3\": { prefix: \"### \" },\n \"header-4\": { prefix: \"#### \" },\n \"header-5\": { prefix: \"##### \" },\n \"header-6\": { prefix: \"###### \" },\n bold: { prefix: \"**\", suffix: \"**\", trimFirst: true },\n italic: { prefix: \"_\", suffix: \"_\", trimFirst: true },\n quote: { prefix: \"> \", multiline: true, surroundWithNewlines: true },\n code: {\n prefix: \"`\",\n suffix: \"`\",\n blockPrefix: \"```\",\n blockSuffix: \"```\"\n },\n link: { prefix: \"[\", suffix: \"](url)\", replaceNext: \"url\", scanFor: \"https?://\" },\n image: { prefix: \"![\", suffix: \"](url)\", replaceNext: \"url\", scanFor: \"https?://\" },\n \"unordered-list\": {\n prefix: \"- \",\n multiline: true,\n unorderedList: true\n },\n \"ordered-list\": {\n prefix: \"1. \",\n multiline: true,\n orderedList: true\n },\n \"task-list\": { prefix: \"- [ ] \", multiline: true, surroundWithNewlines: true },\n mention: { prefix: \"@\", prefixSpace: true },\n ref: { prefix: \"#\", prefixSpace: true },\n strikethrough: { prefix: \"~~\", suffix: \"~~\", trimFirst: true }\n};\nclass MarkdownButtonElement extends HTMLElement {\n constructor() {\n super();\n const apply = (event) => {\n const style = styles.get(this);\n if (!style)\n return;\n event.preventDefault();\n applyStyle(this, style);\n };\n this.addEventListener(\"keydown\", keydown(apply));\n this.addEventListener(\"click\", apply);\n }\n connectedCallback() {\n if (!this.hasAttribute(\"role\")) {\n this.setAttribute(\"role\", \"button\");\n }\n }\n click() {\n const style = styles.get(this);\n if (!style)\n return;\n applyStyle(this, style);\n }\n}\nclass MarkdownHeaderButtonElement extends MarkdownButtonElement {\n constructor() {\n super(...arguments);\n _MarkdownHeaderButtonElement_instances.add(this);\n }\n connectedCallback() {\n const level = parseInt(this.getAttribute(\"level\") || \"3\", 10);\n __classPrivateFieldGet$2(this, _MarkdownHeaderButtonElement_instances, \"m\", _MarkdownHeaderButtonElement_setLevelStyle).call(this, level);\n }\n static get observedAttributes() {\n return [\"level\"];\n }\n attributeChangedCallback(name, oldValue, newValue) {\n if (name !== \"level\")\n return;\n const level = parseInt(newValue || \"3\", 10);\n __classPrivateFieldGet$2(this, _MarkdownHeaderButtonElement_instances, \"m\", _MarkdownHeaderButtonElement_setLevelStyle).call(this, level);\n }\n}\n_MarkdownHeaderButtonElement_instances = /* @__PURE__ */ new WeakSet(), _MarkdownHeaderButtonElement_setLevelStyle = function _MarkdownHeaderButtonElement_setLevelStyle2(level) {\n if (level < 1 || level > 6) {\n return;\n }\n const prefix = `${\"#\".repeat(level)} `;\n styles.set(this, {\n prefix\n });\n};\nif (!window.customElements.get(\"md-header\")) {\n window.MarkdownHeaderButtonElement = MarkdownHeaderButtonElement;\n window.customElements.define(\"md-header\", MarkdownHeaderButtonElement);\n}\nclass MarkdownBoldButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"**\", suffix: \"**\", trimFirst: true });\n }\n}\nif (!window.customElements.get(\"md-bold\")) {\n window.MarkdownBoldButtonElement = MarkdownBoldButtonElement;\n window.customElements.define(\"md-bold\", MarkdownBoldButtonElement);\n}\nclass MarkdownItalicButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"_\", suffix: \"_\", trimFirst: true });\n }\n}\nif (!window.customElements.get(\"md-italic\")) {\n window.MarkdownItalicButtonElement = MarkdownItalicButtonElement;\n window.customElements.define(\"md-italic\", MarkdownItalicButtonElement);\n}\nclass MarkdownQuoteButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"> \", multiline: true, surroundWithNewlines: true });\n }\n}\nif (!window.customElements.get(\"md-quote\")) {\n window.MarkdownQuoteButtonElement = MarkdownQuoteButtonElement;\n window.customElements.define(\"md-quote\", MarkdownQuoteButtonElement);\n}\nclass MarkdownCodeButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"`\", suffix: \"`\", blockPrefix: \"```\", blockSuffix: \"```\" });\n }\n}\nif (!window.customElements.get(\"md-code\")) {\n window.MarkdownCodeButtonElement = MarkdownCodeButtonElement;\n window.customElements.define(\"md-code\", MarkdownCodeButtonElement);\n}\nclass MarkdownLinkButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"[\", suffix: \"](url)\", replaceNext: \"url\", scanFor: \"https?://\" });\n }\n}\nif (!window.customElements.get(\"md-link\")) {\n window.MarkdownLinkButtonElement = MarkdownLinkButtonElement;\n window.customElements.define(\"md-link\", MarkdownLinkButtonElement);\n}\nclass MarkdownImageButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"![\", suffix: \"](url)\", replaceNext: \"url\", scanFor: \"https?://\" });\n }\n}\nif (!window.customElements.get(\"md-image\")) {\n window.MarkdownImageButtonElement = MarkdownImageButtonElement;\n window.customElements.define(\"md-image\", MarkdownImageButtonElement);\n}\nclass MarkdownUnorderedListButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"- \", multiline: true, unorderedList: true });\n }\n}\nif (!window.customElements.get(\"md-unordered-list\")) {\n window.MarkdownUnorderedListButtonElement = MarkdownUnorderedListButtonElement;\n window.customElements.define(\"md-unordered-list\", MarkdownUnorderedListButtonElement);\n}\nclass MarkdownOrderedListButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"1. \", multiline: true, orderedList: true });\n }\n}\nif (!window.customElements.get(\"md-ordered-list\")) {\n window.MarkdownOrderedListButtonElement = MarkdownOrderedListButtonElement;\n window.customElements.define(\"md-ordered-list\", MarkdownOrderedListButtonElement);\n}\nclass MarkdownTaskListButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"- [ ] \", multiline: true, surroundWithNewlines: true });\n }\n}\nif (!window.customElements.get(\"md-task-list\")) {\n window.MarkdownTaskListButtonElement = MarkdownTaskListButtonElement;\n window.customElements.define(\"md-task-list\", MarkdownTaskListButtonElement);\n}\nclass MarkdownMentionButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"@\", prefixSpace: true });\n }\n}\nif (!window.customElements.get(\"md-mention\")) {\n window.MarkdownMentionButtonElement = MarkdownMentionButtonElement;\n window.customElements.define(\"md-mention\", MarkdownMentionButtonElement);\n}\nclass MarkdownRefButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"#\", prefixSpace: true });\n }\n}\nif (!window.customElements.get(\"md-ref\")) {\n window.MarkdownRefButtonElement = MarkdownRefButtonElement;\n window.customElements.define(\"md-ref\", MarkdownRefButtonElement);\n}\nclass MarkdownStrikethroughButtonElement extends MarkdownButtonElement {\n connectedCallback() {\n styles.set(this, { prefix: \"~~\", suffix: \"~~\", trimFirst: true });\n }\n}\nif (!window.customElements.get(\"md-strikethrough\")) {\n window.MarkdownStrikethroughButtonElement = MarkdownStrikethroughButtonElement;\n window.customElements.define(\"md-strikethrough\", MarkdownStrikethroughButtonElement);\n}\nfunction applyFromToolbar(event) {\n const { target, currentTarget } = event;\n if (!(target instanceof HTMLElement))\n return;\n const mdButton = target.closest(\"[data-md-button]\");\n if (!mdButton || mdButton.closest(\"markdown-toolbar\") !== currentTarget)\n return;\n const mdButtonStyle = target.getAttribute(\"data-md-button\");\n const style = manualStyles[mdButtonStyle];\n if (!style)\n return;\n event.preventDefault();\n applyStyle(target, style);\n}\nfunction setFocusManagement(toolbar) {\n toolbar.addEventListener(\"keydown\", focusKeydown);\n toolbar.setAttribute(\"tabindex\", \"0\");\n toolbar.addEventListener(\"focus\", onToolbarFocus, { once: true });\n}\nfunction unsetFocusManagement(toolbar) {\n toolbar.removeEventListener(\"keydown\", focusKeydown);\n toolbar.removeAttribute(\"tabindex\");\n toolbar.removeEventListener(\"focus\", onToolbarFocus);\n}\nclass MarkdownToolbarElement extends HTMLElement {\n connectedCallback() {\n if (!this.hasAttribute(\"role\")) {\n this.setAttribute(\"role\", \"toolbar\");\n }\n if (!this.hasAttribute(\"data-no-focus\")) {\n setFocusManagement(this);\n }\n this.addEventListener(\"keydown\", keydown(applyFromToolbar));\n this.addEventListener(\"click\", applyFromToolbar);\n }\n attributeChangedCallback(name, oldValue, newValue) {\n if (name !== \"data-no-focus\")\n return;\n if (newValue === null) {\n setFocusManagement(this);\n } else {\n unsetFocusManagement(this);\n }\n }\n disconnectedCallback() {\n unsetFocusManagement(this);\n }\n get field() {\n const id = this.getAttribute(\"for\");\n if (!id)\n return null;\n const root2 = \"getRootNode\" in this ? this.getRootNode() : document;\n let field;\n if (root2 instanceof Document || root2 instanceof ShadowRoot) {\n field = root2.getElementById(id);\n }\n return field instanceof HTMLTextAreaElement ? field : null;\n }\n}\nMarkdownToolbarElement.observedAttributes = [\"data-no-focus\"];\nfunction onToolbarFocus({ target }) {\n if (!(target instanceof Element))\n return;\n target.removeAttribute(\"tabindex\");\n let tabindex = \"0\";\n for (const button of getButtons(target)) {\n button.setAttribute(\"tabindex\", tabindex);\n if (tabindex === \"0\") {\n button.focus();\n tabindex = \"-1\";\n }\n }\n}\nfunction focusKeydown(event) {\n const key = event.key;\n if (key !== \"ArrowRight\" && key !== \"ArrowLeft\" && key !== \"Home\" && key !== \"End\")\n return;\n const toolbar = event.currentTarget;\n if (!(toolbar instanceof HTMLElement))\n return;\n const buttons = getButtons(toolbar);\n const index = buttons.indexOf(event.target);\n const length = buttons.length;\n if (index === -1)\n return;\n let n = 0;\n if (key === \"ArrowLeft\")\n n = index - 1;\n if (key === \"ArrowRight\")\n n = index + 1;\n if (key === \"End\")\n n = length - 1;\n if (n < 0)\n n = length - 1;\n if (n > length - 1)\n n = 0;\n for (let i = 0; i < length; i += 1) {\n buttons[i].setAttribute(\"tabindex\", i === n ? \"0\" : \"-1\");\n }\n event.preventDefault();\n buttons[n].focus();\n}\nif (!window.customElements.get(\"markdown-toolbar\")) {\n window.MarkdownToolbarElement = MarkdownToolbarElement;\n window.customElements.define(\"markdown-toolbar\", MarkdownToolbarElement);\n}\nfunction isMultipleLines(string) {\n return string.trim().split(\"\\n\").length > 1;\n}\nfunction repeat(string, n) {\n return Array(n + 1).join(string);\n}\nfunction wordSelectionStart(text, i) {\n let index = i;\n while (text[index] && text[index - 1] != null && !text[index - 1].match(/\\s/)) {\n index--;\n }\n return index;\n}\nfunction wordSelectionEnd(text, i, multiline) {\n let index = i;\n const breakpoint = multiline ? /\\n/ : /\\s/;\n while (text[index] && !text[index].match(breakpoint)) {\n index++;\n }\n return index;\n}\nlet canInsertText = null;\nfunction insertText(textarea, { text, selectionStart, selectionEnd }) {\n const originalSelectionStart = textarea.selectionStart;\n const before = textarea.value.slice(0, originalSelectionStart);\n const after = textarea.value.slice(textarea.selectionEnd);\n if (canInsertText === null || canInsertText === true) {\n textarea.contentEditable = \"true\";\n try {\n canInsertText = document.execCommand(\"insertText\", false, text);\n } catch (error) {\n canInsertText = false;\n }\n textarea.contentEditable = \"false\";\n }\n if (canInsertText && !textarea.value.slice(0, textarea.selectionStart).endsWith(text)) {\n canInsertText = false;\n }\n if (!canInsertText) {\n try {\n document.execCommand(\"ms-beginUndoUnit\");\n } catch (e) {\n }\n textarea.value = before + text + after;\n try {\n document.execCommand(\"ms-endUndoUnit\");\n } catch (e) {\n }\n textarea.dispatchEvent(new CustomEvent(\"input\", { bubbles: true, cancelable: true }));\n }\n if (selectionStart != null && selectionEnd != null) {\n textarea.setSelectionRange(selectionStart, selectionEnd);\n } else {\n textarea.setSelectionRange(originalSelectionStart, textarea.selectionEnd);\n }\n}\nfunction styleSelectedText(textarea, styleArgs) {\n const text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);\n let result;\n if (styleArgs.orderedList || styleArgs.unorderedList) {\n result = listStyle(textarea, styleArgs);\n } else if (styleArgs.multiline && isMultipleLines(text)) {\n result = multilineStyle(textarea, styleArgs);\n } else {\n result = blockStyle(textarea, styleArgs);\n }\n insertText(textarea, result);\n}\nfunction expandSelectionToLine(textarea) {\n const lines = textarea.value.split(\"\\n\");\n let counter = 0;\n for (let index = 0; index < lines.length; index++) {\n const lineLength = lines[index].length + 1;\n if (textarea.selectionStart >= counter && textarea.selectionStart < counter + lineLength) {\n textarea.selectionStart = counter;\n }\n if (textarea.selectionEnd >= counter && textarea.selectionEnd < counter + lineLength) {\n textarea.selectionEnd = counter + lineLength - 1;\n }\n counter += lineLength;\n }\n}\nfunction expandSelectedText(textarea, prefixToUse, suffixToUse, multiline = false) {\n if (textarea.selectionStart === textarea.selectionEnd) {\n textarea.selectionStart = wordSelectionStart(textarea.value, textarea.selectionStart);\n textarea.selectionEnd = wordSelectionEnd(textarea.value, textarea.selectionEnd, multiline);\n } else {\n const expandedSelectionStart = textarea.selectionStart - prefixToUse.length;\n const expandedSelectionEnd = textarea.selectionEnd + suffixToUse.length;\n const beginsWithPrefix = textarea.value.slice(expandedSelectionStart, textarea.selectionStart) === prefixToUse;\n const endsWithSuffix = textarea.value.slice(textarea.selectionEnd, expandedSelectionEnd) === suffixToUse;\n if (beginsWithPrefix && endsWithSuffix) {\n textarea.selectionStart = expandedSelectionStart;\n textarea.selectionEnd = expandedSelectionEnd;\n }\n }\n return textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);\n}\nfunction newlinesToSurroundSelectedText(textarea) {\n const beforeSelection = textarea.value.slice(0, textarea.selectionStart);\n const afterSelection = textarea.value.slice(textarea.selectionEnd);\n const breaksBefore = beforeSelection.match(/\\n*$/);\n const breaksAfter = afterSelection.match(/^\\n*/);\n const newlinesBeforeSelection = breaksBefore ? breaksBefore[0].length : 0;\n const newlinesAfterSelection = breaksAfter ? breaksAfter[0].length : 0;\n let newlinesToAppend;\n let newlinesToPrepend;\n if (beforeSelection.match(/\\S/) && newlinesBeforeSelection < 2) {\n newlinesToAppend = repeat(\"\\n\", 2 - newlinesBeforeSelection);\n }\n if (afterSelection.match(/\\S/) && newlinesAfterSelection < 2) {\n newlinesToPrepend = repeat(\"\\n\", 2 - newlinesAfterSelection);\n }\n if (newlinesToAppend == null) {\n newlinesToAppend = \"\";\n }\n if (newlinesToPrepend == null) {\n newlinesToPrepend = \"\";\n }\n return { newlinesToAppend, newlinesToPrepend };\n}\nfunction blockStyle(textarea, arg) {\n let newlinesToAppend;\n let newlinesToPrepend;\n const { prefix, suffix, blockPrefix, blockSuffix, replaceNext, prefixSpace, scanFor, surroundWithNewlines } = arg;\n const originalSelectionStart = textarea.selectionStart;\n const originalSelectionEnd = textarea.selectionEnd;\n let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);\n let prefixToUse = isMultipleLines(selectedText) && blockPrefix.length > 0 ? `${blockPrefix}\n` : prefix;\n let suffixToUse = isMultipleLines(selectedText) && blockSuffix.length > 0 ? `\n${blockSuffix}` : suffix;\n if (prefixSpace) {\n const beforeSelection = textarea.value[textarea.selectionStart - 1];\n if (textarea.selectionStart !== 0 && beforeSelection != null && !beforeSelection.match(/\\s/)) {\n prefixToUse = ` ${prefixToUse}`;\n }\n }\n selectedText = expandSelectedText(textarea, prefixToUse, suffixToUse, arg.multiline);\n let selectionStart = textarea.selectionStart;\n let selectionEnd = textarea.selectionEnd;\n const hasReplaceNext = replaceNext.length > 0 && suffixToUse.indexOf(replaceNext) > -1 && selectedText.length > 0;\n if (surroundWithNewlines) {\n const ref = newlinesToSurroundSelectedText(textarea);\n newlinesToAppend = ref.newlinesToAppend;\n newlinesToPrepend = ref.newlinesToPrepend;\n prefixToUse = newlinesToAppend + prefix;\n suffixToUse += newlinesToPrepend;\n }\n if (selectedText.startsWith(prefixToUse) && selectedText.endsWith(suffixToUse)) {\n const replacementText = selectedText.slice(prefixToUse.length, selectedText.length - suffixToUse.length);\n if (originalSelectionStart === originalSelectionEnd) {\n let position = originalSelectionStart - prefixToUse.length;\n position = Math.max(position, selectionStart);\n position = Math.min(position, selectionStart + replacementText.length);\n selectionStart = selectionEnd = position;\n } else {\n selectionEnd = selectionStart + replacementText.length;\n }\n return { text: replacementText, selectionStart, selectionEnd };\n } else if (!hasReplaceNext) {\n let replacementText = prefixToUse + selectedText + suffixToUse;\n selectionStart = originalSelectionStart + prefixToUse.length;\n selectionEnd = originalSelectionEnd + prefixToUse.length;\n const whitespaceEdges = selectedText.match(/^\\s*|\\s*$/g);\n if (arg.trimFirst && whitespaceEdges) {\n const leadingWhitespace = whitespaceEdges[0] || \"\";\n const trailingWhitespace = whitespaceEdges[1] || \"\";\n replacementText = leadingWhitespace + prefixToUse + selectedText.trim() + suffixToUse + trailingWhitespace;\n selectionStart += leadingWhitespace.length;\n selectionEnd -= trailingWhitespace.length;\n }\n return { text: replacementText, selectionStart, selectionEnd };\n } else if (scanFor.length > 0 && selectedText.match(scanFor)) {\n suffixToUse = suffixToUse.replace(replaceNext, selectedText);\n const replacementText = prefixToUse + suffixToUse;\n selectionStart = selectionEnd = selectionStart + prefixToUse.length;\n return { text: replacementText, selectionStart, selectionEnd };\n } else {\n const replacementText = prefixToUse + selectedText + suffixToUse;\n selectionStart = selectionStart + prefixToUse.length + selectedText.length + suffixToUse.indexOf(replaceNext);\n selectionEnd = selectionStart + replaceNext.length;\n return { text: replacementText, selectionStart, selectionEnd };\n }\n}\nfunction multilineStyle(textarea, arg) {\n const { prefix, suffix, surroundWithNewlines } = arg;\n let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);\n let selectionStart = textarea.selectionStart;\n let selectionEnd = textarea.selectionEnd;\n const lines = text.split(\"\\n\");\n const undoStyle = lines.every((line) => line.startsWith(prefix) && line.endsWith(suffix));\n if (undoStyle) {\n text = lines.map((line) => line.slice(prefix.length, line.length - suffix.length)).join(\"\\n\");\n selectionEnd = selectionStart + text.length;\n } else {\n text = lines.map((line) => prefix + line + suffix).join(\"\\n\");\n if (surroundWithNewlines) {\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea);\n selectionStart += newlinesToAppend.length;\n selectionEnd = selectionStart + text.length;\n text = newlinesToAppend + text + newlinesToPrepend;\n }\n }\n return { text, selectionStart, selectionEnd };\n}\nfunction undoOrderedListStyle(text) {\n const lines = text.split(\"\\n\");\n const orderedListRegex = /^\\d+\\.\\s+/;\n const shouldUndoOrderedList = lines.every((line) => orderedListRegex.test(line));\n let result = lines;\n if (shouldUndoOrderedList) {\n result = lines.map((line) => line.replace(orderedListRegex, \"\"));\n }\n return {\n text: result.join(\"\\n\"),\n processed: shouldUndoOrderedList\n };\n}\nfunction undoUnorderedListStyle(text) {\n const lines = text.split(\"\\n\");\n const unorderedListPrefix = \"- \";\n const shouldUndoUnorderedList = lines.every((line) => line.startsWith(unorderedListPrefix));\n let result = lines;\n if (shouldUndoUnorderedList) {\n result = lines.map((line) => line.slice(unorderedListPrefix.length, line.length));\n }\n return {\n text: result.join(\"\\n\"),\n processed: shouldUndoUnorderedList\n };\n}\nfunction makePrefix(index, unorderedList) {\n if (unorderedList) {\n return \"- \";\n } else {\n return `${index + 1}. `;\n }\n}\nfunction clearExistingListStyle(style, selectedText) {\n let undoResultOpositeList;\n let undoResult;\n let pristineText;\n if (style.orderedList) {\n undoResult = undoOrderedListStyle(selectedText);\n undoResultOpositeList = undoUnorderedListStyle(undoResult.text);\n pristineText = undoResultOpositeList.text;\n } else {\n undoResult = undoUnorderedListStyle(selectedText);\n undoResultOpositeList = undoOrderedListStyle(undoResult.text);\n pristineText = undoResultOpositeList.text;\n }\n return [undoResult, undoResultOpositeList, pristineText];\n}\nfunction listStyle(textarea, style) {\n const noInitialSelection = textarea.selectionStart === textarea.selectionEnd;\n let selectionStart = textarea.selectionStart;\n let selectionEnd = textarea.selectionEnd;\n expandSelectionToLine(textarea);\n const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);\n const [undoResult, undoResultOpositeList, pristineText] = clearExistingListStyle(style, selectedText);\n const prefixedLines = pristineText.split(\"\\n\").map((value, index) => {\n return `${makePrefix(index, style.unorderedList)}${value}`;\n });\n const totalPrefixLength = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, style.unorderedList).length;\n }, 0);\n const totalPrefixLengthOpositeList = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {\n return previousValue + makePrefix(currentIndex, !style.unorderedList).length;\n }, 0);\n if (undoResult.processed) {\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart - makePrefix(0, style.unorderedList).length, 0);\n selectionEnd = selectionStart;\n } else {\n selectionStart = textarea.selectionStart;\n selectionEnd = textarea.selectionEnd - totalPrefixLength;\n }\n return { text: pristineText, selectionStart, selectionEnd };\n }\n const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea);\n const text = newlinesToAppend + prefixedLines.join(\"\\n\") + newlinesToPrepend;\n if (noInitialSelection) {\n selectionStart = Math.max(selectionStart + makePrefix(0, style.unorderedList).length + newlinesToAppend.length, 0);\n selectionEnd = selectionStart;\n } else {\n if (undoResultOpositeList.processed) {\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0);\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOpositeList;\n } else {\n selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0);\n selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength;\n }\n }\n return { text, selectionStart, selectionEnd };\n}\nfunction applyStyle(button, stylesToApply) {\n const toolbar = button.closest(\"markdown-toolbar\");\n if (!(toolbar instanceof MarkdownToolbarElement))\n return;\n const defaults = {\n prefix: \"\",\n suffix: \"\",\n blockPrefix: \"\",\n blockSuffix: \"\",\n multiline: false,\n replaceNext: \"\",\n prefixSpace: false,\n scanFor: \"\",\n surroundWithNewlines: false,\n orderedList: false,\n unorderedList: false,\n trimFirst: false\n };\n const style = Object.assign(Object.assign({}, defaults), stylesToApply);\n const field = toolbar.field;\n if (field) {\n field.focus();\n styleSelectedText(field, style);\n }\n}\nvar __classPrivateFieldSet$1 = globalThis && globalThis.__classPrivateFieldSet || function(receiver, state, value, kind, f) {\n if (kind === \"m\")\n throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f)\n throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver))\n throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;\n};\nvar __classPrivateFieldGet$1 = globalThis && globalThis.__classPrivateFieldGet || function(receiver, state, kind, f) {\n if (kind === \"a\" && !f)\n throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver))\n throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n};\nvar _DurationFormat_options;\nclass ListFormatPonyFill {\n formatToParts(members) {\n const parts = [];\n for (const value of members) {\n parts.push({ type: \"element\", value });\n parts.push({ type: \"literal\", value: \", \" });\n }\n return parts.slice(0, -1);\n }\n}\nconst ListFormat = typeof Intl !== \"undefined\" && Intl.ListFormat || ListFormatPonyFill;\nconst partsTable = [\n [\"years\", \"year\"],\n [\"months\", \"month\"],\n [\"weeks\", \"week\"],\n [\"days\", \"day\"],\n [\"hours\", \"hour\"],\n [\"minutes\", \"minute\"],\n [\"seconds\", \"second\"],\n [\"milliseconds\", \"millisecond\"]\n];\nconst twoDigitFormatOptions = { minimumIntegerDigits: 2 };\nclass DurationFormat {\n constructor(locale, options = {}) {\n _DurationFormat_options.set(this, void 0);\n let style = String(options.style || \"short\");\n if (style !== \"long\" && style !== \"short\" && style !== \"narrow\" && style !== \"digital\")\n style = \"short\";\n let prevStyle = style === \"digital\" ? \"numeric\" : style;\n const hours = options.hours || prevStyle;\n prevStyle = hours === \"2-digit\" ? \"numeric\" : hours;\n const minutes = options.minutes || prevStyle;\n prevStyle = minutes === \"2-digit\" ? \"numeric\" : minutes;\n const seconds = options.seconds || prevStyle;\n prevStyle = seconds === \"2-digit\" ? \"numeric\" : seconds;\n const milliseconds = options.milliseconds || prevStyle;\n __classPrivateFieldSet$1(this, _DurationFormat_options, {\n locale,\n style,\n years: options.years || style === \"digital\" ? \"short\" : style,\n yearsDisplay: options.yearsDisplay === \"always\" ? \"always\" : \"auto\",\n months: options.months || style === \"digital\" ? \"short\" : style,\n monthsDisplay: options.monthsDisplay === \"always\" ? \"always\" : \"auto\",\n weeks: options.weeks || style === \"digital\" ? \"short\" : style,\n weeksDisplay: options.weeksDisplay === \"always\" ? \"always\" : \"auto\",\n days: options.days || style === \"digital\" ? \"short\" : style,\n daysDisplay: options.daysDisplay === \"always\" ? \"always\" : \"auto\",\n hours,\n hoursDisplay: options.hoursDisplay === \"always\" ? \"always\" : style === \"digital\" ? \"always\" : \"auto\",\n minutes,\n minutesDisplay: options.minutesDisplay === \"always\" ? \"always\" : style === \"digital\" ? \"always\" : \"auto\",\n seconds,\n secondsDisplay: options.secondsDisplay === \"always\" ? \"always\" : style === \"digital\" ? \"always\" : \"auto\",\n milliseconds,\n millisecondsDisplay: options.millisecondsDisplay === \"always\" ? \"always\" : \"auto\"\n }, \"f\");\n }\n resolvedOptions() {\n return __classPrivateFieldGet$1(this, _DurationFormat_options, \"f\");\n }\n formatToParts(duration) {\n const list = [];\n const options = __classPrivateFieldGet$1(this, _DurationFormat_options, \"f\");\n const style = options.style;\n const locale = options.locale;\n for (const [unit, nfUnit] of partsTable) {\n const value = duration[unit];\n if (options[`${unit}Display`] === \"auto\" && !value)\n continue;\n const unitStyle = options[unit];\n const nfOpts = unitStyle === \"2-digit\" ? twoDigitFormatOptions : unitStyle === \"numeric\" ? {} : { style: \"unit\", unit: nfUnit, unitDisplay: unitStyle };\n list.push(new Intl.NumberFormat(locale, nfOpts).format(value));\n }\n return new ListFormat(locale, {\n type: \"unit\",\n style: style === \"digital\" ? \"short\" : style\n }).formatToParts(list);\n }\n format(duration) {\n return this.formatToParts(duration).map((p) => p.value).join(\"\");\n }\n}\n_DurationFormat_options = /* @__PURE__ */ new WeakMap();\nconst durationRe = /^[-+]?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?$/;\nconst unitNames = [\"year\", \"month\", \"week\", \"day\", \"hour\", \"minute\", \"second\", \"millisecond\"];\nconst isDuration = (str) => durationRe.test(str);\nclass Duration {\n constructor(years = 0, months = 0, weeks = 0, days = 0, hours = 0, minutes = 0, seconds = 0, milliseconds = 0) {\n this.years = years;\n this.months = months;\n this.weeks = weeks;\n this.days = days;\n this.hours = hours;\n this.minutes = minutes;\n this.seconds = seconds;\n this.milliseconds = milliseconds;\n this.years || (this.years = 0);\n this.sign || (this.sign = Math.sign(this.years));\n this.months || (this.months = 0);\n this.sign || (this.sign = Math.sign(this.months));\n this.weeks || (this.weeks = 0);\n this.sign || (this.sign = Math.sign(this.weeks));\n this.days || (this.days = 0);\n this.sign || (this.sign = Math.sign(this.days));\n this.hours || (this.hours = 0);\n this.sign || (this.sign = Math.sign(this.hours));\n this.minutes || (this.minutes = 0);\n this.sign || (this.sign = Math.sign(this.minutes));\n this.seconds || (this.seconds = 0);\n this.sign || (this.sign = Math.sign(this.seconds));\n this.milliseconds || (this.milliseconds = 0);\n this.sign || (this.sign = Math.sign(this.milliseconds));\n this.blank = this.sign === 0;\n }\n abs() {\n return new Duration(Math.abs(this.years), Math.abs(this.months), Math.abs(this.weeks), Math.abs(this.days), Math.abs(this.hours), Math.abs(this.minutes), Math.abs(this.seconds), Math.abs(this.milliseconds));\n }\n static from(durationLike) {\n var _a;\n if (typeof durationLike === \"string\") {\n const str = String(durationLike).trim();\n const factor = str.startsWith(\"-\") ? -1 : 1;\n const parsed = (_a = str.match(durationRe)) === null || _a === void 0 ? void 0 : _a.slice(1).map((x) => (Number(x) || 0) * factor);\n if (!parsed)\n return new Duration();\n return new Duration(...parsed);\n } else if (typeof durationLike === \"object\") {\n const { years, months, weeks, days, hours, minutes, seconds, milliseconds } = durationLike;\n return new Duration(years, months, weeks, days, hours, minutes, seconds, milliseconds);\n }\n throw new RangeError(\"invalid duration\");\n }\n static compare(one, two) {\n const now = Date.now();\n const oneApplied = Math.abs(applyDuration(now, Duration.from(one)).getTime() - now);\n const twoApplied = Math.abs(applyDuration(now, Duration.from(two)).getTime() - now);\n return oneApplied > twoApplied ? -1 : oneApplied < twoApplied ? 1 : 0;\n }\n toLocaleString(locale, opts) {\n return new DurationFormat(locale, opts).format(this);\n }\n}\nfunction applyDuration(date, duration) {\n const r = new Date(date);\n r.setFullYear(r.getFullYear() + duration.years);\n r.setMonth(r.getMonth() + duration.months);\n r.setDate(r.getDate() + duration.weeks * 7 + duration.days);\n r.setHours(r.getHours() + duration.hours);\n r.setMinutes(r.getMinutes() + duration.minutes);\n r.setSeconds(r.getSeconds() + duration.seconds);\n return r;\n}\nfunction elapsedTime(date, precision = \"second\", now = Date.now()) {\n const delta = date.getTime() - now;\n if (delta === 0)\n return new Duration();\n const sign = Math.sign(delta);\n const ms = Math.abs(delta);\n const sec = Math.floor(ms / 1e3);\n const min = Math.floor(sec / 60);\n const hr = Math.floor(min / 60);\n const day = Math.floor(hr / 24);\n const month = Math.floor(day / 30);\n const year = Math.floor(month / 12);\n const i = unitNames.indexOf(precision) || unitNames.length;\n return new Duration(i >= 0 ? year * sign : 0, i >= 1 ? (month - year * 12) * sign : 0, 0, i >= 3 ? (day - month * 30) * sign : 0, i >= 4 ? (hr - day * 24) * sign : 0, i >= 5 ? (min - hr * 60) * sign : 0, i >= 6 ? (sec - min * 60) * sign : 0, i >= 7 ? (ms - sec * 1e3) * sign : 0);\n}\nfunction roundToSingleUnit(duration, { relativeTo = Date.now() } = {}) {\n relativeTo = new Date(relativeTo);\n if (duration.blank)\n return duration;\n const sign = duration.sign;\n let years = Math.abs(duration.years);\n let months = Math.abs(duration.months);\n let weeks = Math.abs(duration.weeks);\n let days = Math.abs(duration.days);\n let hours = Math.abs(duration.hours);\n let minutes = Math.abs(duration.minutes);\n let seconds = Math.abs(duration.seconds);\n let milliseconds = Math.abs(duration.milliseconds);\n if (milliseconds >= 900)\n seconds += Math.round(milliseconds / 1e3);\n if (seconds || minutes || hours || days || weeks || months || years) {\n milliseconds = 0;\n }\n if (seconds >= 55)\n minutes += Math.round(seconds / 60);\n if (minutes || hours || days || weeks || months || years)\n seconds = 0;\n if (minutes >= 55)\n hours += Math.round(minutes / 60);\n if (hours || days || weeks || months || years)\n minutes = 0;\n if (days && hours >= 12)\n days += Math.round(hours / 24);\n if (!days && hours >= 21)\n days += Math.round(hours / 24);\n if (days || weeks || months || years)\n hours = 0;\n const currentYear = relativeTo.getFullYear();\n let currentMonth = relativeTo.getMonth();\n const currentDate = relativeTo.getDate();\n if (days >= 27 || years + months && days) {\n relativeTo.setDate(currentDate + days * sign);\n months += Math.abs(relativeTo.getFullYear() >= currentYear ? relativeTo.getMonth() - currentMonth : relativeTo.getMonth() - currentMonth - 12);\n if (months) {\n days = 0;\n }\n currentMonth = relativeTo.getMonth();\n }\n if (days >= 6)\n weeks += Math.round(days / 7);\n if (weeks || months || years)\n days = 0;\n if (weeks >= 4)\n months += Math.round(weeks / 4);\n if (months || years)\n weeks = 0;\n if (months >= 11 || years && months) {\n relativeTo.setMonth(relativeTo.getMonth() + months * sign);\n years += Math.abs(currentYear - relativeTo.getFullYear());\n }\n if (years)\n months = 0;\n return new Duration(years * sign, months * sign, weeks * sign, days * sign, hours * sign, minutes * sign, seconds * sign, milliseconds * sign);\n}\nfunction getRelativeTimeUnit(duration, opts) {\n const rounded = roundToSingleUnit(duration, opts);\n if (rounded.blank)\n return [0, \"second\"];\n for (const unit of unitNames) {\n if (unit === \"millisecond\")\n continue;\n const val = rounded[`${unit}s`];\n if (val)\n return [val, unit];\n }\n return [0, \"second\"];\n}\nvar __classPrivateFieldGet = globalThis && globalThis.__classPrivateFieldGet || function(receiver, state, kind, f) {\n if (kind === \"a\" && !f)\n throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver))\n throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n};\nvar __classPrivateFieldSet = globalThis && globalThis.__classPrivateFieldSet || function(receiver, state, value, kind, f) {\n if (kind === \"m\")\n throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f)\n throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver))\n throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;\n};\nvar _RelativeTimeElement_instances, _RelativeTimeElement_customTitle, _RelativeTimeElement_updating, _RelativeTimeElement_lang_get, _RelativeTimeElement_renderRoot, _RelativeTimeElement_getFormattedTitle, _RelativeTimeElement_resolveFormat, _RelativeTimeElement_getDurationFormat, _RelativeTimeElement_getRelativeFormat, _RelativeTimeElement_getDateTimeFormat, _RelativeTimeElement_onRelativeTimeUpdated;\nconst HTMLElement$1 = globalThis.HTMLElement || null;\nconst emptyDuration = new Duration();\nconst microEmptyDuration = new Duration(0, 0, 0, 0, 0, 1);\nclass RelativeTimeUpdatedEvent extends Event {\n constructor(oldText, newText, oldTitle, newTitle) {\n super(\"relative-time-updated\", { bubbles: true, composed: true });\n this.oldText = oldText;\n this.newText = newText;\n this.oldTitle = oldTitle;\n this.newTitle = newTitle;\n }\n}\nfunction getUnitFactor(el) {\n if (!el.date)\n return Infinity;\n if (el.format === \"duration\" || el.format === \"elapsed\") {\n const precision = el.precision;\n if (precision === \"second\") {\n return 1e3;\n } else if (precision === \"minute\") {\n return 60 * 1e3;\n }\n }\n const ms = Math.abs(Date.now() - el.date.getTime());\n if (ms < 60 * 1e3)\n return 1e3;\n if (ms < 60 * 60 * 1e3)\n return 60 * 1e3;\n return 60 * 60 * 1e3;\n}\nconst dateObserver = new class {\n constructor() {\n this.elements = /* @__PURE__ */ new Set();\n this.time = Infinity;\n this.timer = -1;\n }\n observe(element) {\n if (this.elements.has(element))\n return;\n this.elements.add(element);\n const date = element.date;\n if (date && date.getTime()) {\n const ms = getUnitFactor(element);\n const time = Date.now() + ms;\n if (time < this.time) {\n clearTimeout(this.timer);\n this.timer = setTimeout(() => this.update(), ms);\n this.time = time;\n }\n }\n }\n unobserve(element) {\n if (!this.elements.has(element))\n return;\n this.elements.delete(element);\n }\n update() {\n clearTimeout(this.timer);\n if (!this.elements.size)\n return;\n let nearestDistance = Infinity;\n for (const timeEl of this.elements) {\n nearestDistance = Math.min(nearestDistance, getUnitFactor(timeEl));\n timeEl.update();\n }\n this.time = Math.min(60 * 60 * 1e3, nearestDistance);\n this.timer = setTimeout(() => this.update(), this.time);\n this.time += Date.now();\n }\n}();\nclass RelativeTimeElement extends HTMLElement$1 {\n constructor() {\n super(...arguments);\n _RelativeTimeElement_instances.add(this);\n _RelativeTimeElement_customTitle.set(this, false);\n _RelativeTimeElement_updating.set(this, false);\n _RelativeTimeElement_renderRoot.set(this, this.shadowRoot ? this.shadowRoot : this.attachShadow ? this.attachShadow({ mode: \"open\" }) : this);\n _RelativeTimeElement_onRelativeTimeUpdated.set(this, null);\n }\n static define(tag = \"relative-time\", registry = customElements) {\n registry.define(tag, this);\n return this;\n }\n static get observedAttributes() {\n return [\n \"second\",\n \"minute\",\n \"hour\",\n \"weekday\",\n \"day\",\n \"month\",\n \"year\",\n \"time-zone-name\",\n \"prefix\",\n \"threshold\",\n \"tense\",\n \"precision\",\n \"format\",\n \"format-style\",\n \"datetime\",\n \"lang\",\n \"title\"\n ];\n }\n get onRelativeTimeUpdated() {\n return __classPrivateFieldGet(this, _RelativeTimeElement_onRelativeTimeUpdated, \"f\");\n }\n set onRelativeTimeUpdated(listener) {\n if (__classPrivateFieldGet(this, _RelativeTimeElement_onRelativeTimeUpdated, \"f\")) {\n this.removeEventListener(\"relative-time-updated\", __classPrivateFieldGet(this, _RelativeTimeElement_onRelativeTimeUpdated, \"f\"));\n }\n __classPrivateFieldSet(this, _RelativeTimeElement_onRelativeTimeUpdated, typeof listener === \"object\" || typeof listener === \"function\" ? listener : null, \"f\");\n if (typeof listener === \"function\") {\n this.addEventListener(\"relative-time-updated\", listener);\n }\n }\n get second() {\n const second = this.getAttribute(\"second\");\n if (second === \"numeric\" || second === \"2-digit\")\n return second;\n }\n set second(value) {\n this.setAttribute(\"second\", value || \"\");\n }\n get minute() {\n const minute = this.getAttribute(\"minute\");\n if (minute === \"numeric\" || minute === \"2-digit\")\n return minute;\n }\n set minute(value) {\n this.setAttribute(\"minute\", value || \"\");\n }\n get hour() {\n const hour = this.getAttribute(\"hour\");\n if (hour === \"numeric\" || hour === \"2-digit\")\n return hour;\n }\n set hour(value) {\n this.setAttribute(\"hour\", value || \"\");\n }\n get weekday() {\n const weekday = this.getAttribute(\"weekday\");\n if (weekday === \"long\" || weekday === \"short\" || weekday === \"narrow\") {\n return weekday;\n }\n if (this.format === \"datetime\" && weekday !== \"\")\n return this.formatStyle;\n }\n set weekday(value) {\n this.setAttribute(\"weekday\", value || \"\");\n }\n get day() {\n var _a;\n const day = (_a = this.getAttribute(\"day\")) !== null && _a !== void 0 ? _a : \"numeric\";\n if (day === \"numeric\" || day === \"2-digit\")\n return day;\n }\n set day(value) {\n this.setAttribute(\"day\", value || \"\");\n }\n get month() {\n const format = this.format;\n let month = this.getAttribute(\"month\");\n if (month === \"\")\n return;\n month !== null && month !== void 0 ? month : month = format === \"datetime\" ? this.formatStyle : \"short\";\n if (month === \"numeric\" || month === \"2-digit\" || month === \"short\" || month === \"long\" || month === \"narrow\") {\n return month;\n }\n }\n set month(value) {\n this.setAttribute(\"month\", value || \"\");\n }\n get year() {\n var _a;\n const year = this.getAttribute(\"year\");\n if (year === \"numeric\" || year === \"2-digit\")\n return year;\n if (!this.hasAttribute(\"year\") && (/* @__PURE__ */ new Date()).getUTCFullYear() !== ((_a = this.date) === null || _a === void 0 ? void 0 : _a.getUTCFullYear())) {\n return \"numeric\";\n }\n }\n set year(value) {\n this.setAttribute(\"year\", value || \"\");\n }\n get timeZoneName() {\n const name = this.getAttribute(\"time-zone-name\");\n if (name === \"long\" || name === \"short\" || name === \"shortOffset\" || name === \"longOffset\" || name === \"shortGeneric\" || name === \"longGeneric\") {\n return name;\n }\n }\n set timeZoneName(value) {\n this.setAttribute(\"time-zone-name\", value || \"\");\n }\n get prefix() {\n var _a;\n return (_a = this.getAttribute(\"prefix\")) !== null && _a !== void 0 ? _a : this.format === \"datetime\" ? \"\" : \"on\";\n }\n set prefix(value) {\n this.setAttribute(\"prefix\", value);\n }\n get threshold() {\n const threshold = this.getAttribute(\"threshold\");\n return threshold && isDuration(threshold) ? threshold : \"P30D\";\n }\n set threshold(value) {\n this.setAttribute(\"threshold\", value);\n }\n get tense() {\n const tense = this.getAttribute(\"tense\");\n if (tense === \"past\")\n return \"past\";\n if (tense === \"future\")\n return \"future\";\n return \"auto\";\n }\n set tense(value) {\n this.setAttribute(\"tense\", value);\n }\n get precision() {\n const precision = this.getAttribute(\"precision\");\n if (unitNames.includes(precision))\n return precision;\n if (this.format === \"micro\")\n return \"minute\";\n return \"second\";\n }\n set precision(value) {\n this.setAttribute(\"precision\", value);\n }\n get format() {\n const format = this.getAttribute(\"format\");\n if (format === \"datetime\")\n return \"datetime\";\n if (format === \"relative\")\n return \"relative\";\n if (format === \"duration\")\n return \"duration\";\n if (format === \"micro\")\n return \"micro\";\n if (format === \"elapsed\")\n return \"elapsed\";\n return \"auto\";\n }\n set format(value) {\n this.setAttribute(\"format\", value);\n }\n get formatStyle() {\n const formatStyle = this.getAttribute(\"format-style\");\n if (formatStyle === \"long\")\n return \"long\";\n if (formatStyle === \"short\")\n return \"short\";\n if (formatStyle === \"narrow\")\n return \"narrow\";\n const format = this.format;\n if (format === \"elapsed\" || format === \"micro\")\n return \"narrow\";\n if (format === \"datetime\")\n return \"short\";\n return \"long\";\n }\n set formatStyle(value) {\n this.setAttribute(\"format-style\", value);\n }\n get datetime() {\n return this.getAttribute(\"datetime\") || \"\";\n }\n set datetime(value) {\n this.setAttribute(\"datetime\", value);\n }\n get date() {\n const parsed = Date.parse(this.datetime);\n return Number.isNaN(parsed) ? null : new Date(parsed);\n }\n set date(value) {\n this.datetime = (value === null || value === void 0 ? void 0 : value.toISOString()) || \"\";\n }\n connectedCallback() {\n this.update();\n }\n disconnectedCallback() {\n dateObserver.unobserve(this);\n }\n attributeChangedCallback(attrName, oldValue, newValue) {\n if (oldValue === newValue)\n return;\n if (attrName === \"title\") {\n __classPrivateFieldSet(this, _RelativeTimeElement_customTitle, newValue !== null && (this.date && __classPrivateFieldGet(this, _RelativeTimeElement_instances, \"m\", _RelativeTimeElement_getFormattedTitle).call(this, this.date)) !== newValue, \"f\");\n }\n if (!__classPrivateFieldGet(this, _RelativeTimeElement_updating, \"f\") && !(attrName === \"title\" && __classPrivateFieldGet(this, _RelativeTimeElement_customTitle, \"f\"))) {\n __classPrivateFieldSet(this, _RelativeTimeElement_updating, (async () => {\n await Promise.resolve();\n this.update();\n })(), \"f\");\n }\n }\n update() {\n const oldText = __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, \"f\").textContent || this.textContent || \"\";\n const oldTitle = this.getAttribute(\"title\") || \"\";\n let newTitle = oldTitle;\n const date = this.date;\n if (typeof Intl === \"undefined\" || !Intl.DateTimeFormat || !date) {\n __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, \"f\").textContent = oldText;\n return;\n }\n const now = Date.now();\n if (!__classPrivateFieldGet(this, _RelativeTimeElement_customTitle, \"f\")) {\n newTitle = __classPrivateFieldGet(this, _RelativeTimeElement_instances, \"m\", _RelativeTimeElement_getFormattedTitle).call(this, date) || \"\";\n if (newTitle)\n this.setAttribute(\"title\", newTitle);\n }\n const duration = elapsedTime(date, this.precision, now);\n const format = __classPrivateFieldGet(this, _RelativeTimeElement_instances, \"m\", _RelativeTimeElement_resolveFormat).call(this, duration);\n let newText = oldText;\n if (format === \"duration\") {\n newText = __classPrivateFieldGet(this, _RelativeTimeElement_instances, \"m\", _RelativeTimeElement_getDurationFormat).call(this, duration);\n } else if (format === \"relative\") {\n newText = __classPrivateFieldGet(this, _RelativeTimeElement_instances, \"m\", _RelativeTimeElement_getRelativeFormat).call(this, duration);\n } else {\n newText = __classPrivateFieldGet(this, _RelativeTimeElement_instances, \"m\", _RelativeTimeElement_getDateTimeFormat).call(this, date);\n }\n if (newText) {\n __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, \"f\").textContent = newText;\n } else if (this.shadowRoot === __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, \"f\") && this.textContent) {\n __classPrivateFieldGet(this, _RelativeTimeElement_renderRoot, \"f\").textContent = this.textContent;\n }\n if (newText !== oldText || newTitle !== oldTitle) {\n this.dispatchEvent(new RelativeTimeUpdatedEvent(oldText, newText, oldTitle, newTitle));\n }\n if (format === \"relative\" || format === \"duration\") {\n dateObserver.observe(this);\n } else {\n dateObserver.unobserve(this);\n }\n __classPrivateFieldSet(this, _RelativeTimeElement_updating, false, \"f\");\n }\n}\n_RelativeTimeElement_customTitle = /* @__PURE__ */ new WeakMap(), _RelativeTimeElement_updating = /* @__PURE__ */ new WeakMap(), _RelativeTimeElement_renderRoot = /* @__PURE__ */ new WeakMap(), _RelativeTimeElement_onRelativeTimeUpdated = /* @__PURE__ */ new WeakMap(), _RelativeTimeElement_instances = /* @__PURE__ */ new WeakSet(), _RelativeTimeElement_lang_get = function _RelativeTimeElement_lang_get2() {\n var _a;\n return ((_a = this.closest(\"[lang]\")) === null || _a === void 0 ? void 0 : _a.getAttribute(\"lang\")) || this.ownerDocument.documentElement.getAttribute(\"lang\") || \"default\";\n}, _RelativeTimeElement_getFormattedTitle = function _RelativeTimeElement_getFormattedTitle2(date) {\n return new Intl.DateTimeFormat(__classPrivateFieldGet(this, _RelativeTimeElement_instances, \"a\", _RelativeTimeElement_lang_get), {\n day: \"numeric\",\n month: \"short\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n timeZoneName: \"short\"\n }).format(date);\n}, _RelativeTimeElement_resolveFormat = function _RelativeTimeElement_resolveFormat2(duration) {\n const format = this.format;\n if (format === \"datetime\")\n return \"datetime\";\n if (format === \"duration\")\n return \"duration\";\n if (format === \"elapsed\")\n return \"duration\";\n if (format === \"micro\")\n return \"duration\";\n if ((format === \"auto\" || format === \"relative\") && typeof Intl !== \"undefined\" && Intl.RelativeTimeFormat) {\n const tense = this.tense;\n if (tense === \"past\" || tense === \"future\")\n return \"relative\";\n if (Duration.compare(duration, this.threshold) === 1)\n return \"relative\";\n }\n return \"datetime\";\n}, _RelativeTimeElement_getDurationFormat = function _RelativeTimeElement_getDurationFormat2(duration) {\n const locale = __classPrivateFieldGet(this, _RelativeTimeElement_instances, \"a\", _RelativeTimeElement_lang_get);\n const format = this.format;\n const style = this.formatStyle;\n const tense = this.tense;\n let empty = emptyDuration;\n if (format === \"micro\") {\n duration = roundToSingleUnit(duration);\n empty = microEmptyDuration;\n if (this.tense === \"past\" && duration.sign !== -1 || this.tense === \"future\" && duration.sign !== 1) {\n duration = microEmptyDuration;\n }\n } else if (tense === \"past\" && duration.sign !== -1 || tense === \"future\" && duration.sign !== 1) {\n duration = empty;\n }\n const display = `${this.precision}sDisplay`;\n if (duration.blank) {\n return empty.toLocaleString(locale, { style, [display]: \"always\" });\n }\n return duration.abs().toLocaleString(locale, { style });\n}, _RelativeTimeElement_getRelativeFormat = function _RelativeTimeElement_getRelativeFormat2(duration) {\n const relativeFormat = new Intl.RelativeTimeFormat(__classPrivateFieldGet(this, _RelativeTimeElement_instances, \"a\", _RelativeTimeElement_lang_get), {\n numeric: \"auto\",\n style: this.formatStyle\n });\n const tense = this.tense;\n if (tense === \"future\" && duration.sign !== 1)\n duration = emptyDuration;\n if (tense === \"past\" && duration.sign !== -1)\n duration = emptyDuration;\n const [int, unit] = getRelativeTimeUnit(duration);\n if (unit === \"second\" && int < 10) {\n return relativeFormat.format(0, \"second\");\n }\n return relativeFormat.format(int, unit);\n}, _RelativeTimeElement_getDateTimeFormat = function _RelativeTimeElement_getDateTimeFormat2(date) {\n const formatter = new Intl.DateTimeFormat(__classPrivateFieldGet(this, _RelativeTimeElement_instances, \"a\", _RelativeTimeElement_lang_get), {\n second: this.second,\n minute: this.minute,\n hour: this.hour,\n weekday: this.weekday,\n day: this.day,\n month: this.month,\n year: this.year,\n timeZoneName: this.timeZoneName\n });\n return `${this.prefix} ${formatter.format(date)}`.trim();\n};\nconst root = typeof globalThis !== \"undefined\" ? globalThis : window;\ntry {\n root.RelativeTimeElement = RelativeTimeElement.define();\n} catch (e) {\n if (!(root.DOMException && e instanceof DOMException && e.name === \"NotSupportedError\") && !(e instanceof ReferenceError)) {\n throw e;\n }\n}\nconst ctrlBindings = !!navigator.userAgent.match(/Macintosh/);\nclass Combobox {\n constructor(input, list) {\n this.input = input;\n this.list = list;\n this.isComposing = false;\n if (!list.id) {\n list.id = `combobox-${Math.random().toString().slice(2, 6)}`;\n }\n this.keyboardEventHandler = (event) => keyboardBindings(event, this);\n this.compositionEventHandler = (event) => trackComposition(event, this);\n this.inputHandler = this.clearSelection.bind(this);\n input.setAttribute(\"role\", \"combobox\");\n input.setAttribute(\"aria-controls\", list.id);\n input.setAttribute(\"aria-expanded\", \"false\");\n input.setAttribute(\"aria-autocomplete\", \"list\");\n input.setAttribute(\"aria-haspopup\", \"listbox\");\n }\n destroy() {\n this.clearSelection();\n this.stop();\n this.input.removeAttribute(\"role\");\n this.input.removeAttribute(\"aria-controls\");\n this.input.removeAttribute(\"aria-expanded\");\n this.input.removeAttribute(\"aria-autocomplete\");\n this.input.removeAttribute(\"aria-haspopup\");\n }\n start() {\n this.input.setAttribute(\"aria-expanded\", \"true\");\n this.input.addEventListener(\"compositionstart\", this.compositionEventHandler);\n this.input.addEventListener(\"compositionend\", this.compositionEventHandler);\n this.input.addEventListener(\"input\", this.inputHandler);\n this.input.addEventListener(\"keydown\", this.keyboardEventHandler);\n this.list.addEventListener(\"click\", commitWithElement);\n }\n stop() {\n this.clearSelection();\n this.input.setAttribute(\"aria-expanded\", \"false\");\n this.input.removeEventListener(\"compositionstart\", this.compositionEventHandler);\n this.input.removeEventListener(\"compositionend\", this.compositionEventHandler);\n this.input.removeEventListener(\"input\", this.inputHandler);\n this.input.removeEventListener(\"keydown\", this.keyboardEventHandler);\n this.list.removeEventListener(\"click\", commitWithElement);\n }\n navigate(indexDiff = 1) {\n const focusEl = Array.from(this.list.querySelectorAll('[aria-selected=\"true\"]')).filter(visible)[0];\n const els = Array.from(this.list.querySelectorAll('[role=\"option\"]')).filter(visible);\n const focusIndex = els.indexOf(focusEl);\n if (focusIndex === els.length - 1 && indexDiff === 1 || focusIndex === 0 && indexDiff === -1) {\n this.clearSelection();\n this.input.focus();\n return;\n }\n let indexOfItem = indexDiff === 1 ? 0 : els.length - 1;\n if (focusEl && focusIndex >= 0) {\n const newIndex = focusIndex + indexDiff;\n if (newIndex >= 0 && newIndex < els.length)\n indexOfItem = newIndex;\n }\n const target = els[indexOfItem];\n if (!target)\n return;\n for (const el of els) {\n if (target === el) {\n this.input.setAttribute(\"aria-activedescendant\", target.id);\n target.setAttribute(\"aria-selected\", \"true\");\n scrollTo(this.list, target);\n } else {\n el.setAttribute(\"aria-selected\", \"false\");\n }\n }\n }\n clearSelection() {\n this.input.removeAttribute(\"aria-activedescendant\");\n for (const el of this.list.querySelectorAll('[aria-selected=\"true\"]')) {\n el.setAttribute(\"aria-selected\", \"false\");\n }\n }\n}\nfunction keyboardBindings(event, combobox) {\n if (event.shiftKey || event.metaKey || event.altKey)\n return;\n if (!ctrlBindings && event.ctrlKey)\n return;\n if (combobox.isComposing)\n return;\n switch (event.key) {\n case \"Enter\":\n case \"Tab\":\n if (commit(combobox.input, combobox.list)) {\n event.preventDefault();\n }\n break;\n case \"Escape\":\n combobox.clearSelection();\n break;\n case \"ArrowDown\":\n combobox.navigate(1);\n event.preventDefault();\n break;\n case \"ArrowUp\":\n combobox.navigate(-1);\n event.preventDefault();\n break;\n case \"n\":\n if (ctrlBindings && event.ctrlKey) {\n combobox.navigate(1);\n event.preventDefault();\n }\n break;\n case \"p\":\n if (ctrlBindings && event.ctrlKey) {\n combobox.navigate(-1);\n event.preventDefault();\n }\n break;\n default:\n if (event.ctrlKey)\n break;\n combobox.clearSelection();\n }\n}\nfunction commitWithElement(event) {\n if (!(event.target instanceof Element))\n return;\n const target = event.target.closest('[role=\"option\"]');\n if (!target)\n return;\n if (target.getAttribute(\"aria-disabled\") === \"true\")\n return;\n fireCommitEvent(target);\n}\nfunction commit(input, list) {\n const target = list.querySelector('[aria-selected=\"true\"]');\n if (!target)\n return false;\n if (target.getAttribute(\"aria-disabled\") === \"true\")\n return true;\n target.click();\n return true;\n}\nfunction fireCommitEvent(target) {\n target.dispatchEvent(new CustomEvent(\"combobox-commit\", { bubbles: true }));\n}\nfunction visible(el) {\n return !el.hidden && !(el instanceof HTMLInputElement && el.type === \"hidden\") && (el.offsetWidth > 0 || el.offsetHeight > 0);\n}\nfunction trackComposition(event, combobox) {\n combobox.isComposing = event.type === \"compositionstart\";\n const list = document.getElementById(combobox.input.getAttribute(\"aria-controls\") || \"\");\n if (!list)\n return;\n combobox.clearSelection();\n}\nfunction scrollTo(container, target) {\n if (!inViewport(container, target)) {\n container.scrollTop = target.offsetTop;\n }\n}\nfunction inViewport(container, element) {\n const scrollTop = container.scrollTop;\n const containerBottom = scrollTop + container.clientHeight;\n const top = element.offsetTop;\n const bottom = top + element.clientHeight;\n return top >= scrollTop && bottom <= containerBottom;\n}\nconst boundary = /\\s|\\(|\\[/;\nfunction query(text, key, cursor, { multiWord, lookBackIndex, lastMatchPosition } = {\n multiWord: false,\n lookBackIndex: 0,\n lastMatchPosition: null\n}) {\n let keyIndex = text.lastIndexOf(key, cursor - 1);\n if (keyIndex === -1)\n return;\n if (keyIndex < lookBackIndex)\n return;\n if (multiWord) {\n if (lastMatchPosition != null) {\n if (lastMatchPosition === keyIndex)\n return;\n keyIndex = lastMatchPosition - key.length;\n }\n const charAfterKey = text[keyIndex + 1];\n if (charAfterKey === \" \" && cursor >= keyIndex + key.length + 1)\n return;\n const newLineIndex = text.lastIndexOf(\"\\n\", cursor - 1);\n if (newLineIndex > keyIndex)\n return;\n const dotIndex = text.lastIndexOf(\".\", cursor - 1);\n if (dotIndex > keyIndex)\n return;\n } else {\n const spaceIndex = text.lastIndexOf(\" \", cursor - 1);\n if (spaceIndex > keyIndex)\n return;\n }\n const pre = text[keyIndex - 1];\n if (pre && !boundary.test(pre))\n return;\n const queryString = text.substring(keyIndex + key.length, cursor);\n return {\n text: queryString,\n position: keyIndex + key.length\n };\n}\nconst properties = [\"position:absolute;\", \"overflow:auto;\", \"word-wrap:break-word;\", \"top:0px;\", \"left:-9999px;\"];\nconst propertyNamesToCopy = [\n \"box-sizing\",\n \"font-family\",\n \"font-size\",\n \"font-style\",\n \"font-variant\",\n \"font-weight\",\n \"height\",\n \"letter-spacing\",\n \"line-height\",\n \"max-height\",\n \"min-height\",\n \"padding-bottom\",\n \"padding-left\",\n \"padding-right\",\n \"padding-top\",\n \"border-bottom\",\n \"border-left\",\n \"border-right\",\n \"border-top\",\n \"text-decoration\",\n \"text-indent\",\n \"text-transform\",\n \"width\",\n \"word-spacing\"\n];\nconst mirrorMap = /* @__PURE__ */ new WeakMap();\nfunction textFieldMirror(textField, markerPosition) {\n const nodeName = textField.nodeName.toLowerCase();\n if (nodeName !== \"textarea\" && nodeName !== \"input\") {\n throw new Error(\"expected textField to a textarea or input\");\n }\n let mirror = mirrorMap.get(textField);\n if (mirror && mirror.parentElement === textField.parentElement) {\n mirror.innerHTML = \"\";\n } else {\n mirror = document.createElement(\"div\");\n mirrorMap.set(textField, mirror);\n const style = window.getComputedStyle(textField);\n const props = properties.slice(0);\n if (nodeName === \"textarea\") {\n props.push(\"white-space:pre-wrap;\");\n } else {\n props.push(\"white-space:nowrap;\");\n }\n for (let i = 0, len = propertyNamesToCopy.length; i < len; i++) {\n const name = propertyNamesToCopy[i];\n props.push(`${name}:${style.getPropertyValue(name)};`);\n }\n mirror.style.cssText = props.join(\" \");\n }\n const marker = document.createElement(\"span\");\n marker.style.cssText = \"position: absolute;\";\n marker.innerHTML = \" \";\n let before;\n let after;\n if (typeof markerPosition === \"number\") {\n let text = textField.value.substring(0, markerPosition);\n if (text) {\n before = document.createTextNode(text);\n }\n text = textField.value.substring(markerPosition);\n if (text) {\n after = document.createTextNode(text);\n }\n } else {\n const text = textField.value;\n if (text) {\n before = document.createTextNode(text);\n }\n }\n if (before) {\n mirror.appendChild(before);\n }\n mirror.appendChild(marker);\n if (after) {\n mirror.appendChild(after);\n }\n if (!mirror.parentElement) {\n if (!textField.parentElement) {\n throw new Error(\"textField must have a parentElement to mirror\");\n }\n textField.parentElement.insertBefore(mirror, textField);\n }\n mirror.scrollTop = textField.scrollTop;\n mirror.scrollLeft = textField.scrollLeft;\n return { mirror, marker };\n}\nfunction textFieldSelectionPosition(field, index = field.selectionEnd) {\n const { mirror, marker } = textFieldMirror(field, index);\n const mirrorRect = mirror.getBoundingClientRect();\n const markerRect = marker.getBoundingClientRect();\n setTimeout(() => {\n mirror.remove();\n }, 5e3);\n return {\n top: markerRect.top - mirrorRect.top,\n left: markerRect.left - mirrorRect.left\n };\n}\nconst states = /* @__PURE__ */ new WeakMap();\nclass TextExpander {\n constructor(expander, input) {\n this.expander = expander;\n this.input = input;\n this.combobox = null;\n this.menu = null;\n this.match = null;\n this.justPasted = false;\n this.lookBackIndex = 0;\n this.oninput = this.onInput.bind(this);\n this.onpaste = this.onPaste.bind(this);\n this.onkeydown = this.onKeydown.bind(this);\n this.oncommit = this.onCommit.bind(this);\n this.onmousedown = this.onMousedown.bind(this);\n this.onblur = this.onBlur.bind(this);\n this.interactingWithList = false;\n input.addEventListener(\"paste\", this.onpaste);\n input.addEventListener(\"input\", this.oninput);\n input.addEventListener(\"keydown\", this.onkeydown);\n input.addEventListener(\"blur\", this.onblur);\n }\n destroy() {\n this.input.removeEventListener(\"paste\", this.onpaste);\n this.input.removeEventListener(\"input\", this.oninput);\n this.input.removeEventListener(\"keydown\", this.onkeydown);\n this.input.removeEventListener(\"blur\", this.onblur);\n }\n dismissMenu() {\n if (this.deactivate()) {\n this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex;\n }\n }\n activate(match, menu) {\n var _a, _b;\n if (this.input !== document.activeElement && this.input !== ((_b = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.activeElement)) {\n return;\n }\n this.deactivate();\n this.menu = menu;\n if (!menu.id)\n menu.id = `text-expander-${Math.floor(Math.random() * 1e5).toString()}`;\n this.expander.append(menu);\n this.combobox = new Combobox(this.input, menu);\n const { top, left } = textFieldSelectionPosition(this.input, match.position);\n menu.style.top = `${top}px`;\n menu.style.left = `${left}px`;\n this.combobox.start();\n menu.addEventListener(\"combobox-commit\", this.oncommit);\n menu.addEventListener(\"mousedown\", this.onmousedown);\n this.combobox.navigate(1);\n }\n deactivate() {\n const menu = this.menu;\n if (!menu || !this.combobox)\n return false;\n this.menu = null;\n menu.removeEventListener(\"combobox-commit\", this.oncommit);\n menu.removeEventListener(\"mousedown\", this.onmousedown);\n this.combobox.destroy();\n this.combobox = null;\n menu.remove();\n return true;\n }\n onCommit({ target }) {\n var _a;\n const item = target;\n if (!(item instanceof HTMLElement))\n return;\n if (!this.combobox)\n return;\n const match = this.match;\n if (!match)\n return;\n const beginning = this.input.value.substring(0, match.position - match.key.length);\n const remaining = this.input.value.substring(match.position + match.text.length);\n const detail = { item, key: match.key, value: null, continue: false };\n const canceled = !this.expander.dispatchEvent(new CustomEvent(\"text-expander-value\", { cancelable: true, detail }));\n if (canceled)\n return;\n if (!detail.value)\n return;\n let suffix = (_a = this.expander.getAttribute(\"suffix\")) !== null && _a !== void 0 ? _a : \" \";\n if (detail.continue) {\n suffix = \"\";\n }\n const value = `${detail.value}${suffix}`;\n this.input.value = beginning + value + remaining;\n const cursor = beginning.length + value.length;\n this.deactivate();\n this.input.focus({\n preventScroll: true\n });\n this.input.selectionStart = cursor;\n this.input.selectionEnd = cursor;\n if (!detail.continue) {\n this.lookBackIndex = cursor;\n this.match = null;\n }\n this.expander.dispatchEvent(new CustomEvent(\"text-expander-committed\", { cancelable: false, detail: { input: this.input } }));\n }\n onBlur() {\n if (this.interactingWithList) {\n this.interactingWithList = false;\n return;\n }\n this.deactivate();\n }\n onPaste() {\n this.justPasted = true;\n }\n async onInput() {\n if (this.justPasted) {\n this.justPasted = false;\n return;\n }\n const match = this.findMatch();\n if (match) {\n this.match = match;\n const menu = await this.notifyProviders(match);\n if (!this.match)\n return;\n if (menu) {\n this.activate(match, menu);\n } else {\n this.deactivate();\n }\n } else {\n this.match = null;\n this.deactivate();\n }\n }\n findMatch() {\n const cursor = this.input.selectionEnd || 0;\n const text = this.input.value;\n if (cursor <= this.lookBackIndex) {\n this.lookBackIndex = cursor - 1;\n }\n for (const { key, multiWord } of this.expander.keys) {\n const found = query(text, key, cursor, {\n multiWord,\n lookBackIndex: this.lookBackIndex,\n lastMatchPosition: this.match ? this.match.position : null\n });\n if (found) {\n return { text: found.text, key, position: found.position };\n }\n }\n }\n async notifyProviders(match) {\n const providers = [];\n const provide = (result) => providers.push(result);\n const canceled = !this.expander.dispatchEvent(new CustomEvent(\"text-expander-change\", { cancelable: true, detail: { provide, text: match.text, key: match.key } }));\n if (canceled)\n return;\n const all = await Promise.all(providers);\n const fragments = all.filter((x) => x.matched).map((x) => x.fragment);\n return fragments[0];\n }\n onMousedown() {\n this.interactingWithList = true;\n }\n onKeydown(event) {\n if (event.key === \"Escape\") {\n this.match = null;\n if (this.deactivate()) {\n this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex;\n event.stopImmediatePropagation();\n event.preventDefault();\n }\n }\n }\n}\nclass TextExpanderElement extends HTMLElement {\n get keys() {\n const keysAttr = this.getAttribute(\"keys\");\n const keys = keysAttr ? keysAttr.split(\" \") : [];\n const multiWordAttr = this.getAttribute(\"multiword\");\n const multiWord = multiWordAttr ? multiWordAttr.split(\" \") : [];\n const globalMultiWord = multiWord.length === 0 && this.hasAttribute(\"multiword\");\n return keys.map((key) => ({ key, multiWord: globalMultiWord || multiWord.includes(key) }));\n }\n connectedCallback() {\n const input = this.querySelector('input[type=\"text\"], textarea');\n if (!(input instanceof HTMLInputElement || input instanceof HTMLTextAreaElement))\n return;\n const state = new TextExpander(this, input);\n states.set(this, state);\n }\n disconnectedCallback() {\n const state = states.get(this);\n if (!state)\n return;\n state.destroy();\n states.delete(this);\n }\n dismiss() {\n const state = states.get(this);\n if (!state)\n return;\n state.dismissMenu();\n }\n}\nif (!window.customElements.get(\"text-expander\")) {\n window.TextExpanderElement = TextExpanderElement;\n window.customElements.define(\"text-expander\", TextExpanderElement);\n}\nconst admin = \"\";\n","/**\n* Tom Select v2.3.1\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * MicroEvent - to make any js object an event emitter\n *\n * - pure javascript - server compatible, browser compatible\n * - dont rely on the browser doms\n * - super simple - you get it immediatly, no mistery, no magic involved\n *\n * @author Jerome Etienne (https://github.com/jeromeetienne)\n */\n\n/**\n * Execute callback for each event in space separated list of event names\n *\n */\nfunction forEvents(events, callback) {\n events.split(/\\s+/).forEach(event => {\n callback(event);\n });\n}\nclass MicroEvent {\n constructor() {\n this._events = void 0;\n this._events = {};\n }\n on(events, fct) {\n forEvents(events, event => {\n const event_array = this._events[event] || [];\n event_array.push(fct);\n this._events[event] = event_array;\n });\n }\n off(events, fct) {\n var n = arguments.length;\n if (n === 0) {\n this._events = {};\n return;\n }\n forEvents(events, event => {\n if (n === 1) {\n delete this._events[event];\n return;\n }\n const event_array = this._events[event];\n if (event_array === undefined) return;\n event_array.splice(event_array.indexOf(fct), 1);\n this._events[event] = event_array;\n });\n }\n trigger(events, ...args) {\n var self = this;\n forEvents(events, event => {\n const event_array = self._events[event];\n if (event_array === undefined) return;\n event_array.forEach(fct => {\n fct.apply(self, args);\n });\n });\n }\n}\n\n/**\n * microplugin.js\n * Copyright (c) 2013 Brian Reavis & contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n * @author Brian Reavis \n */\n\nfunction MicroPlugin(Interface) {\n Interface.plugins = {};\n return class extends Interface {\n constructor(...args) {\n super(...args);\n this.plugins = {\n names: [],\n settings: {},\n requested: {},\n loaded: {}\n };\n }\n /**\n * Registers a plugin.\n *\n * @param {function} fn\n */\n static define(name, fn) {\n Interface.plugins[name] = {\n 'name': name,\n 'fn': fn\n };\n }\n\n /**\n * Initializes the listed plugins (with options).\n * Acceptable formats:\n *\n * List (without options):\n * ['a', 'b', 'c']\n *\n * List (with options):\n * [{'name': 'a', options: {}}, {'name': 'b', options: {}}]\n *\n * Hash (with options):\n * {'a': { ... }, 'b': { ... }, 'c': { ... }}\n *\n * @param {array|object} plugins\n */\n initializePlugins(plugins) {\n var key, name;\n const self = this;\n const queue = [];\n if (Array.isArray(plugins)) {\n plugins.forEach(plugin => {\n if (typeof plugin === 'string') {\n queue.push(plugin);\n } else {\n self.plugins.settings[plugin.name] = plugin.options;\n queue.push(plugin.name);\n }\n });\n } else if (plugins) {\n for (key in plugins) {\n if (plugins.hasOwnProperty(key)) {\n self.plugins.settings[key] = plugins[key];\n queue.push(key);\n }\n }\n }\n while (name = queue.shift()) {\n self.require(name);\n }\n }\n loadPlugin(name) {\n var self = this;\n var plugins = self.plugins;\n var plugin = Interface.plugins[name];\n if (!Interface.plugins.hasOwnProperty(name)) {\n throw new Error('Unable to find \"' + name + '\" plugin');\n }\n plugins.requested[name] = true;\n plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);\n plugins.names.push(name);\n }\n\n /**\n * Initializes a plugin.\n *\n */\n require(name) {\n var self = this;\n var plugins = self.plugins;\n if (!self.plugins.loaded.hasOwnProperty(name)) {\n if (plugins.requested[name]) {\n throw new Error('Plugin has circular dependency (\"' + name + '\")');\n }\n self.loadPlugin(name);\n }\n return plugins.loaded[name];\n }\n };\n}\n\n/*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */\n/**\n * Convert array of strings to a regular expression\n *\tex ['ab','a'] => (?:ab|a)\n * \tex ['a','b'] => [ab]\n * @param {string[]} chars\n * @return {string}\n */\nconst arrayToPattern = chars => {\n chars = chars.filter(Boolean);\n\n if (chars.length < 2) {\n return chars[0] || '';\n }\n\n return maxValueLength(chars) == 1 ? '[' + chars.join('') + ']' : '(?:' + chars.join('|') + ')';\n};\n/**\n * @param {string[]} array\n * @return {string}\n */\n\nconst sequencePattern = array => {\n if (!hasDuplicates(array)) {\n return array.join('');\n }\n\n let pattern = '';\n let prev_char_count = 0;\n\n const prev_pattern = () => {\n if (prev_char_count > 1) {\n pattern += '{' + prev_char_count + '}';\n }\n };\n\n array.forEach((char, i) => {\n if (char === array[i - 1]) {\n prev_char_count++;\n return;\n }\n\n prev_pattern();\n pattern += char;\n prev_char_count = 1;\n });\n prev_pattern();\n return pattern;\n};\n/**\n * Convert array of strings to a regular expression\n *\tex ['ab','a'] => (?:ab|a)\n * \tex ['a','b'] => [ab]\n * @param {Set} chars\n * @return {string}\n */\n\nconst setToPattern = chars => {\n let array = toArray(chars);\n return arrayToPattern(array);\n};\n/**\n *\n * https://stackoverflow.com/questions/7376598/in-javascript-how-do-i-check-if-an-array-has-duplicate-values\n * @param {any[]} array\n */\n\nconst hasDuplicates = array => {\n return new Set(array).size !== array.length;\n};\n/**\n * https://stackoverflow.com/questions/63006601/why-does-u-throw-an-invalid-escape-error\n * @param {string} str\n * @return {string}\n */\n\nconst escape_regex = str => {\n return (str + '').replace(/([\\$\\(\\)\\*\\+\\.\\?\\[\\]\\^\\{\\|\\}\\\\])/gu, '\\\\$1');\n};\n/**\n * Return the max length of array values\n * @param {string[]} array\n *\n */\n\nconst maxValueLength = array => {\n return array.reduce((longest, value) => Math.max(longest, unicodeLength(value)), 0);\n};\n/**\n * @param {string} str\n */\n\nconst unicodeLength = str => {\n return toArray(str).length;\n};\n/**\n * @param {any} p\n * @return {any[]}\n */\n\nconst toArray = p => Array.from(p);\n\n/*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */\n/**\n * Get all possible combinations of substrings that add up to the given string\n * https://stackoverflow.com/questions/30169587/find-all-the-combination-of-substrings-that-add-up-to-the-given-string\n * @param {string} input\n * @return {string[][]}\n */\nconst allSubstrings = input => {\n if (input.length === 1) return [[input]];\n /** @type {string[][]} */\n\n let result = [];\n const start = input.substring(1);\n const suba = allSubstrings(start);\n suba.forEach(function (subresult) {\n let tmp = subresult.slice(0);\n tmp[0] = input.charAt(0) + tmp[0];\n result.push(tmp);\n tmp = subresult.slice(0);\n tmp.unshift(input.charAt(0));\n result.push(tmp);\n });\n return result;\n};\n\n/*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */\n\n/**\n * @typedef {{[key:string]:string}} TUnicodeMap\n * @typedef {{[key:string]:Set}} TUnicodeSets\n * @typedef {[[number,number]]} TCodePoints\n * @typedef {{folded:string,composed:string,code_point:number}} TCodePointObj\n * @typedef {{start:number,end:number,length:number,substr:string}} TSequencePart\n */\n/** @type {TCodePoints} */\n\nconst code_points = [[0, 65535]];\nconst accent_pat = '[\\u0300-\\u036F\\u{b7}\\u{2be}\\u{2bc}]';\n/** @type {TUnicodeMap} */\n\nlet unicode_map;\n/** @type {RegExp} */\n\nlet multi_char_reg;\nconst max_char_length = 3;\n/** @type {TUnicodeMap} */\n\nconst latin_convert = {};\n/** @type {TUnicodeMap} */\n\nconst latin_condensed = {\n '/': '⁄∕',\n '0': '߀',\n \"a\": \"ⱥɐɑ\",\n \"aa\": \"ꜳ\",\n \"ae\": \"æǽǣ\",\n \"ao\": \"ꜵ\",\n \"au\": \"ꜷ\",\n \"av\": \"ꜹꜻ\",\n \"ay\": \"ꜽ\",\n \"b\": \"ƀɓƃ\",\n \"c\": \"ꜿƈȼↄ\",\n \"d\": \"đɗɖᴅƌꮷԁɦ\",\n \"e\": \"ɛǝᴇɇ\",\n \"f\": \"ꝼƒ\",\n \"g\": \"ǥɠꞡᵹꝿɢ\",\n \"h\": \"ħⱨⱶɥ\",\n \"i\": \"ɨı\",\n \"j\": \"ɉȷ\",\n \"k\": \"ƙⱪꝁꝃꝅꞣ\",\n \"l\": \"łƚɫⱡꝉꝇꞁɭ\",\n \"m\": \"ɱɯϻ\",\n \"n\": \"ꞥƞɲꞑᴎлԉ\",\n \"o\": \"øǿɔɵꝋꝍᴑ\",\n \"oe\": \"œ\",\n \"oi\": \"ƣ\",\n \"oo\": \"ꝏ\",\n \"ou\": \"ȣ\",\n \"p\": \"ƥᵽꝑꝓꝕρ\",\n \"q\": \"ꝗꝙɋ\",\n \"r\": \"ɍɽꝛꞧꞃ\",\n \"s\": \"ßȿꞩꞅʂ\",\n \"t\": \"ŧƭʈⱦꞇ\",\n \"th\": \"þ\",\n \"tz\": \"ꜩ\",\n \"u\": \"ʉ\",\n \"v\": \"ʋꝟʌ\",\n \"vy\": \"ꝡ\",\n \"w\": \"ⱳ\",\n \"y\": \"ƴɏỿ\",\n \"z\": \"ƶȥɀⱬꝣ\",\n \"hv\": \"ƕ\"\n};\n\nfor (let latin in latin_condensed) {\n let unicode = latin_condensed[latin] || '';\n\n for (let i = 0; i < unicode.length; i++) {\n let char = unicode.substring(i, i + 1);\n latin_convert[char] = latin;\n }\n}\n\nconst convert_pat = new RegExp(Object.keys(latin_convert).join('|') + '|' + accent_pat, 'gu');\n/**\n * Initialize the unicode_map from the give code point ranges\n *\n * @param {TCodePoints=} _code_points\n */\n\nconst initialize = _code_points => {\n if (unicode_map !== undefined) return;\n unicode_map = generateMap(_code_points || code_points);\n};\n/**\n * Helper method for normalize a string\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize\n * @param {string} str\n * @param {string} form\n */\n\nconst normalize = (str, form = 'NFKD') => str.normalize(form);\n/**\n * Remove accents without reordering string\n * calling str.normalize('NFKD') on \\u{594}\\u{595}\\u{596} becomes \\u{596}\\u{594}\\u{595}\n * via https://github.com/krisk/Fuse/issues/133#issuecomment-318692703\n * @param {string} str\n * @return {string}\n */\n\nconst asciifold = str => {\n return toArray(str).reduce(\n /**\n * @param {string} result\n * @param {string} char\n */\n (result, char) => {\n return result + _asciifold(char);\n }, '');\n};\n/**\n * @param {string} str\n * @return {string}\n */\n\nconst _asciifold = str => {\n str = normalize(str).toLowerCase().replace(convert_pat, (\n /** @type {string} */\n char) => {\n return latin_convert[char] || '';\n }); //return str;\n\n return normalize(str, 'NFC');\n};\n/**\n * Generate a list of unicode variants from the list of code points\n * @param {TCodePoints} code_points\n * @yield {TCodePointObj}\n */\n\nfunction* generator(code_points) {\n for (const [code_point_min, code_point_max] of code_points) {\n for (let i = code_point_min; i <= code_point_max; i++) {\n let composed = String.fromCharCode(i);\n let folded = asciifold(composed);\n\n if (folded == composed.toLowerCase()) {\n continue;\n } // skip when folded is a string longer than 3 characters long\n // bc the resulting regex patterns will be long\n // eg:\n // folded صلى الله عليه وسلم length 18 code point 65018\n // folded جل جلاله length 8 code point 65019\n\n\n if (folded.length > max_char_length) {\n continue;\n }\n\n if (folded.length == 0) {\n continue;\n }\n\n yield {\n folded: folded,\n composed: composed,\n code_point: i\n };\n }\n }\n}\n/**\n * Generate a unicode map from the list of code points\n * @param {TCodePoints} code_points\n * @return {TUnicodeSets}\n */\n\nconst generateSets = code_points => {\n /** @type {{[key:string]:Set}} */\n const unicode_sets = {};\n /**\n * @param {string} folded\n * @param {string} to_add\n */\n\n const addMatching = (folded, to_add) => {\n /** @type {Set} */\n const folded_set = unicode_sets[folded] || new Set();\n const patt = new RegExp('^' + setToPattern(folded_set) + '$', 'iu');\n\n if (to_add.match(patt)) {\n return;\n }\n\n folded_set.add(escape_regex(to_add));\n unicode_sets[folded] = folded_set;\n };\n\n for (let value of generator(code_points)) {\n addMatching(value.folded, value.folded);\n addMatching(value.folded, value.composed);\n }\n\n return unicode_sets;\n};\n/**\n * Generate a unicode map from the list of code points\n * ae => (?:(?:ae|Æ|Ǽ|Ǣ)|(?:A|Ⓐ|A...)(?:E|ɛ|Ⓔ...))\n *\n * @param {TCodePoints} code_points\n * @return {TUnicodeMap}\n */\n\nconst generateMap = code_points => {\n /** @type {TUnicodeSets} */\n const unicode_sets = generateSets(code_points);\n /** @type {TUnicodeMap} */\n\n const unicode_map = {};\n /** @type {string[]} */\n\n let multi_char = [];\n\n for (let folded in unicode_sets) {\n let set = unicode_sets[folded];\n\n if (set) {\n unicode_map[folded] = setToPattern(set);\n }\n\n if (folded.length > 1) {\n multi_char.push(escape_regex(folded));\n }\n }\n\n multi_char.sort((a, b) => b.length - a.length);\n const multi_char_patt = arrayToPattern(multi_char);\n multi_char_reg = new RegExp('^' + multi_char_patt, 'u');\n return unicode_map;\n};\n/**\n * Map each element of an array from it's folded value to all possible unicode matches\n * @param {string[]} strings\n * @param {number} min_replacement\n * @return {string}\n */\n\nconst mapSequence = (strings, min_replacement = 1) => {\n let chars_replaced = 0;\n strings = strings.map(str => {\n if (unicode_map[str]) {\n chars_replaced += str.length;\n }\n\n return unicode_map[str] || str;\n });\n\n if (chars_replaced >= min_replacement) {\n return sequencePattern(strings);\n }\n\n return '';\n};\n/**\n * Convert a short string and split it into all possible patterns\n * Keep a pattern only if min_replacement is met\n *\n * 'abc'\n * \t\t=> [['abc'],['ab','c'],['a','bc'],['a','b','c']]\n *\t\t=> ['abc-pattern','ab-c-pattern'...]\n *\n *\n * @param {string} str\n * @param {number} min_replacement\n * @return {string}\n */\n\nconst substringsToPattern = (str, min_replacement = 1) => {\n min_replacement = Math.max(min_replacement, str.length - 1);\n return arrayToPattern(allSubstrings(str).map(sub_pat => {\n return mapSequence(sub_pat, min_replacement);\n }));\n};\n/**\n * Convert an array of sequences into a pattern\n * [{start:0,end:3,length:3,substr:'iii'}...] => (?:iii...)\n *\n * @param {Sequence[]} sequences\n * @param {boolean} all\n */\n\nconst sequencesToPattern = (sequences, all = true) => {\n let min_replacement = sequences.length > 1 ? 1 : 0;\n return arrayToPattern(sequences.map(sequence => {\n let seq = [];\n const len = all ? sequence.length() : sequence.length() - 1;\n\n for (let j = 0; j < len; j++) {\n seq.push(substringsToPattern(sequence.substrs[j] || '', min_replacement));\n }\n\n return sequencePattern(seq);\n }));\n};\n/**\n * Return true if the sequence is already in the sequences\n * @param {Sequence} needle_seq\n * @param {Sequence[]} sequences\n */\n\n\nconst inSequences = (needle_seq, sequences) => {\n for (const seq of sequences) {\n if (seq.start != needle_seq.start || seq.end != needle_seq.end) {\n continue;\n }\n\n if (seq.substrs.join('') !== needle_seq.substrs.join('')) {\n continue;\n }\n\n let needle_parts = needle_seq.parts;\n /**\n * @param {TSequencePart} part\n */\n\n const filter = part => {\n for (const needle_part of needle_parts) {\n if (needle_part.start === part.start && needle_part.substr === part.substr) {\n return false;\n }\n\n if (part.length == 1 || needle_part.length == 1) {\n continue;\n } // check for overlapping parts\n // a = ['::=','==']\n // b = ['::','===']\n // a = ['r','sm']\n // b = ['rs','m']\n\n\n if (part.start < needle_part.start && part.end > needle_part.start) {\n return true;\n }\n\n if (needle_part.start < part.start && needle_part.end > part.start) {\n return true;\n }\n }\n\n return false;\n };\n\n let filtered = seq.parts.filter(filter);\n\n if (filtered.length > 0) {\n continue;\n }\n\n return true;\n }\n\n return false;\n};\n\nclass Sequence {\n constructor() {\n /** @type {TSequencePart[]} */\n this.parts = [];\n /** @type {string[]} */\n\n this.substrs = [];\n this.start = 0;\n this.end = 0;\n }\n /**\n * @param {TSequencePart|undefined} part\n */\n\n\n add(part) {\n if (part) {\n this.parts.push(part);\n this.substrs.push(part.substr);\n this.start = Math.min(part.start, this.start);\n this.end = Math.max(part.end, this.end);\n }\n }\n\n last() {\n return this.parts[this.parts.length - 1];\n }\n\n length() {\n return this.parts.length;\n }\n /**\n * @param {number} position\n * @param {TSequencePart} last_piece\n */\n\n\n clone(position, last_piece) {\n let clone = new Sequence();\n let parts = JSON.parse(JSON.stringify(this.parts));\n let last_part = parts.pop();\n\n for (const part of parts) {\n clone.add(part);\n }\n\n let last_substr = last_piece.substr.substring(0, position - last_part.start);\n let clone_last_len = last_substr.length;\n clone.add({\n start: last_part.start,\n end: last_part.start + clone_last_len,\n length: clone_last_len,\n substr: last_substr\n });\n return clone;\n }\n\n}\n/**\n * Expand a regular expression pattern to include unicode variants\n * \teg /a/ becomes /aⓐaẚàáâầấẫẩãāăằắẵẳȧǡäǟảåǻǎȁȃạậặḁąⱥɐɑAⒶAÀÁÂẦẤẪẨÃĀĂẰẮẴẲȦǠÄǞẢÅǺǍȀȂẠẬẶḀĄȺⱯ/\n *\n * Issue:\n * ﺊﺋ [ 'ﺊ = \\\\u{fe8a}', 'ﺋ = \\\\u{fe8b}' ]\n *\tbecomes:\tئئ [ 'ي = \\\\u{64a}', 'ٔ = \\\\u{654}', 'ي = \\\\u{64a}', 'ٔ = \\\\u{654}' ]\n *\n *\tİIJ = IIJ = ⅡJ\n *\n * \t1/2/4\n *\n * @param {string} str\n * @return {string|undefined}\n */\n\n\nconst getPattern = str => {\n initialize();\n str = asciifold(str);\n let pattern = '';\n let sequences = [new Sequence()];\n\n for (let i = 0; i < str.length; i++) {\n let substr = str.substring(i);\n let match = substr.match(multi_char_reg);\n const char = str.substring(i, i + 1);\n const match_str = match ? match[0] : null; // loop through sequences\n // add either the char or multi_match\n\n let overlapping = [];\n let added_types = new Set();\n\n for (const sequence of sequences) {\n const last_piece = sequence.last();\n\n if (!last_piece || last_piece.length == 1 || last_piece.end <= i) {\n // if we have a multi match\n if (match_str) {\n const len = match_str.length;\n sequence.add({\n start: i,\n end: i + len,\n length: len,\n substr: match_str\n });\n added_types.add('1');\n } else {\n sequence.add({\n start: i,\n end: i + 1,\n length: 1,\n substr: char\n });\n added_types.add('2');\n }\n } else if (match_str) {\n let clone = sequence.clone(i, last_piece);\n const len = match_str.length;\n clone.add({\n start: i,\n end: i + len,\n length: len,\n substr: match_str\n });\n overlapping.push(clone);\n } else {\n // don't add char\n // adding would create invalid patterns: 234 => [2,34,4]\n added_types.add('3');\n }\n } // if we have overlapping\n\n\n if (overlapping.length > 0) {\n // ['ii','iii'] before ['i','i','iii']\n overlapping = overlapping.sort((a, b) => {\n return a.length() - b.length();\n });\n\n for (let clone of overlapping) {\n // don't add if we already have an equivalent sequence\n if (inSequences(clone, sequences)) {\n continue;\n }\n\n sequences.push(clone);\n }\n\n continue;\n } // if we haven't done anything unique\n // clean up the patterns\n // helps keep patterns smaller\n // if str = 'r₨㎧aarss', pattern will be 446 instead of 655\n\n\n if (i > 0 && added_types.size == 1 && !added_types.has('3')) {\n pattern += sequencesToPattern(sequences, false);\n let new_seq = new Sequence();\n const old_seq = sequences[0];\n\n if (old_seq) {\n new_seq.add(old_seq.last());\n }\n\n sequences = [new_seq];\n }\n }\n\n pattern += sequencesToPattern(sequences, true);\n return pattern;\n};\n\n/*! sifter.js | https://github.com/orchidjs/sifter.js | Apache License (v2) */\n\n/**\n * A property getter resolving dot-notation\n * @param {Object} obj The root object to fetch property on\n * @param {String} name The optionally dotted property name to fetch\n * @return {Object} The resolved property value\n */\nconst getAttr = (obj, name) => {\n if (!obj) return;\n return obj[name];\n};\n/**\n * A property getter resolving dot-notation\n * @param {Object} obj The root object to fetch property on\n * @param {String} name The optionally dotted property name to fetch\n * @return {Object} The resolved property value\n */\n\nconst getAttrNesting = (obj, name) => {\n if (!obj) return;\n var part,\n names = name.split(\".\");\n\n while ((part = names.shift()) && (obj = obj[part]));\n\n return obj;\n};\n/**\n * Calculates how close of a match the\n * given value is against a search token.\n *\n */\n\nconst scoreValue = (value, token, weight) => {\n var score, pos;\n if (!value) return 0;\n value = value + '';\n if (token.regex == null) return 0;\n pos = value.search(token.regex);\n if (pos === -1) return 0;\n score = token.string.length / value.length;\n if (pos === 0) score += 0.5;\n return score * weight;\n};\n/**\n * Cast object property to an array if it exists and has a value\n *\n */\n\nconst propToArray = (obj, key) => {\n var value = obj[key];\n if (typeof value == 'function') return value;\n\n if (value && !Array.isArray(value)) {\n obj[key] = [value];\n }\n};\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\n\nconst iterate$1 = (object, callback) => {\n if (Array.isArray(object)) {\n object.forEach(callback);\n } else {\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n callback(object[key], key);\n }\n }\n }\n};\nconst cmp = (a, b) => {\n if (typeof a === 'number' && typeof b === 'number') {\n return a > b ? 1 : a < b ? -1 : 0;\n }\n\n a = asciifold(a + '').toLowerCase();\n b = asciifold(b + '').toLowerCase();\n if (a > b) return 1;\n if (b > a) return -1;\n return 0;\n};\n\n/*! sifter.js | https://github.com/orchidjs/sifter.js | Apache License (v2) */\n\n/**\n * sifter.js\n * Copyright (c) 2013–2020 Brian Reavis & contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n * @author Brian Reavis \n */\n\nclass Sifter {\n // []|{};\n\n /**\n * Textually searches arrays and hashes of objects\n * by property (or multiple properties). Designed\n * specifically for autocomplete.\n *\n */\n constructor(items, settings) {\n this.items = void 0;\n this.settings = void 0;\n this.items = items;\n this.settings = settings || {\n diacritics: true\n };\n }\n\n /**\n * Splits a search string into an array of individual\n * regexps to be used to match results.\n *\n */\n tokenize(query, respect_word_boundaries, weights) {\n if (!query || !query.length) return [];\n const tokens = [];\n const words = query.split(/\\s+/);\n var field_regex;\n\n if (weights) {\n field_regex = new RegExp('^(' + Object.keys(weights).map(escape_regex).join('|') + ')\\:(.*)$');\n }\n\n words.forEach(word => {\n let field_match;\n let field = null;\n let regex = null; // look for \"field:query\" tokens\n\n if (field_regex && (field_match = word.match(field_regex))) {\n field = field_match[1];\n word = field_match[2];\n }\n\n if (word.length > 0) {\n if (this.settings.diacritics) {\n regex = getPattern(word) || null;\n } else {\n regex = escape_regex(word);\n }\n\n if (regex && respect_word_boundaries) regex = \"\\\\b\" + regex;\n }\n\n tokens.push({\n string: word,\n regex: regex ? new RegExp(regex, 'iu') : null,\n field: field\n });\n });\n return tokens;\n }\n\n /**\n * Returns a function to be used to score individual results.\n *\n * Good matches will have a higher score than poor matches.\n * If an item is not a match, 0 will be returned by the function.\n *\n * @returns {T.ScoreFn}\n */\n getScoreFunction(query, options) {\n var search = this.prepareSearch(query, options);\n return this._getScoreFunction(search);\n }\n /**\n * @returns {T.ScoreFn}\n *\n */\n\n\n _getScoreFunction(search) {\n const tokens = search.tokens,\n token_count = tokens.length;\n\n if (!token_count) {\n return function () {\n return 0;\n };\n }\n\n const fields = search.options.fields,\n weights = search.weights,\n field_count = fields.length,\n getAttrFn = search.getAttrFn;\n\n if (!field_count) {\n return function () {\n return 1;\n };\n }\n /**\n * Calculates the score of an object\n * against the search query.\n *\n */\n\n\n const scoreObject = function () {\n if (field_count === 1) {\n return function (token, data) {\n const field = fields[0].field;\n return scoreValue(getAttrFn(data, field), token, weights[field] || 1);\n };\n }\n\n return function (token, data) {\n var sum = 0; // is the token specific to a field?\n\n if (token.field) {\n const value = getAttrFn(data, token.field);\n\n if (!token.regex && value) {\n sum += 1 / field_count;\n } else {\n sum += scoreValue(value, token, 1);\n }\n } else {\n iterate$1(weights, (weight, field) => {\n sum += scoreValue(getAttrFn(data, field), token, weight);\n });\n }\n\n return sum / field_count;\n };\n }();\n\n if (token_count === 1) {\n return function (data) {\n return scoreObject(tokens[0], data);\n };\n }\n\n if (search.options.conjunction === 'and') {\n return function (data) {\n var score,\n sum = 0;\n\n for (let token of tokens) {\n score = scoreObject(token, data);\n if (score <= 0) return 0;\n sum += score;\n }\n\n return sum / token_count;\n };\n } else {\n return function (data) {\n var sum = 0;\n iterate$1(tokens, token => {\n sum += scoreObject(token, data);\n });\n return sum / token_count;\n };\n }\n }\n\n /**\n * Returns a function that can be used to compare two\n * results, for sorting purposes. If no sorting should\n * be performed, `null` will be returned.\n *\n * @return function(a,b)\n */\n getSortFunction(query, options) {\n var search = this.prepareSearch(query, options);\n return this._getSortFunction(search);\n }\n\n _getSortFunction(search) {\n var implicit_score,\n sort_flds = [];\n const self = this,\n options = search.options,\n sort = !search.query && options.sort_empty ? options.sort_empty : options.sort;\n\n if (typeof sort == 'function') {\n return sort.bind(this);\n }\n /**\n * Fetches the specified sort field value\n * from a search result item.\n *\n */\n\n\n const get_field = function get_field(name, result) {\n if (name === '$score') return result.score;\n return search.getAttrFn(self.items[result.id], name);\n }; // parse options\n\n\n if (sort) {\n for (let s of sort) {\n if (search.query || s.field !== '$score') {\n sort_flds.push(s);\n }\n }\n } // the \"$score\" field is implied to be the primary\n // sort field, unless it's manually specified\n\n\n if (search.query) {\n implicit_score = true;\n\n for (let fld of sort_flds) {\n if (fld.field === '$score') {\n implicit_score = false;\n break;\n }\n }\n\n if (implicit_score) {\n sort_flds.unshift({\n field: '$score',\n direction: 'desc'\n });\n } // without a search.query, all items will have the same score\n\n } else {\n sort_flds = sort_flds.filter(fld => fld.field !== '$score');\n } // build function\n\n\n const sort_flds_count = sort_flds.length;\n\n if (!sort_flds_count) {\n return null;\n }\n\n return function (a, b) {\n var result, field;\n\n for (let sort_fld of sort_flds) {\n field = sort_fld.field;\n let multiplier = sort_fld.direction === 'desc' ? -1 : 1;\n result = multiplier * cmp(get_field(field, a), get_field(field, b));\n if (result) return result;\n }\n\n return 0;\n };\n }\n\n /**\n * Parses a search query and returns an object\n * with tokens and fields ready to be populated\n * with results.\n *\n */\n prepareSearch(query, optsUser) {\n const weights = {};\n var options = Object.assign({}, optsUser);\n propToArray(options, 'sort');\n propToArray(options, 'sort_empty'); // convert fields to new format\n\n if (options.fields) {\n propToArray(options, 'fields');\n const fields = [];\n options.fields.forEach(field => {\n if (typeof field == 'string') {\n field = {\n field: field,\n weight: 1\n };\n }\n\n fields.push(field);\n weights[field.field] = 'weight' in field ? field.weight : 1;\n });\n options.fields = fields;\n }\n\n return {\n options: options,\n query: query.toLowerCase().trim(),\n tokens: this.tokenize(query, options.respect_word_boundaries, weights),\n total: 0,\n items: [],\n weights: weights,\n getAttrFn: options.nesting ? getAttrNesting : getAttr\n };\n }\n\n /**\n * Searches through all items and returns a sorted array of matches.\n *\n */\n search(query, options) {\n var self = this,\n score,\n search;\n search = this.prepareSearch(query, options);\n options = search.options;\n query = search.query; // generate result scoring function\n\n const fn_score = options.score || self._getScoreFunction(search); // perform search and sort\n\n\n if (query.length) {\n iterate$1(self.items, (item, id) => {\n score = fn_score(item);\n\n if (options.filter === false || score > 0) {\n search.items.push({\n 'score': score,\n 'id': id\n });\n }\n });\n } else {\n iterate$1(self.items, (_, id) => {\n search.items.push({\n 'score': 1,\n 'id': id\n });\n });\n }\n\n const fn_sort = self._getSortFunction(search);\n\n if (fn_sort) search.items.sort(fn_sort); // apply limits\n\n search.total = search.items.length;\n\n if (typeof options.limit === 'number') {\n search.items = search.items.slice(0, options.limit);\n }\n\n return search;\n }\n\n}\n\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\nconst iterate = (object, callback) => {\n if (Array.isArray(object)) {\n object.forEach(callback);\n } else {\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n callback(object[key], key);\n }\n }\n }\n};\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nconst getDom = query => {\n if (query.jquery) {\n return query[0];\n }\n if (query instanceof HTMLElement) {\n return query;\n }\n if (isHtmlString(query)) {\n var tpl = document.createElement('template');\n tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n return tpl.content.firstChild;\n }\n return document.querySelector(query);\n};\nconst isHtmlString = arg => {\n if (typeof arg === 'string' && arg.indexOf('<') > -1) {\n return true;\n }\n return false;\n};\nconst escapeQuery = query => {\n return query.replace(/['\"\\\\]/g, '\\\\$&');\n};\n\n/**\n * Dispatch an event\n *\n */\nconst triggerEvent = (dom_el, event_name) => {\n var event = document.createEvent('HTMLEvents');\n event.initEvent(event_name, true, false);\n dom_el.dispatchEvent(event);\n};\n\n/**\n * Apply CSS rules to a dom element\n *\n */\nconst applyCSS = (dom_el, css) => {\n Object.assign(dom_el.style, css);\n};\n\n/**\n * Add css classes\n *\n */\nconst addClasses = (elmts, ...classes) => {\n var norm_classes = classesArray(classes);\n elmts = castAsArray(elmts);\n elmts.map(el => {\n norm_classes.map(cls => {\n el.classList.add(cls);\n });\n });\n};\n\n/**\n * Remove css classes\n *\n */\nconst removeClasses = (elmts, ...classes) => {\n var norm_classes = classesArray(classes);\n elmts = castAsArray(elmts);\n elmts.map(el => {\n norm_classes.map(cls => {\n el.classList.remove(cls);\n });\n });\n};\n\n/**\n * Return arguments\n *\n */\nconst classesArray = args => {\n var classes = [];\n iterate(args, _classes => {\n if (typeof _classes === 'string') {\n _classes = _classes.trim().split(/[\\11\\12\\14\\15\\40]/);\n }\n if (Array.isArray(_classes)) {\n classes = classes.concat(_classes);\n }\n });\n return classes.filter(Boolean);\n};\n\n/**\n * Create an array from arg if it's not already an array\n *\n */\nconst castAsArray = arg => {\n if (!Array.isArray(arg)) {\n arg = [arg];\n }\n return arg;\n};\n\n/**\n * Get the closest node to the evt.target matching the selector\n * Stops at wrapper\n *\n */\nconst parentMatch = (target, selector, wrapper) => {\n if (wrapper && !wrapper.contains(target)) {\n return;\n }\n while (target && target.matches) {\n if (target.matches(selector)) {\n return target;\n }\n target = target.parentNode;\n }\n};\n\n/**\n * Get the first or last item from an array\n *\n * > 0 - right (last)\n * <= 0 - left (first)\n *\n */\nconst getTail = (list, direction = 0) => {\n if (direction > 0) {\n return list[list.length - 1];\n }\n return list[0];\n};\n\n/**\n * Return true if an object is empty\n *\n */\nconst isEmptyObject = obj => {\n return Object.keys(obj).length === 0;\n};\n\n/**\n * Get the index of an element amongst sibling nodes of the same type\n *\n */\nconst nodeIndex = (el, amongst) => {\n if (!el) return -1;\n amongst = amongst || el.nodeName;\n var i = 0;\n while (el = el.previousElementSibling) {\n if (el.matches(amongst)) {\n i++;\n }\n }\n return i;\n};\n\n/**\n * Set attributes of an element\n *\n */\nconst setAttr = (el, attrs) => {\n iterate(attrs, (val, attr) => {\n if (val == null) {\n el.removeAttribute(attr);\n } else {\n el.setAttribute(attr, '' + val);\n }\n });\n};\n\n/**\n * Replace a node\n */\nconst replaceNode = (existing, replacement) => {\n if (existing.parentNode) existing.parentNode.replaceChild(replacement, existing);\n};\n\n/**\n * highlight v3 | MIT license | Johann Burkard \n * Highlights arbitrary terms in a node.\n *\n * - Modified by Marshal 2011-6-24 (added regex)\n * - Modified by Brian Reavis 2012-8-27 (cleanup)\n */\n\nconst highlight = (element, regex) => {\n if (regex === null) return;\n\n // convet string to regex\n if (typeof regex === 'string') {\n if (!regex.length) return;\n regex = new RegExp(regex, 'i');\n }\n\n // Wrap matching part of text node with highlighting , e.g.\n // Soccer -> Soccer for regex = /soc/i\n const highlightText = node => {\n var match = node.data.match(regex);\n if (match && node.data.length > 0) {\n var spannode = document.createElement('span');\n spannode.className = 'highlight';\n var middlebit = node.splitText(match.index);\n middlebit.splitText(match[0].length);\n var middleclone = middlebit.cloneNode(true);\n spannode.appendChild(middleclone);\n replaceNode(middlebit, spannode);\n return 1;\n }\n return 0;\n };\n\n // Recurse element node, looking for child text nodes to highlight, unless element\n // is childless,