{"version":3,"file":"facilmap-frontend.mjs","sources":["../../src/lib/utils/search.ts","../../src/lib/utils/vue.ts","../../src/lib/utils/cookies.ts","../../src/lib/utils/i18n.ts","../../src/lib/utils/utils.ts","../../src/lib/utils/link-disabled.ts","../../src/lib/components/ui/toasts/toasts.vue","../../src/lib/utils/bootstrap.ts","../../src/lib/components/facil-map-context-provider/facil-map-context-provider.vue","../../src/lib/utils/add.ts","../../src/lib/utils/box-selection.ts","../../src/lib/utils/carousel.ts","../../src/lib/utils/draw.ts","../../src/lib/utils/files.ts","../../src/lib/utils/heightgraph.ts","../../src/lib/utils/modal.ts","../../src/lib/utils/selection.ts","../../src/lib/utils/storage.ts","../../src/lib/utils/tooltip.ts","../../src/lib/utils/ui.ts","../../src/lib/utils/zoom.ts","../../src/lib/components/edit-type-dialog/edit-type-utils.ts","../../src/lib/components/ui/popover.vue","../../src/lib/components/ui/attribute-preserving-element.vue","../../src/lib/components/ui/hybrid-popover.vue","../../src/lib/components/ui/validated-form/validated-form.vue","../../src/lib/components/ui/validated-form/validated-field.vue","../../src/lib/components/ui/picker.vue","../../src/lib/components/ui/colour-picker.vue","../../src/lib/components/ui/prerendered-list.vue","../../src/lib/components/ui/shape-picker.vue","../../src/lib/components/ui/icon.vue","../../src/lib/components/ui/symbol-picker.vue","../../src/lib/components/ui/dropdown-menu.vue","../../src/lib/components/ui/route-mode.vue","../../src/lib/components/ui/field-input.vue","../../src/lib/components/ui/width-picker.vue","../../src/lib/components/ui/size-picker.vue","../../src/lib/components/ui/modal-dialog.vue","../../src/lib/components/ui/alert.vue","../../src/lib/components/ui/stroke-picker.vue","../../src/lib/components/edit-type-dialog/edit-type-dropdown-dialog.vue","../../src/lib/components/edit-type-dialog/edit-type-dialog.vue","../../src/lib/components/history-dialog/history-utils.ts","../../src/lib/components/history-dialog/history-dialog.vue","../../src/lib/components/leaflet-map/attribution.ts","../../src/lib/components/leaflet-map/leaflet-map-components.ts","../../src/lib/components/leaflet-map/logo.png","../../src/lib/components/leaflet-map/leaflet-map.vue","../../src/lib/components/legend/legend-content.vue","../../src/lib/components/legend/legend-utils.ts","../../src/lib/components/search-box/search-box-tab.vue","../../src/lib/components/legend/legend.vue","../../src/lib/components/edit-line-dialog.vue","../../src/lib/components/ui/elevation-stats.vue","../../src/lib/components/ui/elevation-plot.vue","../../src/lib/components/ui/zoom-to-object-button.vue","../../src/lib/components/ui/add-to-map-dropdown.vue","../../src/lib/components/ui/export-dropdown.vue","../../src/lib/components/route-form/route-form.vue","../../src/lib/components/line-info/line-info.vue","../../src/lib/components/line-info/line-info-tab.vue","../../src/lib/components/edit-marker-dialog.vue","../../src/lib/components/ui/coordinates.vue","../../src/lib/components/ui/use-as-dropdown.vue","../../src/lib/components/marker-info/marker-info.vue","../../src/lib/components/marker-info/marker-info-tab.vue","../../src/lib/components/multiple-info/multiple-info.vue","../../src/lib/components/multiple-info/multiple-info-tab.vue","../../src/lib/components/overpass-form/overpass-form.vue","../../src/lib/components/overpass-form/overpass-form-tab.vue","../../src/lib/components/ui/copy-to-clipboard-input.vue","../../src/lib/components/pad-settings-dialog/pad-id-edit.vue","../../src/lib/components/pad-settings-dialog/pad-settings-dialog.vue","../../src/lib/components/route-form/route-form-tab.vue","../../src/lib/components/search-box/search-box.vue","../../src/lib/components/search-result-info.vue","../../src/lib/components/search-results/custom-import-dialog.vue","../../src/lib/components/search-results/search-results.vue","../../src/lib/components/file-results.vue","../../src/lib/components/search-form/search-form.vue","../../src/lib/components/search-form/search-form-tab.vue","../../src/lib/components/manage-types-dialog.vue","../../src/lib/components/toolbox/toolbox-add-dropdown.vue","../../src/lib/components/manage-bookmarks-dialog.vue","../../src/lib/components/ui/pagination.vue","../../src/lib/components/open-map-dialog.vue","../../src/lib/components/toolbox/toolbox-collab-maps-dropdown.vue","../../src/lib/components/about-dialog.vue","../../src/lib/components/toolbox/toolbox-help-dropdown.vue","../../src/lib/components/toolbox/toolbox-map-style-dropdown.vue","../../src/lib/components/edit-filter-dialog.vue","../../src/lib/components/share-dialog.vue","../../src/lib/components/ui/help-popover.vue","../../src/lib/components/export-dialog.vue","../../src/lib/components/user-preferences-dialog.vue","../../src/lib/components/toolbox/toolbox-tools-dropdown.vue","../../src/lib/components/save-view-dialog.vue","../../src/lib/components/manage-views-dialog.vue","../../src/lib/components/toolbox/toolbox-views-dropdown.vue","../../src/lib/components/ui/sidebar.vue","../../src/lib/components/toolbox/toolbox.vue","../../src/lib/components/ui/toasts/toast.vue","../../src/lib/components/click-marker-tab.vue","../../src/lib/components/client-provider.vue","../../src/lib/components/import-tab.vue","../../src/lib/components/overpass-info/overpass-info.vue","../../src/lib/components/overpass-info/overpass-multiple-info.vue","../../src/lib/components/overpass-info/overpass-info-tab.vue","../../src/lib/components/facil-map.vue"],"sourcesContent":["import type { FindOnMapResult, SearchResult } from \"facilmap-types\";\nimport { numberKeys } from \"facilmap-utils\";\nimport { isEqual } from \"lodash-es\";\nimport type { FileResult, FileResultObject } from \"./files\";\nimport type { ClientContext } from \"../components/facil-map-context-provider/client-context\";\n\nconst VIEW_KEYS: Array<keyof FileResultObject[\"views\"][0]> = [\"name\", \"baseLayer\", \"layers\", \"top\", \"bottom\", \"left\", \"right\", \"filter\"];\nconst TYPE_KEYS: Array<keyof FileResultObject[\"types\"][0]> = [\"name\", \"type\", \"defaultColour\", \"colourFixed\", \"defaultSize\", \"sizeFixed\", \"defaultSymbol\", \"symbolFixed\", \"defaultShape\", \"shapeFixed\", \"defaultWidth\", \"widthFixed\", \"defaultStroke\", \"strokeFixed\", \"defaultMode\", \"modeFixed\", \"fields\"];\n\nexport function isSearchResult(result: SearchResult | FindOnMapResult | FileResult): result is SearchResult {\n\treturn !isMapResult(result) && !isFileResult(result);\n}\n\nexport function isMapResult(result: SearchResult | FindOnMapResult | FileResult): result is FindOnMapResult {\n\treturn \"kind\" in result;\n}\n\nexport function isFileResult(result: SearchResult | FindOnMapResult | FileResult): result is FileResult {\n\treturn \"isFileResult\" in result && result.isFileResult;\n}\n\nexport function isMarkerResult(result: SearchResult | FindOnMapResult | FileResult): boolean {\n\tif (isMapResult(result))\n\t\treturn result.kind == \"marker\";\n\telse\n\t\treturn (result.lat != null && result.lon != null) || (!!result.geojson && result.geojson.type == \"Point\");\n}\n\nexport function isLineResult(result: SearchResult | FindOnMapResult | FileResult): boolean {\n\tif (isMapResult(result))\n\t\treturn result.kind == \"line\";\n\telse\n\t\treturn !!result.geojson && [\"LineString\", \"MultiLineString\", \"Polygon\", \"MultiPolygon\"].includes(result.geojson.type);\n}\n\nexport function viewExists(client: ClientContext, view: FileResultObject[\"views\"][0]): boolean {\n\tfor (const viewId of numberKeys(client.views)) {\n\t\tif(!VIEW_KEYS.some((idx) => !isEqual(view[idx], client.views[viewId][idx])))\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport function typeExists(client: ClientContext, type: FileResultObject[\"types\"][0]): boolean {\n\tfor (const typeId of numberKeys(client.types)) {\n\t\tif(!TYPE_KEYS.some((idx) => !isEqual(type[idx], client.types[typeId][idx])))\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n","import { type ComponentPublicInstance, type DeepReadonly, type Directive, type Ref, computed, onScopeDispose, readonly, ref, shallowReadonly, shallowRef, watch, type ComputedGetter, type Component, type VNodeProps, type AllowedComponentProps } from \"vue\";\n\n// https://stackoverflow.com/a/73784241/242365\nexport type ComponentProps<C extends Component> = C extends new (...args: any) => any\n  ? Omit<InstanceType<C>['$props'], keyof VNodeProps | keyof AllowedComponentProps>\n  : never;\n\nexport const vScrollIntoView: Directive<Element, boolean | undefined> = (el, binding) => {\n\tif (binding.value)\n\t\tel.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n};\n\n/**\n * Returns a computed property that is recomputed every time the window is resized.\n */\nexport function computedOnResize<T>(getValue: () => T): Readonly<Ref<T>> {\n\tconst value = shallowRef(getValue());\n\n\tconst handleResize = () => {\n\t\tvalue.value = getValue();\n\t};\n\n\twindow.addEventListener(\"resize\", handleResize);\n\n\tonScopeDispose(() => {\n\t\twindow.removeEventListener(\"resize\", handleResize);\n\t});\n\n\treturn shallowReadonly(value);\n}\n\nexport function useRefWithOverride<Value>(fallbackValue: Value, getProp: () => Value | undefined, onUpdate: (newValue: Value) => void): Ref<Value> {\n    const internalValue = ref(getProp() ?? fallbackValue);\n    return computed({\n        get: (): Value => {\n            const propValue = getProp();\n            return propValue !== undefined ? propValue : internalValue.value as Value;\n        },\n        set: (val: Value) => {\n            internalValue.value = val as any;\n            onUpdate(val);\n        }\n    });\n}\n\nexport function mapRef<K>(map: Map<K, Element | ComponentPublicInstance>, key: K): (ref: Element | ComponentPublicInstance | null) => void {\n\treturn (ref) => {\n\t\tif (ref) {\n\t\t\tmap.set(key, ref);\n\t\t} else {\n\t\t\tmap.delete(key);\n\t\t}\n\t};\n}\n\nexport function useResizeObserver(\n\telement: Ref<HTMLElement | undefined>,\n\tcallback?: (entry: ResizeObserverEntry) => void\n): DeepReadonly<Ref<ResizeObserverEntry | undefined>> {\n\tconst entry = ref<ResizeObserverEntry>();\n\tconst observer = new ResizeObserver((entries) => {\n\t\tentry.value = entries[0];\n\t\tcallback?.(entry.value);\n\t});\n\n\twatch(element, (value, oldValue, onCleanup) => {\n\t\tif (value) {\n\t\t\tobserver.observe(value);\n\t\t\tonCleanup(() => {\n\t\t\t\tobserver.unobserve(value);\n\t\t\t});\n\t\t}\n\t}, { immediate: true });\n\n\treturn readonly(entry);\n}\n\n/**\n * Allows to run multiple cleanup functions in watchers. Due to https://github.com/vuejs/core/issues/3341, only the last\n * onCleanup function specified is called. Call this with the onCleanup function given by the watcher and register\n * multiple cleanup callbacks by calling the onCleanup method returned by this function.\n */\nexport function fixOnCleanup(onCleanup: (cleanupFn: () => void) => void): (cleanupFn: () => void) => void {\n\tconst cleanupFns: Array<() => void> = [];\n\tonCleanup(() => {\n\t\tfor (const cleanupFn of cleanupFns) {\n\t\t\tcleanupFn();\n\t\t}\n\t});\n\n\treturn (cleanupFn: () => void) => {\n\t\tcleanupFns.push(cleanupFn);\n\t};\n}\n\nexport function computedAsync<T>(getter: ComputedGetter<Promise<T>>, onError = (err: any) => { console.error(err); }): Ref<T | undefined> {\n\tconst promise = computed(getter);\n\tconst val = ref<T>();\n\twatch(promise, (p) => {\n\t\tval.value = undefined;\n\t\tp.then((v) => {\n\t\t\tif (promise.value === p) {\n\t\t\t\tval.value = v;\n\t\t\t}\n\t\t}).catch(onError);\n\t}, { immediate: true });\n\treturn val;\n}\n\nexport const vHtmlAsync: Directive<Element, Promise<string>> = (el, binding) => {\n\tconst html = computedAsync(() => binding.value);\n\n\twatch(() => html.value, (val) => {\n\t\tel.innerHTML = val ?? \"\";\n\t});\n};","import { Units, unitsValidator } from \"facilmap-types\";\nimport Cookies from \"js-cookie\";\nimport { computed, reactive, readonly, ref } from \"vue\";\nimport * as z from \"zod\";\n\nconst cookieValidators = {\n\tlang: z.string().optional(),\n\tunits: unitsValidator.optional()\n};\n\nexport type Cookies = {\n\t[Name in keyof typeof cookieValidators]: z.infer<typeof cookieValidators[Name]>;\n}\n\nconst cookieCounter = ref(0);\n\nfunction cookie<Name extends keyof Cookies>(name: Name) {\n\treturn computed((): Cookies[Name] | undefined => {\n\t\tcookieCounter.value;\n\t\tconst value = Cookies.get(name);\n\t\tif (value == null) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst result = cookieValidators[name].safeParse(value);\n\t\treturn result.success ? result.data as Cookies[Name] : undefined;\n\t});\n}\n\nexport const cookies = readonly(reactive({\n\tlang: cookie(\"lang\"),\n\tunits: cookie(\"units\")\n}));\n\nconst hasStorageAccessP = (async () => {\n\tif (\"hasStorageAccess\" in document) {\n\t\treturn await document.hasStorageAccess();\n\t} else {\n\t\treturn true;\n\t}\n})();\n\nasync function setLongTermCookie(name: keyof Cookies, value: string): Promise<void> {\n\ttry {\n\t\tCookies.set(name, value, {\n\t\t\texpires: 3650,\n\t\t\tpartitioned: !(await hasStorageAccessP)\n\t\t});\n\t} finally {\n\t\tcookieCounter.value++;\n\t}\n}\n\nexport async function setLangCookie(value: string): Promise<void> {\n\tawait setLongTermCookie(\"lang\", value);\n}\n\nexport async function setUnitsCookie(value: Units): Promise<void> {\n\tawait setLongTermCookie(\"units\", value);\n}\n\n// Renew long-term cookies (see https://developer.chrome.com/blog/cookie-max-age-expires)\nif (cookies.lang) {\n\tvoid setLangCookie(cookies.lang);\n}\nif (cookies.units) {\n\tvoid setUnitsCookie(cookies.units);\n}","/// <reference types=\"vite/client\" />\nimport { type i18n } from \"i18next\";\nimport { defineComponent, ref } from \"vue\";\nimport messagesEn from \"../../i18n/en.json\";\nimport messagesDe from \"../../i18n/de.json\";\nimport messagesNbNo from \"../../i18n/nb-NO.json\";\nimport messagesRu from \"../../i18n/ru.json\";\nimport { LANG_COOKIE, LANG_QUERY, decodeQueryString, getAcceptHotI18n, getRawI18n, onI18nReady, setCurrentUnitsGetter } from \"facilmap-utils\";\nimport { cookies } from \"./cookies\";\nimport { unitsValidator } from \"facilmap-types\";\n\nconst namespace = \"facilmap-frontend\";\n\nonI18nReady((i18n) => {\n\ti18n.addResourceBundle(\"en\", namespace, messagesEn);\n\ti18n.addResourceBundle(\"de\", namespace, messagesDe);\n\ti18n.addResourceBundle(\"nb-NO\", namespace, messagesNbNo);\n\ti18n.addResourceBundle(\"ru\", namespace, messagesRu);\n});\n\nif (import.meta.hot) {\n\timport.meta.hot!.accept(`../../i18n/en.json`, getAcceptHotI18n(\"en\", namespace));\n\timport.meta.hot!.accept(`../../i18n/de.json`, getAcceptHotI18n(\"de\", namespace));\n\timport.meta.hot!.accept(`../../i18n/nb-NO.json`, getAcceptHotI18n(\"nb-NO\", namespace));\n\timport.meta.hot!.accept(`../../i18n/ru.json`, getAcceptHotI18n(\"ru\", namespace));\n}\n\nexport const i18nResourceChangeCounter = ref(0);\nconst onI18nResourceChange = () => {\n\ti18nResourceChangeCounter.value++;\n};\n\nonI18nReady((i18n) => {\n\ti18n.store.on(\"added\", onI18nResourceChange);\n\ti18n.store.on(\"removed\", onI18nResourceChange);\n\ti18n.on(\"languageChanged\", onI18nResourceChange);\n\ti18n.on(\"loaded\", onI18nResourceChange);\n\n\tlet tBkp = i18n.t;\n\ti18n.t = function(this: any, ...args: any) {\n\t\t// Consume resource change counter to make calls to t() reactive to i18n resource changes\n\t\ti18nResourceChangeCounter.value;\n\n\t\treturn tBkp.apply(this, args);\n\t} as any;\n});\n\nconst UNITS_COOKIE = \"units\";\nconst UNITS_QUERY = \"units\";\n\nsetCurrentUnitsGetter(() => {\n\tconst queryParams = decodeQueryString(location.search);\n\tconst query = queryParams.format ? unitsValidator.safeParse(queryParams[UNITS_QUERY]) : undefined;\n\treturn query?.success ? query.data : cookies[UNITS_COOKIE];\n});\n\nexport function getI18n(): {\n\tt: i18n[\"t\"];\n\tchangeLanguage: (lang: string) => Promise<void>;\n} {\n\treturn {\n\t\tt: getRawI18n().getFixedT(null, namespace),\n\n\t\tchangeLanguage: async (lang) => {\n\t\t\tawait getRawI18n().changeLanguage(lang);\n\t\t}\n\t};\n}\n\nexport function useI18n(): ReturnType<typeof getI18n> {\n\treturn getI18n();\n}\n\n/**\n * Renders a translated message. Each interpolation variable needs to be specified as a slot, making it possible to interpolate\n * components and rich text.\n */\nexport const T = defineComponent({\n\tprops: {\n\t\tk: { type: String, required: true }\n\t},\n\tsetup(props, { slots }) {\n\t\tconst i18n = useI18n();\n\n\t\treturn () => {\n\t\t\tconst mappedSlots = Object.entries(slots).map(([name, slot], i) => ({ name, placeholder: `%___SLOT_${i}___%`, slot }));\n\t\t\tconst placeholderByName = Object.fromEntries(mappedSlots.map(({ name, placeholder }) => [name, placeholder]));\n\t\t\tconst slotByPlaceholder = Object.fromEntries(mappedSlots.map(({ placeholder, slot }) => [placeholder, slot]));\n\t\t\tconst message = i18n.t(props.k, placeholderByName);\n\t\t\treturn message.split(/(%___SLOT_\\d+___%)/g).map((v, i) => {\n\t\t\t\tif (i % 2 === 0) {\n\t\t\t\t\treturn v;\n\t\t\t\t} else {\n\t\t\t\t\treturn slotByPlaceholder[v]!();\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\t}\n});\n\nexport function isLanguageExplicit(): boolean {\n\tconst queryParams = decodeQueryString(location.search);\n\treturn !!queryParams[LANG_QUERY] || !!queryParams[LANG_COOKIE];\n}\n\nexport function isUnitsExplicit(): boolean {\n\tconst queryParams = decodeQueryString(location.search);\n\treturn !!queryParams[UNITS_QUERY] || !!queryParams[UNITS_COOKIE];\n}","import type { Emitter } from \"mitt\";\nimport { type DeepReadonly, type Ref, watchEffect, toRef, effectScope } from \"vue\";\nimport type * as z from \"zod\";\nimport { getI18n } from \"./i18n\";\n\n// https://stackoverflow.com/a/62085569/242365\nexport type DistributedKeyOf<T> = T extends any ? keyof T : never;\n\nexport type AnyRef<T> = T | Ref<T> | (() => T);\n\n\nlet idCounter = 1;\n\nexport function getUniqueId(scope = \"\"): string {\n\treturn `${scope ? `${scope}-` : \"\"}${idCounter++}`;\n}\n\nexport function useEventListener<EventMap extends Record<string, unknown>, EventType extends keyof EventMap>(emitter: AnyRef<Emitter<EventMap> | DeepReadonly<Emitter<EventMap>> | undefined>, type: EventType, listener: (data: EventMap[EventType]) => void): void {\n\tconst emitterRef = toRef(emitter);\n\n\twatchEffect((onCleanup) => {\n\t\tif (emitterRef.value) {\n\t\t\tconst val = emitterRef.value;\n\t\t\tval.on(type, listener);\n\t\t\tonCleanup(() => {\n\t\t\t\tval.off(type, listener);\n\t\t\t});\n\t\t}\n\t});\n}\n\nexport function useDomEventListener<Element extends EventTarget, Args extends Parameters<Element[\"addEventListener\"]>>(element: AnyRef<EventTarget | undefined>, ...args: Args): void {\n\twatchEffect((onCleanup) => {\n\t\tconst elementRef = toRef(element);\n\t\tif (elementRef.value) {\n\t\t\tconst el = elementRef.value as any;\n\t\t\tel.addEventListener(...args);\n\t\t\tonCleanup(() => {\n\t\t\t\tel.removeEventListener(...args);\n\t\t\t});\n\t\t}\n\t});\n}\n\n/**\n * An event whose handler can be delayed in a similar fashion to the native ExtendableEvent\n * (https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent/ExtendableEvent).\n * This enables a pattern described here: https://github.com/vuejs/vue/issues/5443#issuecomment-379284227\n * as a workaround for the fact that Vue event handlers cannot be async.\n */\nexport interface ExtendableEventMixin {\n\twaitUntil(promise: Promise<void>): void;\n\t_hasAwaited?: boolean;\n\t_promises?: Array<Promise<void>>;\n\t_awaitPromises(): Promise<void>;\n}\n\nexport const extendableEventMixin: ExtendableEventMixin = {\n\twaitUntil(promise) {\n\t\tif (this._hasAwaited) {\n\t\t\tthrow new Error(\"Cannot call waitUntil() after event has been processed.\");\n\t\t} else if (this._promises) {\n\t\t\tthis._promises.push(promise);\n\t\t} else {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\tthis._promises = [promise];\n\t\t}\n\t},\n\n\tasync _awaitPromises() {\n\t\tif (this._hasAwaited) {\n\t\t\tthrow new Error(\"Event has already been awaited.\");\n\t\t} else {\n\t\t\tthis._hasAwaited = true;\n\t\t\tawait Promise.all(this._promises ?? []);\n\t\t}\n\t}\n}\n\nexport function validations<V>(val: V, funcs: Array<(val: V) => string | undefined>): string | undefined {\n\tfor (const func of funcs) {\n\t\tconst result = func(val);\n\t\tif (result) {\n\t\t\treturn result;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport function validateRequired(val: any): string | undefined {\n\tif (val == null || val === \"\") {\n\t\treturn getI18n().t(\"utils.required-error\");\n\t}\n}\n\nexport function getZodValidator(validator: z.ZodType): (val: any) => string | undefined {\n\treturn (val) => {\n\t\tif (val) {\n\t\t\tconst result = validator.safeParse(val);\n\t\t\tif (!result.success) {\n\t\t\t\treturn result.error.format()._errors.join(\"\\n\");\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Registers a focus handler on the given element that does not fire when the focus was given through a click.\n */\nexport function useNonClickFocusHandler(element: AnyRef<HTMLElement | undefined>, onFocus: (e: FocusEvent) => void): void {\n\tlet lastEvent: {\n\t\ttimeout: ReturnType<typeof setTimeout>;\n\t\thadMouseDown?: boolean;\n\t\tfocusEvent?: FocusEvent;\n\t} | undefined;\n\n\tuseDomEventListener(element, \"mousedown\", () => {\n\t\tlastEvent = {\n\t\t\t...lastEvent,\n\t\t\ttimeout: lastEvent?.timeout ?? setTimeout(handleTimeout, 0),\n\t\t\thadMouseDown: true\n\t\t};\n\t});\n\n\tuseDomEventListener(element, \"focus\", (e: Event) => {\n\t\tlastEvent = {\n\t\t\t...lastEvent,\n\t\t\ttimeout: lastEvent?.timeout ?? setTimeout(handleTimeout, 0),\n\t\t\tfocusEvent: e as FocusEvent\n\t\t};\n\t});\n\n\tfunction handleTimeout() {\n\t\tif (lastEvent?.focusEvent && !lastEvent.hadMouseDown) {\n\t\t\tonFocus(lastEvent.focusEvent);\n\t\t}\n\t\tlastEvent = undefined;\n\t}\n}\n\n/**\n * Registers a click handler on the given element that does not fire when the click is caused by a drag.\n */\nexport function useNonDragClickHandler(element: AnyRef<HTMLElement | undefined>, onClick: (e: MouseEvent) => void): void {\n\tlet hasMoved = false;\n\n\tuseDomEventListener(element, \"mousedown\", () => {\n\t\thasMoved = false;\n\t\tconst scope = effectScope();\n\t\tscope.run(() => {\n\t\t\tuseDomEventListener(document, \"mousemove\", () => {\n\t\t\t\thasMoved = true;\n\t\t\t}, { capture: true });\n\t\t\tuseDomEventListener(document, \"mouseup\", () => {\n\t\t\t\tscope.stop();\n\t\t\t}, { capture: true });\n\t\t});\n\t});\n\n\tuseDomEventListener(element, \"click\", (e) => {\n\t\tif (!hasMoved) {\n\t\t\tonClick(e as MouseEvent);\n\t\t}\n\t});\n}\n\nexport function useUnloadHandler(hasUnsavedModifications: AnyRef<boolean>): void {\n\tconst hasUnsavedModificationsRef = toRef(hasUnsavedModifications);\n\tuseDomEventListener(window, \"beforeunload\", (e) => {\n\t\tif (hasUnsavedModificationsRef.value) {\n\t\t\te.preventDefault();\n\t\t}\n\t});\n}","import type { Directive } from \"vue\";\n\nconst vLinkDisabled: Directive<HTMLAnchorElement, boolean> = (el, binding) => {\n\tif (binding.value) {\n\t\tel.classList.add(\"disabled\");\n\t\tel.setAttribute(\"aria-disabled\", \"true\");\n\t\tel.setAttribute(\"tabindex\", \"-1\");\n\t} else {\n\t\tel.classList.remove(\"disabled\");\n\t\tel.removeAttribute(\"aria-disabled\");\n\t\tel.removeAttribute(\"tabindex\");\n\t}\n};\n\nexport default vLinkDisabled;","<script lang=\"ts\">\n\t/// <reference types=\"vite/client\" />\n\n\timport { createApp, nextTick, onScopeDispose, reactive, ref, toRef, type App } from \"vue\";\n\timport Toast from \"bootstrap/js/dist/toast\";\n\timport Toasts from \"./toasts.vue\";\n\timport { mapRef } from \"../../../utils/vue\";\n\timport { getUniqueId } from \"../../../utils/utils\";\n\timport type { ThemeColour } from \"../../../utils/bootstrap\";\n\timport { getI18n, useI18n } from \"../../../utils/i18n\";\n\timport vLinkDisabled from \"../../../utils/link-disabled\";\n\n\texport interface ToastContext {\n\t\tshowErrorToast(id: string | undefined, title: string | (() => string), err: any, options?: ToastOptions | (() => ToastOptions)): Promise<void>;\n\t\ttoastErrors<C extends (...args: any[]) => any>(callback: C): C;\n\t\tshowToast(id: string | undefined, title: string | (() => string), message: string | (() => string), options?: ToastOptions | (() => ToastOptions)): Promise<void>;\n\t\thideToast(id: string): Promise<void>;\n\t\tdispose(): void;\n\t}\n\n\texport interface ToastOptions {\n\t\tactions?: ToastAction[];\n\t\tspinner?: boolean;\n\t\tvariant?: ThemeColour;\n\t\tnoCloseButton?: boolean;\n\t\tautoHide?: boolean;\n\t\tonHide?: () => void;\n\t\tonHidden?: () => void;\n\t}\n\n\texport interface ToastAction {\n\t\tonClick?: (e: MouseEvent) => void;\n\t\tlabel: string;\n\t\thref?: string;\n\t\tvariant?: ThemeColour;\n\t\tisDisabled?: boolean;\n\t\tisPending?: boolean;\n\t}\n\n\tinterface ToastInstance {\n\t\tkey: string;\n\t\tid: string | undefined;\n\t\ttitle: string;\n\t\tmessage: string;\n\t\tcontextId: string;\n\t\toptions: ToastOptions;\n\t}\n\n\texport const toastContainer = document.createElement(\"div\");\n\ttoastContainer.classList.add(\"fm-toast-container\");\n\tdocument.body.appendChild(toastContainer);\n\n\tlet app: App | undefined;\n\tconst appMountP = Promise.resolve().then(() => {\n\t\tapp = createApp(Toasts);\n\t\tapp.mount(toastContainer);\n\t}).catch((err) => {\n\t\tconsole.error(\"Error rendering toast container\", err);\n\t});\n\timport.meta.hot?.dispose(() => {\n\t\tapp?.unmount();\n\t\ttoastContainer.remove();\n\t});\n\n\tconst toasts = ref<ToastInstance[]>([]);\n\tconst toastRefs = reactive(new Map<ToastInstance, HTMLElement>());\n\n\texport function useToasts(noScope = false): ToastContext {\n\t\tconst contextId = getUniqueId(\"fm-toast-context\");\n\t\tconst result: ToastContext = {\n\t\t\tshowErrorToast: async (id, title, err, options) => {\n\t\t\t\tif (err.stack)\n\t\t\t\t\tconsole.error(err.stack);\n\n\t\t\t\tawait result.showToast(id, title, err.message || err, {\n\t\t\t\t\tvariant: \"danger\",\n\t\t\t\t\tnoCloseButton: false,\n\t\t\t\t\t...options\n\t\t\t\t});\n\t\t\t},\n\n\t\t\ttoastErrors: <C extends (...args: any[]) => any>(callback: C) => {\n\t\t\t\treturn ((...args) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst res = callback(...args);\n\t\t\t\t\t\tPromise.resolve(res).catch((err) => {\n\t\t\t\t\t\t\tvoid result.showErrorToast(undefined, getI18n().t(\"toasts.unexpected-error\"), err);\n\t\t\t\t\t\t\tthrow err;\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn res;\n\t\t\t\t\t} catch (err: any) {\n\t\t\t\t\t\tvoid result.showErrorToast(undefined, getI18n().t(\"toasts.unexpected-error\"), err);\n\t\t\t\t\t}\n\t\t\t\t}) as C;\n\t\t\t},\n\n\t\t\tshowToast: async (id, title, message, options = {}) => {\n\t\t\t\tawait appMountP;\n\t\t\t\tif (id != null) {\n\t\t\t\t\tvoid result.hideToast(id);\n\t\t\t\t}\n\n\t\t\t\tconst toast: ToastInstance = reactive({\n\t\t\t\t\tkey: getUniqueId(\"fm-toast\"),\n\t\t\t\t\tid,\n\t\t\t\t\ttitle: toRef(title),\n\t\t\t\t\tmessage: toRef(message),\n\t\t\t\t\tcontextId,\n\t\t\t\t\toptions: toRef(options)\n\t\t\t\t});\n\t\t\t\ttoasts.value.push(toast);\n\n\t\t\t\tawait nextTick();\n\n\t\t\t\tawait showToastInstance(toast);\n\t\t\t},\n\n\t\t\thideToast: async (id) => {\n\t\t\t\tconst toastsToHide = toasts.value.filter((t) => t.contextId === contextId && t.id === id);\n\t\t\t\tawait Promise.all(toastsToHide.map(async (toast) => {\n\t\t\t\t\tawait hideToastInstance(toast);\n\t\t\t\t}));\n\t\t\t},\n\n\t\t\tdispose: async () => {\n\t\t\t\tconst toastsToHide = toasts.value.filter((t) => t.contextId === contextId);\n\t\t\t\tawait Promise.all(toastsToHide.map(async (toast) => {\n\t\t\t\t\tawait hideToastInstance(toast);\n\t\t\t\t}));\n\t\t\t}\n\t\t};\n\n\t\tif (!noScope) {\n\t\t\tonScopeDispose(() => {\n\t\t\t\tresult.dispose();\n\t\t\t});\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tasync function showToastInstance(toast: ToastInstance): Promise<void> {\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tconst toastRef = toastRefs.get(toast)!;\n\t\t\ttoastRef.addEventListener(\"shown.bs.toast\", () => resolve());\n\t\t\tToast.getOrCreateInstance(toastRef, { autohide: !!toast.options.autoHide }).show();\n\n\t\t\ttoastRef.addEventListener(\"hide.bs.toast\", () => {\n\t\t\t\ttoast.options.onHide?.();\n\t\t\t});\n\n\t\t\ttoastRef.addEventListener(\"hidden.bs.toast\", () => {\n\t\t\t\ttoasts.value = toasts.value.filter((t) => t !== toast);\n\t\t\t\ttoastRefs.delete(toast);\n\t\t\t\ttoast.options.onHidden?.();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync function hideToastInstance(toast: ToastInstance): Promise<void> {\n\t\tawait appMountP;\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tconst toastRef = toastRefs.get(toast)!;\n\t\t\ttoastRef.addEventListener(\"hidden.bs.toast\", () => resolve());\n\t\t\tToast.getInstance(toastRef)!.hide();\n\t\t});\n\t}\n</script>\n\n<script setup lang=\"ts\">\n\t// This script must not be empty, otherwise Vue assumes this component is using the Options API\n\n\tconst i18n = useI18n();\n</script>\n\n<template>\n\t<div class=\"toast-container position-fixed top-0 end-0 p-3 fm-toasts\">\n\t\t<div\n\t\t\tv-for=\"toast in toasts\"\n\t\t\t:key=\"toast.key\"\n\t\t\tclass=\"toast\"\n\t\t\t:class=\"{ 'border-0': toast.options.variant }\"\n\t\t\trole=\"alert\"\n\t\t\taria-live=\"assertive\"\n\t\t\taria-atomic=\"true\"\n\t\t\t:ref=\"mapRef(toastRefs, toast)\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"toast-header bg-opacity-25 text-break\"\n\t\t\t\t:class=\"toast.options.variant && `bg-${toast.options.variant} bg-opacity-25`\"\n\t\t\t>\n\t\t\t\t<strong class=\"me-auto\">{{toast.title}}</strong>\n\t\t\t\t<button v-if=\"!toast.options.noCloseButton\" type=\"button\" class=\"btn-close\" @click=\"hideToastInstance(toast)\" :aria-label=\"i18n.t('toasts.close-label')\"></button>\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tclass=\"toast-body bg-opacity-10 text-break\"\n\t\t\t\t:class=\"toast.options.variant && `bg-${toast.options.variant} bg-opacity-10`\"\n\t\t\t>\n\t\t\t\t<div>\n\t\t\t\t\t<div v-if=\"toast.options.spinner\" class=\"spinner-border spinner-border-sm\" role=\"status\">\n\t\t\t\t\t\t<span class=\"visually-hidden\">{{i18n.t(\"toasts.spinner-label\")}}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t{{toast.message}}\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"(toast.options.actions?.length ?? 0) > 0\" class=\"btn-toolbar mt-2 pt-2 border-top\">\n\t\t\t\t\t<template v-for=\"(action, idx) in toast.options.actions\" :key=\"idx\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tv-if=\"!action.href\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"btn btn-sm\"\n\t\t\t\t\t\t\t:class=\"`btn-${action.variant ?? 'secondary'}`\"\n\t\t\t\t\t\t\t@click=\"action.onClick\"\n\t\t\t\t\t\t\t:disabled=\"action.isDisabled\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div v-if=\"action.isPending\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t{{action.label}}\n\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\tv-if=\"action.href\"\n\t\t\t\t\t\t\t:href=\"action.href\"\n\t\t\t\t\t\t\tclass=\"btn btn-sm\"\n\t\t\t\t\t\t\t:class=\"`btn-${action.variant ?? 'secondary'}`\"\n\t\t\t\t\t\t\t@click=\"action.onClick\"\n\t\t\t\t\t\t\tv-link-disabled=\"action.isDisabled ?? false\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div v-if=\"action.isPending\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t{{action.label}}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</template>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-toast-container {\n\t\tposition: absolute;\n\t\tz-index: 10002; /* Above .fm-leaflet-map-disabled-cover */\n\t}\n</style>","import { computed, type Ref, ref } from \"vue\";\nimport maxSize from \"popper-max-size-modifier\";\nimport type { Modifier, ModifierArguments } from \"@popperjs/core\";\n\nconst breakpointMinWidth = {\n\t// See https://getbootstrap.com/docs/5.3/layout/breakpoints/#available-breakpoints\n\txs: 0,\n\tsm: 576,\n\tmd: 768,\n\tlg: 992,\n\txl: 1200,\n\txxl: 1400\n};\n\nexport type Breakpoint = keyof typeof breakpointMinWidth;\n\nexport const breakpoints = Object.keys(breakpointMinWidth) as Breakpoint[];\n\nconst update = ref(0);\n\nconst mediaQueries = Object.fromEntries(Object.entries(breakpointMinWidth).map(([breakpoint, minWidth]) => {\n\tconst query = matchMedia(`(min-width: ${minWidth}px)`);\n\tquery.addEventListener(\"change\", () => {\n\t\tupdate.value++\n\t});\n\treturn [breakpoint, query];\n}));\n\nexport const reactiveBreakpoint = computed(() => {\n\tupdate.value;\n\treturn [...breakpoints].reverse().find((breakpoint) => mediaQueries[breakpoint].matches) ?? 'xs';\n});\n\nexport function isMaxBreakpoint(breakpoint: Breakpoint): boolean {\n\treturn breakpoints.indexOf(reactiveBreakpoint.value) <= breakpoints.indexOf(breakpoint);\n}\n\n/**\n * Returns a reactive boolean that is true if the current breakpoint is the specified one or smaller.\n */\nexport function useMaxBreakpoint(breakpoint: Breakpoint): Ref<boolean> {\n\treturn computed(() => isMaxBreakpoint(breakpoint));\n}\n\n/**\n * Returns a reactive boolean that is true if the current breakpoint is the specified one or larger.\n */\nexport function useMinBreakpoint(breakpoint: Breakpoint): Ref<boolean> {\n\treturn computed(() => breakpoints.indexOf(reactiveBreakpoint.value) >= breakpoints.indexOf(breakpoint));\n}\n\nexport type ThemeColour = \"primary\" | \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"light\" | \"dark\";\nexport type ButtonVariant = ThemeColour | \"link\" | \"outline-primary\" | \"outline-secondary\" | \"outline-success\" | \"outline-danger\" | \"outline-warning\" | \"outline-info\" | \"outline-light\" | \"outline-dark\";\nexport type ButtonSize = \"lg\" | \"sm\";\n\n/**\n * An array of popper modifiers that uses popper-max-size-modifier to shrink the popover to prevent overflow\n * rather than move it, as is the default in Bootstrap.\n */\nexport const getMaxSizeModifiers = ({ maxWidth = \"30rem\" }: { maxWidth?: string } = {}): Array<Partial<Modifier<any, any>>> => [\n\t{\n\t\t...maxSize,\n\t\toptions: {\n\t\t\tpadding: 5\n\t\t}\n\t},\n\t{\n\t\tname: 'applyMaxSize',\n\t\tenabled: true,\n\t\tphase: 'beforeWrite',\n\t\trequires: ['maxSize'],\n\t\tfn({ state }: ModifierArguments<any>): void {\n\t\t\t// The `maxSize` modifier provides this data\n\t\t\tconst {width, height} = state.modifiersData.maxSize;\n\n\t\t\tstate.styles.popper = {\n\t\t\t\t...state.styles.popper,\n\t\t\t\tmaxWidth: `min(${maxWidth}, ${width}px)`,\n\t\t\t\tmaxHeight: `${height}px`\n\t\t\t}\n\t\t}\n\t}\n];\n","<script lang=\"ts\">\n\timport { type InjectionKey, type Ref, inject, onScopeDispose, provide, shallowReactive, toRef, watch, reactive, readonly, shallowReadonly } from \"vue\";\n\timport { useMaxBreakpoint } from \"../../utils/bootstrap\";\n\timport type { FacilMapComponents, FacilMapContext, FacilMapSettings } from \"./facil-map-context\";\n\n\tconst contextInject = Symbol(\"contextInject\") as InjectionKey<FacilMapContext>;\n\n\texport function injectContextOptional(): FacilMapContext | undefined {\n\t\treturn inject(contextInject);\n\t}\n\n\texport function injectContextRequired(): FacilMapContext {\n\t\tconst context = injectContextOptional();\n\t\tif (!context) {\n\t\t\tthrow new Error(\"No context injected.\");\n\t\t}\n\t\treturn context;\n\t}\n\n\tfunction getRequireContext<K extends keyof FacilMapComponents>(key: K, componentName: string): (context: FacilMapContext) => Ref<NonNullable<FacilMapComponents[K]>> {\n\t\treturn (context) => {\n\t\t\treturn toRef(() => {\n\t\t\t\tif (!context.components[key]) {\n\t\t\t\t\tthrow new Error(`${key} component is not available. Make sure to have a <${componentName}> within your <FacilMapContextProvider>.`);\n\t\t\t\t}\n\t\t\t\treturn context.components[key] as NonNullable<FacilMapComponents[K]>;\n\t\t\t});\n\t\t};\n\t}\n\n\texport const requireClientContext = getRequireContext(\"client\", \"ClientProvider\");\n\texport const requireMapContext = getRequireContext(\"map\", \"LeafletMap\");\n\texport const requireSearchBoxContext = getRequireContext(\"searchBox\", \"SearchBox\");\n\n\tlet idCounter = 1;\n</script>\n\n<script setup lang=\"ts\">\n\tconst props = withDefaults(defineProps<{\n\t\tbaseUrl: string;\n\t\tappName?: string;\n\t\thideCommercialMapLinks?: boolean;\n\t\tsettings?: Partial<FacilMapSettings>;\n\t}>(), {\n\t\tappName: \"FacilMap\"\n\t});\n\n\tconst isNarrow = useMaxBreakpoint(\"sm\");\n\n\tconst components = shallowReactive<FacilMapComponents>({});\n\n\tfunction provideComponent<K extends keyof FacilMapComponents>(key: K, componentRef: Readonly<Ref<FacilMapComponents[K]>>) {\n\t\tif (key in components) {\n\t\t\tthrow new Error(`Component \"${key}\" is already provided.`);\n\t\t}\n\n\t\twatch(componentRef, (component) => {\n\t\t\tcomponents[key] = component;\n\t\t}, { immediate: true });\n\n\t\tonScopeDispose(() => {\n\t\t\tdelete components[key];\n\t\t});\n\t}\n\n\tconst context: FacilMapContext = shallowReadonly(reactive({\n\t\tid: idCounter++,\n\t\tbaseUrl: toRef(() => props.baseUrl),\n\t\tappName: toRef(() => props.appName),\n\t\thideCommercialMapLinks: toRef(() => props.hideCommercialMapLinks),\n\t\tisNarrow,\n\t\tsettings: readonly(toRef(() => ({\n\t\t\ttoolbox: true,\n\t\t\tsearch: true,\n\t\t\troute: true,\n\t\t\tpois: true,\n\t\t\tlocate: true,\n\t\t\tautofocus: false,\n\t\t\tlegend: true,\n\t\t\tinteractive: true,\n\t\t\tlinkLogo: false,\n\t\t\tupdateHash: false,\n\t\t\trouting: true,\n\t\t\tadvancedRouting: true,\n\t\t\t...props.settings\n\t\t}))),\n\t\tcomponents: shallowReadonly(components),\n\t\tprovideComponent\n\t}));\n\n\tprovide(contextInject, context)\n\n\tdefineExpose({\n\t\tcontext\n\t});\n</script>\n\n<template>\n\t<slot></slot>\n</template>","import type { CRU, Line, Marker, Point, SearchResult, Type } from \"facilmap-types\";\nimport { omit } from \"lodash-es\";\nimport type { FileResult } from \"./files\";\nimport type { LineString, MultiLineString, MultiPolygon, Point as GeoJSONPoint, Polygon, Position } from \"geojson\";\nimport type { Optional } from \"facilmap-utils\";\nimport type { OverpassElement } from \"facilmap-leaflet\";\nimport type { SelectedItem } from \"./selection\";\nimport type { ClientContext } from \"../components/facil-map-context-provider/client-context\";\nimport { isLineResult, isMarkerResult } from \"./search\";\nimport { useToasts } from \"../components/ui/toasts/toasts.vue\";\nimport type { FacilMapContext } from \"../components/facil-map-context-provider/facil-map-context\";\nimport { requireClientContext, requireMapContext } from \"../components/facil-map-context-provider/facil-map-context-provider.vue\";\nimport type { Ref } from \"vue\";\nimport { getI18n } from \"./i18n\";\n\nexport type MarkerWithTags = Omit<Marker<CRU.CREATE>, \"typeId\"> & { tags?: Record<string, string> };\nexport type LineWithTags = Omit<Line<CRU.CREATE>, \"typeId\"> & { tags?: Record<string, string> };\n\nexport function searchResultToMarkerWithTags(result: SearchResult | FileResult): MarkerWithTags | undefined {\n\tif (!isMarkerResult(result)) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\ttags: {\n\t\t\t...(result.address ? { address: result.address } : {}),\n\t\t\t...result.extratags\n\t\t},\n\t\t...(\"fmProperties\" in result && result.fmProperties ? omit(result.fmProperties, [\"typeId\"]) : {}), // Import GeoJSON\n\t\tname: result.short_name,\n\t\tlat: result.lat ?? (result.geojson as GeoJSONPoint).coordinates[1],\n\t\tlon: result.lon ?? (result.geojson as GeoJSONPoint).coordinates[0]\n\t};\n}\n\nexport function searchResultsToMarkersWithTags(results: Array<SearchResult | FileResult>): MarkerWithTags[] {\n\treturn results.flatMap((result) => {\n\t\tconst markerWithTags = searchResultToMarkerWithTags(result);\n\t\treturn markerWithTags ? [markerWithTags] : [];\n\t});\n}\n\nexport function searchResultToLineWithTags(result: SearchResult | FileResult): LineWithTags | undefined {\n\tif (!isLineResult(result)) {\n\t\treturn undefined;\n\t}\n\n\tconst line: Optional<LineWithTags, \"routePoints\"> = {\n\t\ttags: {\n\t\t\t...(result.address ? { address: result.address } : {}),\n\t\t\t...result.extratags\n\t\t},\n\t\t...(\"fmProperties\" in result && result.fmProperties ? omit(result.fmProperties, [\"typeId\"]) : {}), // Import GeoJSON\n\t\tname: result.short_name\n\t};\n\n\tif (!line.routePoints) {\n\t\tconst trackPoints = lineStringToTrackPoints(result.geojson as any);\n\n\t\treturn {\n\t\t\t...line,\n\t\t\troutePoints: [trackPoints[0], trackPoints[trackPoints.length-1]],\n\t\t\ttrackPoints: trackPoints,\n\t\t\tmode: \"track\"\n\t\t};\n\t} else {\n\t\treturn line as LineWithTags;\n\t}\n}\n\nexport function searchResultsToLinesWithTags(results: Array<SearchResult | FileResult>): LineWithTags[] {\n\treturn results.flatMap((result) => {\n\t\tconst lineWithTags = searchResultToLineWithTags(result);\n\t\treturn lineWithTags ? [lineWithTags] : [];\n\t});\n}\n\nexport function overpassElementsToMarkersWithTags(elements: OverpassElement[]): MarkerWithTags[] {\n\treturn elements.map((element) => {\n\t\treturn {\n\t\t\tname: element.tags.name || \"\",\n\t\t\tlat: element.lat,\n\t\t\tlon: element.lon,\n\t\t\ttags: element.tags,\n\t\t};\n\t});\n}\n\n/**\n * Maps the tags from a search result to fields whose name is similar to the tag key (ignoring case and\n * non-letters). The resulting object can be used as \"data\" for a marker and line.\n */\nexport function mapTagsToType(tags: Record<string, string>, type: Type): Record<string, string> {\n\tlet keyMap = (keys: string[]) => {\n\t\tlet ret: Record<string, string> = Object.create(null);\n\t\tfor(let key of keys)\n\t\t\tret[key.replace(/[^a-z0-9]/gi, \"\").toLowerCase()] = key;\n\t\treturn ret;\n\t};\n\n\tlet fieldKeys = keyMap(type.fields.map((field) => (field.name)));\n\tlet resultDataKeys = keyMap(Object.keys(tags));\n\n\tconst ret: Record<string, string> = Object.create(null);\n\tfor(let key in resultDataKeys) {\n\t\tif(fieldKeys[key])\n\t\t\tret[fieldKeys[key]] = tags[resultDataKeys[key]];\n\t}\n\treturn ret;\n}\n\nfunction lineStringToTrackPoints(geometry: LineString | MultiLineString | Polygon | MultiPolygon): Point[] {\n\tlet coords: Position[][];\n\tif (geometry.type == \"MultiPolygon\") // Take only outer ring of polygons\n\t\tcoords = geometry.coordinates.map((coordArr) => coordArr[0]);\n\telse if (geometry.type == \"MultiLineString\")\n\t\tcoords = geometry.coordinates;\n\telse if (geometry.type == \"Polygon\")\n\t\tcoords = [geometry.coordinates[0]];\n\telse\n\t\tcoords = [geometry.coordinates];\n\n\treturn coords.flat().map((latlng) => ({ lat: latlng[1], lon: latlng[0] }));\n}\n\nexport async function addMarkerToMap(client: Ref<ClientContext>, marker: MarkerWithTags, type: Type): Promise<SelectedItem> {\n\tconst newMarker = await client.value.addMarker({\n\t\t...marker,\n\t\tdata: {\n\t\t\t...marker.tags && mapTagsToType(marker.tags, type),\n\t\t\t...marker.data\n\t\t},\n\t\ttypeId: type.id\n\t});\n\n\treturn { type: \"marker\", id: newMarker.id };\n}\n\nexport async function addLineToMap(client: Ref<ClientContext>, line: LineWithTags, type: Type): Promise<SelectedItem> {\n\tconst newLine = await client.value.addLine({\n\t\t...line,\n\t\ttypeId: type.id\n\t});\n\n\treturn { type: \"line\", id: newLine.id };\n}\n\nexport async function addToMap(context: FacilMapContext, objects: Array<({ marker: MarkerWithTags } | { line: LineWithTags }) & { type: Type }>): Promise<SelectedItem[]> {\n\tconst selection: SelectedItem[] = [];\n\n\tconst client = requireClientContext(context);\n\n\tfor (const object of objects) {\n\t\tif (\"marker\" in object) {\n\t\t\tselection.push(await addMarkerToMap(client, object.marker, object.type));\n\t\t} else {\n\t\t\tselection.push(await addLineToMap(client, object.line, object.type));\n\t\t}\n\t}\n\n\tshowAddConfirmation(context, selection);\n\n\treturn selection;\n}\n\nfunction showAddConfirmation(context: FacilMapContext, selection: SelectedItem[]) {\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\n\tconst markers = selection.flatMap((item) => (item.type === \"marker\" ? [client.value.markers[item.id]] : []));\n\tconst lines = selection.flatMap((item) => (item.type === \"line\" ? [client.value.lines[item.id]] : []));\n\n\tconst objects = [...markers, ...lines].length;\n\tconst hiddenObjects = [...markers, ...lines].filter((obj) => !mapContext.value.components.map.fmFilterFunc(obj, client.value.types[obj.typeId])).length;\n\n\tif (hiddenObjects > 0) {\n\t\tconst i18n = getI18n();\n\t\tconst title = () => (\n\t\t\tlines.length === 0 ? i18n.t(\"add.hidden-markers-added-title\", { count: markers.length }) :\n\t\t\tmarkers.length === 0 ? i18n.t(\"add.hidden-lines-added-title\", { count: lines.length }) :\n\t\t\ti18n.t(\"add.hidden-objects-added-title\", { count: objects })\n\t\t);\n\n\t\tconst message = () => (\n\t\t\tlines.length === 0 ? i18n.t(\"add.hidden-markers-added-message\", { count: markers.length }) :\n\t\t\tmarkers.length === 0 ? i18n.t(\"add.hidden-lines-added-message\", { count: lines.length }) :\n\t\t\tobjects === hiddenObjects ? i18n.t(\"add.hidden-objects-added-message\", { count: objects }) :\n\t\t\ti18n.t(\"add.hidden-objects-added-message-some\", { count: objects })\n\t\t);\n\n\t\tconst toasts = useToasts(true);\n\t\ttoasts.showToast(\n\t\t\tundefined,\n\t\t\ttitle,\n\t\t\tmessage,\n\t\t\t{\n\t\t\t\tvariant: \"success\",\n\t\t\t\tautoHide: true,\n\t\t\t\tonHidden: () => {\n\t\t\t\t\ttoasts.dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n}","import { Evented, LatLngBounds, Map } from \"leaflet\";\nimport { throttle } from \"lodash-es\";\n\nexport default class BoxSelection extends Map.BoxZoom {\n\n\t_ctrlKey = false;\n\n\tconstructor(map: Map) {\n\t\tsuper(Object.assign(Object.create(map), {\n\t\t\tfire: (type: string) => {\n\t\t\t\tif (type == \"boxzoomstart\")\n\t\t\t\t\tthis.fire(\"selectstart\", { ctrlKey: this._ctrlKey });\n\t\t\t\telse if (type == \"boxzoomend\")\n\t\t\t\t\tthis.fire(\"selectend\");\n\n\t\t\t\treturn this._map;\n\t\t\t},\n\t\t\tfitBounds: () => {\n\t\t\t\treturn this._map;\n\t\t\t}\n\t\t}));\n\t}\n\n\t_onMouseDown(e: MouseEvent): void {\n\t\tthis._ctrlKey = e.ctrlKey;\n\t\tsuper._onMouseDown(e);\n\t}\n\n\t_onMouseMove(e: MouseEvent): void {\n\t\tsuper._onMouseMove(e);\n\n\t\tthis.fireSelect(new LatLngBounds(\n\t\t\tthis._map.containerPointToLatLng(this._startPoint),\n\t\t\tthis._map.containerPointToLatLng(this._point)\n\t\t));\n\t}\n\n\tfireSelect = throttle((bounds: LatLngBounds) => {\n\t\tthis.fire(\"select\", { bounds });\n\t}, 300);\n\n}\n\n// eslint-disable-next-line no-redeclare\nexport default interface BoxSelection extends Evented {}\nObject.assign(BoxSelection.prototype, Evented.prototype);\n","import Carousel from \"bootstrap/js/dist/carousel\";\nimport { type Ref, reactive, readonly, watch } from \"vue\";\n\nexport interface CarouselContext {\n\ttab: number;\n\tsetTab(tab: number): void;\n}\n\nexport function useCarousel(element: Ref<HTMLElement | undefined>): Readonly<CarouselContext> {\n\tconst context = reactive<CarouselContext>({\n\t\ttab: 0,\n\t\tsetTab: (tab) => {\n\t\t\tconst carousel = element.value && Carousel.getInstance(element.value);\n\t\t\tif (carousel) {\n\t\t\t\tcarousel.to(tab);\n\t\t\t} else {\n\t\t\t\tcontext.tab = tab;\n\t\t\t}\n\t\t}\n\t});\n\n\twatch(element, (newRef, oldRef, onCleanup) => {\n\t\tif (newRef) {\n\t\t\tconst carousel = new Carousel(newRef, {\n\t\t\t\tinterval: 0,\n\t\t\t\twrap: false\n\t\t\t});\n\n\t\t\tif (context.tab !== 0) {\n\t\t\t\tcarousel.to(context.tab);\n\t\t\t}\n\n\t\t\tnewRef.addEventListener(\"slid.bs.carousel\", handleSlid);\n\n\t\t\tonCleanup(() => {\n\t\t\t\tcarousel.dispose();\n\t\t\t\tnewRef.removeEventListener(\"slid.bs.carousel\", handleSlid);\n\t\t\t});\n\t\t}\n\t});\n\n\tfunction handleSlid(e: Event) {\n\t\tconst event = e as Event & Carousel.Event;\n\t\tcontext.tab = event.to;\n\t}\n\n\treturn readonly(context);\n}","import { addClickListener } from \"facilmap-leaflet\";\nimport type { ID, Point, Type } from \"facilmap-types\";\nimport type { ToastContext } from \"../components/ui/toasts/toasts.vue\";\nimport type { FacilMapContext } from \"../components/facil-map-context-provider/facil-map-context\";\nimport { requireClientContext, requireMapContext } from \"../components/facil-map-context-provider/facil-map-context-provider.vue\";\nimport { addToMap } from \"./add\";\nimport { formatTypeName } from \"facilmap-utils\";\nimport { getI18n } from \"./i18n\";\nimport { reactive, ref, toRef } from \"vue\";\n\nexport function drawMarker(type: Type, context: FacilMapContext, toasts: ToastContext): void {\n\tconst mapContext = requireMapContext(context);\n\n\tconst isSaving = ref(false);\n\n\tconst create = async (point: Point | undefined) => {\n\t\ttry {\n\t\t\tif (point) {\n\t\t\t\tisSaving.value = true;\n\t\t\t\tconst selection = await addToMap(context, [\n\t\t\t\t\t{ marker: { lat: point.lat, lon: point.lon }, type }\n\t\t\t\t]);\n\n\t\t\t\tmapContext.value.components.selectionHandler.setSelectedItems(selection, true);\n\t\t\t}\n\t\t\ttoasts.hideToast(\"fm-draw-add-marker\");\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(\"fm-draw-add-marker\", () => getI18n().t(\"draw.add-marker-error\"), err);\n\t\t}\n\t};\n\n\tconst clickListener = addClickListener(mapContext.value.components.map, async (point) => {\n\t\tawait create(point);\n\t});\n\n\ttoasts.showToast(\"fm-draw-add-marker\", () => getI18n().t(\"draw.add-marker-title\", { typeName: formatTypeName(type.name) }), () => getI18n().t(\"draw.add-marker-message\"), reactive({\n\t\tnoCloseButton: true,\n\t\tactions: toRef(() => [\n\t\t\t...mapContext.value.location ? [{\n\t\t\t\tlabel: getI18n().t(\"draw.add-marker-current\"),\n\t\t\t\tonClick: () => {\n\t\t\t\t\tclickListener.cancel();\n\t\t\t\t\tvoid create(mapContext.value.location!);\n\t\t\t\t},\n\t\t\t\tisDisabled: isSaving.value\n\t\t\t}] : [],\n\t\t\t{\n\t\t\t\tlabel: getI18n().t(\"draw.add-marker-cancel\"),\n\t\t\t\tonClick: () => {\n\t\t\t\t\tclickListener.cancel();\n\t\t\t\t},\n\t\t\t\tisDisabled: isSaving.value\n\t\t\t}\n\t\t]),\n\t\tspinner: isSaving\n\t}));\n}\n\nexport function moveMarker(markerId: ID, context: FacilMapContext, toasts: ToastContext): void {\n\tconst mapContext = requireMapContext(context);\n\tconst client = requireClientContext(context);\n\n\tconst markerLayer = mapContext.value.components.markersLayer.getLayerByMarkerId(markerId);\n\tif(!markerLayer)\n\t\treturn;\n\n\ttoasts.hideToast(\"fm-draw-drag-marker\");\n\n\tmapContext.value.components.map.fire('fmInteractionStart');\n\tmapContext.value.components.markersLayer.lockMarker(markerId);\n\n\tconst isSaving = ref(false);\n\n\tconst finish = async (pos: Point | undefined) => {\n\t\tmarkerLayer.dragging!.disable();\n\n\t\ttry {\n\t\t\tif(pos) {\n\t\t\t\tisSaving.value = true;\n\t\t\t\tawait client.value.editMarker({ id: markerId, lat: pos.lat, lon: pos.lon });\n\t\t\t}\n\n\t\t\ttoasts.hideToast(\"fm-draw-drag-marker\");\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(\"fm-draw-drag-marker\", () => getI18n().t(\"draw.move-marker-error\"), err);\n\t\t}\n\n\t\tmapContext.value.components.markersLayer.unlockMarker(markerId);\n\t\tmapContext.value.components.map.fire('fmInteractionEnd');\n\t};\n\n\ttoasts.showToast(\"fm-draw-drag-marker\", () => getI18n().t(\"draw.move-marker-title\"), getI18n().t(\"draw.move-marker-message\"), reactive({\n\t\tnoCloseButton: true,\n\t\tactions: toRef(() => [\n\t\t\t{\n\t\t\t\tlabel: getI18n().t(\"draw.move-marker-save\"),\n\t\t\t\tvariant: \"primary\" as const,\n\t\t\t\tonClick: () => {\n\t\t\t\t\tconst pos = markerLayer.getLatLng()\n\t\t\t\t\tvoid finish({ lat: pos.lat, lon: pos.lng });\n\t\t\t\t},\n\t\t\t\tisPending: isSaving.value,\n\t\t\t\tisDisabled: isSaving.value\n\t\t\t},\n\t\t\t...mapContext.value.location ? [{\n\t\t\t\tlabel: getI18n().t(\"draw.move-marker-current\"),\n\t\t\t\tonClick: () => {\n\t\t\t\t\tvoid finish(mapContext.value.location);\n\t\t\t\t},\n\t\t\t\tisDisabled: isSaving.value\n\t\t\t}] : [],\n\t\t\t{\n\t\t\t\tlabel: getI18n().t(\"draw.move-marker-cancel\"),\n\t\t\t\tonClick: () => {\n\t\t\t\t\tvoid finish(undefined);\n\t\t\t\t},\n\t\t\t\tisDisabled: isSaving.value\n\t\t\t}\n\t\t])\n\t}));\n\n\tmarkerLayer.dragging!.enable();\n}\n\nexport async function drawLine(type: Type, context: FacilMapContext, toasts: ToastContext): Promise<void> {\n\ttry {\n\t\ttoasts.hideToast(\"fm-draw-add-line\");\n\n\t\tconst mapContext = requireMapContext(context);\n\t\tconst client = requireClientContext(context);\n\n\t\tconst lineTemplate = await client.value.getLineTemplate({ typeId: type.id });\n\n\t\tconst isDisabled = ref(true);\n\t\tconst isSaving = ref(false);\n\t\ttoasts.showToast(\"fm-draw-add-line\", () => getI18n().t(\"draw.add-line-title\", { typeName: formatTypeName(type.name) }), () => getI18n().t(\"draw.add-line-message\"), reactive({\n\t\t\tnoCloseButton: true,\n\t\t\tactions: toRef(() => [\n\t\t\t\t{\n\t\t\t\t\tlabel: getI18n().t(\"draw.add-line-finish\"),\n\t\t\t\t\tvariant: \"primary\" as const,\n\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\tmapContext.value.components.linesLayer.endDrawLine(true);\n\t\t\t\t\t},\n\t\t\t\t\tisDisabled: isDisabled.value || isSaving.value,\n\t\t\t\t\tisPending: isSaving.value\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: getI18n().t(\"draw.add-line-cancel\"),\n\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\tmapContext.value.components.linesLayer.endDrawLine(false);\n\t\t\t\t\t},\n\t\t\t\t\tisDisabled: isSaving.value\n\t\t\t\t}\n\t\t\t])\n\t\t}));\n\n\t\tconst routePoints = await mapContext.value.components.linesLayer.drawLine(lineTemplate, (point, points) => {\n\t\t\tisDisabled.value = points.length < 2;\n\t\t});\n\n\t\ttry {\n\t\t\tif (routePoints) {\n\t\t\t\tisSaving.value = true;\n\n\t\t\t\tconst selection = await addToMap(context, [\n\t\t\t\t\t{ line: { routePoints }, type }\n\t\t\t\t]);\n\t\t\t\tmapContext.value.components.selectionHandler.setSelectedItems(selection, true);\n\t\t\t}\n\t\t} finally {\n\t\t\ttoasts.hideToast(\"fm-draw-add-line\");\n\t\t}\n\t} catch (err) {\n\t\ttoasts.showErrorToast(\"fm-draw-add-line\", getI18n().t(\"draw.add-line-error\"), err);\n\t}\n}","import type { Feature, Geometry } from \"geojson\";\nimport type { GeoJsonExport, LineFeature, MarkerFeature, SearchResult } from \"facilmap-types\";\nimport { flattenObject } from \"facilmap-utils\";\nimport { getI18n } from \"./i18n\";\n\ntype FmFeatureProperties = Partial<MarkerFeature[\"properties\"]> | Partial<LineFeature[\"properties\"]>;\ntype FeatureProperties = FmFeatureProperties & {\n\ttags?: Record<string, string>; // Tags for OSM objects\n\ttype?: string;\n\tid?: string;\n}\n\nexport type FileResult = SearchResult & {\n\tisFileResult: true;\n\tfmTypeId?: number;\n\tfmProperties?: FmFeatureProperties;\n}\n\nexport interface FileResultObject {\n\tfeatures: FileResult[];\n\tviews: GeoJsonExport[\"facilmap\"][\"views\"];\n\ttypes: GeoJsonExport[\"facilmap\"][\"types\"];\n\terrors: boolean;\n}\n\nasync function fileToGeoJSON(file: string): Promise<any> {\n\tif(file.match(/^\\s*</)) {\n\t\tconst doc = (new window.DOMParser()).parseFromString(file, \"text/xml\");\n\t\tconst parserErrorElem = doc.getElementsByTagName(\"parsererror\")[0];\n\t\tif (parserErrorElem) {\n\t\t\tthrow new Error(getI18n().t(\"files.invalid-xml-error\", { textContent: parserErrorElem.textContent }));\n\t\t}\n\n\t\tconst xml = doc.documentElement;\n\n\t\tif (xml.matches(\"gpx\")) {\n\t\t\tconst { gpx } = await import(\"@tmcw/togeojson\");\n\t\t\treturn gpx(xml);\n\t\t} else if (xml.matches(\"kml\")) {\n\t\t\tconst { kml } = await import(\"@tmcw/togeojson\");\n\t\t\treturn kml(xml);\n\t\t} else if (xml.matches(\"osm\")) {\n\t\t\tconst { default: osmtogeojson } = await import(\"osmtogeojson\");\n\t\t\treturn osmtogeojson(xml);\n\t\t} else if (xml.matches(\"TrainingCenterDatabase\")) {\n\t\t\tconst { tcx } = await import(\"@tmcw/togeojson\");\n\t\t\treturn tcx(xml);\n\t\t}\n\t} else if(file.match(/^\\s*\\{/)) {\n\t\tconst content = JSON.parse(file);\n\t\tif(content.type)\n\t\t\treturn content;\n\t}\n}\n\nexport async function parseFiles(files: string[]): Promise<FileResultObject> {\n\tconst filesGeoJSON = await Promise.all(files.map(fileToGeoJSON));\n\n\tconst ret: FileResultObject = { features: [ ], views: [ ], types: { }, errors: false };\n\tlet nextTypeIdx = 1;\n\n\tfor (const geojson of filesGeoJSON) {\n\t\tif(geojson == null) {\n\t\t\tret.errors = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst typeMapping: Record<string, number> = {};\n\n\t\tif (geojson.facilmap) {\n\t\t\tif (geojson.facilmap.types) {\n\t\t\t\tfor (const i of Object.keys(geojson.facilmap.types)) {\n\t\t\t\t\ttypeMapping[i] = nextTypeIdx++;\n\t\t\t\t\tret.types[typeMapping[i]] = geojson.facilmap.types[i];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(geojson.facilmap.views)\n\t\t\t\tret.views.push(...geojson.facilmap.views);\n\t\t}\n\n\t\tlet features: Feature<Geometry, FeatureProperties>[];\n\t\tif(geojson.type == \"FeatureCollection\")\n\t\t\tfeatures = geojson.features || [ ];\n\t\telse if(geojson.type == \"Feature\")\n\t\t\tfeatures = [ geojson ];\n\t\telse\n\t\t\tfeatures = [ { type: \"Feature\", geometry: geojson, properties: { } } ];\n\n\t\tfor (const feature of features) {\n\t\t\tlet name;\n\n\t\t\tif(typeof feature.properties != \"object\")\n\t\t\t\tfeature.properties = { };\n\n\t\t\tif(feature.properties.name)\n\t\t\t\tname = feature.properties.name;\n\t\t\telse if(feature.properties.tags && feature.properties.tags.name)\n\t\t\t\tname = feature.properties.tags.name;\n\t\t\telse if(feature.properties.type)\n\t\t\t\tname = feature.properties.type + \" \" + feature.properties.id;\n\t\t\telse if([ \"Polygon\", \"MultiPolygon\" ].indexOf(feature.geometry.type) != -1)\n\t\t\t\tname = \"Polygon\";\n\t\t\telse if([ \"LineString\", \"MultiLineString\" ].indexOf(feature.geometry.type) != -1)\n\t\t\t\tname = \"Line\";\n\t\t\telse if([ \"Point\", \"MultiPoint\" ].indexOf(feature.geometry.type) != -1)\n\t\t\t\tname = \"Point\";\n\t\t\telse\n\t\t\t\tname = feature.geometry.type || \"Object\";\n\n\t\t\tconst extraTags = feature.properties.data || feature.properties.tags || flattenObject(Object.assign({}, feature.properties, {coordTimes: null}));\n\n\t\t\tlet f: FileResult = {\n\t\t\t\tisFileResult: true,\n\t\t\t\tshort_name: name,\n\t\t\t\tdisplay_name: name,\n\t\t\t\textratags: Object.fromEntries(Object.entries(extraTags).map(([k, v]) => [k, `${v}`])),\n\t\t\t\tgeojson: feature.geometry,\n\t\t\t\ttype: feature.properties.type || feature.geometry.type\n\t\t\t};\n\n\t\t\tif(geojson.facilmap) {\n\t\t\t\tif(feature.properties.typeId && typeMapping[feature.properties.typeId])\n\t\t\t\t\tf.fmTypeId = typeMapping[feature.properties.typeId];\n\t\t\t\tf.fmProperties = feature.properties;\n\t\t\t}\n\n\t\t\tret.features.push(f);\n\t\t}\n\t}\n\n\treturn ret;\n}","import \"leaflet.heightgraph\";\nimport { Control, Polyline } from \"leaflet\";\nimport \"leaflet.heightgraph/src/L.Control.Heightgraph.css\";\nimport \"./heightgraph.scss\";\nimport type { TrackPoints } from \"facilmap-client\";\nimport { type ExtraInfo, type TrackPoint } from \"facilmap-types\";\nimport type { FeatureCollection } from \"geojson\";\nimport { calculateDistance, formatDistance, formatElevation, getCurrentUnits } from \"facilmap-utils\";\nimport { getI18n } from \"./i18n\";\n\nfunction trackSegment(trackPoints: TrackPoints, fromIdx: number, toIdx: number): TrackPoint[] {\n\tlet ret: TrackPoint[] = [];\n\n\tfor(let i=fromIdx; i<trackPoints.length; i++) {\n\t\tif(trackPoints[i] && trackPoints[i].ele != null) {\n\t\t\tret.push(trackPoints[i]);\n\n\t\t\tif(i >= toIdx) // Makes sure that if toIdx does not exist in trackPoints, the next trackPoint is added, which avoids gaps between the segments, as required by leaflet.heightgraph\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ret;\n}\n\ntype Collection = FeatureCollection & {\n\tproperties: {\n\t\tsummary: string;\n\t\tdistances: Record<number, number>;\n\t};\n}\n\nfunction createGeoJsonForHeightGraph(extraInfo: ExtraInfo | undefined, trackPoints: TrackPoints): Collection[] {\n\tconst geojson: Collection[] = [];\n\n\tif(!extraInfo || Object.keys(extraInfo).length == 0)\n\t\textraInfo = { \"\": [[ 0, trackPoints.length-1, \"\" as any ]] };\n\n\tfor(const i of Object.keys(extraInfo)) {\n\t\tlet featureCollection: Collection = {\n\t\t\ttype: \"FeatureCollection\",\n\t\t\tfeatures: [],\n\t\t\tproperties: {\n\t\t\t\tsummary: i,\n\t\t\t\tdistances: {}\n\t\t\t}\n\t\t};\n\n\t\tconst distances = featureCollection.properties.distances;\n\n\t\tfor(let segment in extraInfo[i]) {\n\t\t\tconst segmentPosList = trackSegment(trackPoints, extraInfo[i][segment][0], extraInfo[i][segment][1]);\n\n\t\t\tif (distances[extraInfo[i][segment][2]] == null)\n\t\t\t\tdistances[extraInfo[i][segment][2]] = 0;\n\t\t\tdistances[extraInfo[i][segment][2]] += calculateDistance(segmentPosList);\n\n\t\t\tfeatureCollection.features.push({\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"LineString\",\n\t\t\t\t\tcoordinates: segmentPosList.map((trackPoint) => ([trackPoint.lon, trackPoint.lat, ...(trackPoint.ele != null ? [trackPoint.ele] : [])]))\n\t\t\t\t},\n\t\t\t\tproperties: {\n\t\t\t\t\tattributeType: extraInfo[i][segment][2]\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tgeojson.push(featureCollection);\n\t}\n\treturn geojson;\n}\n\nfunction getDistancesByInfoType(extraInfo: ExtraInfo[string] | undefined, trackPoints: TrackPoints): Record<number, number> {\n\tconst ret: Record<number, number> = { };\n\n\tif (!extraInfo)\n\t\treturn ret;\n\n\tfor(let segment in extraInfo) {\n\t\tif (ret[extraInfo[segment][2]] == null)\n\t\t\tret[extraInfo[segment][2]] = 0;\n\n\t\tret[extraInfo[segment][2]] += calculateDistance(trackSegment(trackPoints, extraInfo[segment][0], extraInfo[segment][1]));\n\t}\n\n\treturn ret;\n}\n\nexport function createElevationStats(extraInfo: ExtraInfo | undefined, trackPoints: TrackPoints): Record<number, number> | null {\n\tif (!extraInfo || !extraInfo.steepness)\n\t\treturn null;\n\n\tconst stats = getDistancesByInfoType(extraInfo.steepness, trackPoints);\n\n\tconst sum = (filter: (i: number) => boolean): number => Object.keys(stats).map((i) => parseInt(i, 10)).filter(filter).reduce((acc, cur) => acc + stats[cur], 0);\n\n\treturn {\n\t\t\"-16\": sum((i) => (i <= -5)),\n\t\t\"-10\": sum((i) => (i <= -4)),\n\t\t\"-7\": sum((i) => (i <= -3)),\n\t\t\"-4\": sum((i) => (i <= -2)),\n\t\t\"-1\": sum((i) => (i <= -1)),\n\t\t\"0\": sum((i) => (i == 0)),\n\t\t\"1\": sum((i) => (i >= 1)),\n\t\t\"4\": sum((i) => (i >= 2)),\n\t\t\"7\": sum((i) => (i >= 3)),\n\t\t\"10\": sum((i) => (i >= 4)),\n\t\t\"16\": sum((i) => (i >= 5))\n\t};\n}\n\nexport default class FmHeightgraph extends Control.Heightgraph {\n\tprivate translatedMapping: Record<\"steepness\" | \"waytypes\" | \"surface\" | \"suitablity\" | \"green\" | \"noise\" | \"tollways\" | \"avgspeed\" | \"traildifficulty\" | \"roadaccessrestrictions\", string>;\n\n\tconstructor(options?: any) {\n\t\t// Consume current units in constructor to mark it as a reactive dependency\n\t\tgetCurrentUnits();\n\n\t\tconst i18n = getI18n();\n\t\tconst translatedMapping: typeof FmHeightgraph[\"translatedMapping\"] = {\n\t\t\tsteepness: i18n.t(\"heightgraph.steepness\"),\n\t\t\twaytypes: i18n.t(\"heightgraph.waytypes\"),\n\t\t\tsurface: i18n.t(\"heightgraph.surface\"),\n\t\t\tsuitablity: i18n.t(\"heightgraph.suitability\"),\n\t\t\tgreen: i18n.t(\"heightgraph.green\"),\n\t\t\tnoise: i18n.t(\"heightgraph.noise\"),\n\t\t\ttollways: i18n.t(\"heightgraph.tollways\"),\n\t\t\tavgspeed: i18n.t(\"heightgraph.avgspeed\"),\n\t\t\ttraildifficulty: i18n.t(\"heightgraph.traildifficulty\"),\n\t\t\troadaccessrestrictions: i18n.t(\"heightgraph.roadaccessrestrictions\")\n\t\t};\n\n\t\tsuper({\n\t\t\tmargins: {\n\t\t\t\ttop: 20,\n\t\t\t\tright: 10,\n\t\t\t\tbottom: 45,\n\t\t\t\tleft: 50\n\t\t\t},\n\t\t\ttranslation: {\n\t\t\t\tdistance: i18n.t(\"heightgraph.distance\"),\n\t\t\t\televation: i18n.t(\"heightgraph.elevation\"),\n\t\t\t\tsegment_length: i18n.t(\"heightgraph.segment-length\"),\n\t\t\t\ttype: i18n.t(\"heightgraph.type\"),\n\t\t\t\tlegend: i18n.t(\"heightgraph.legend\")\n\t\t\t},\n\t\t\tmappings: {\n\t\t\t\t\"\": {\n\t\t\t\t\t\"\": { text: i18n.t(\"heightgraph.unknown\"), color: '#4682B4' }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.steepness]: {\n\t\t\t\t\t\"-5\": { text: \"−16 % +\", color: \"#028306\" },\n\t\t\t\t\t\"-4\": { text: \"−10–15 %\", color: \"#2AA12E\" },\n\t\t\t\t\t\"-3\": { text: \"−7–9 %\", color: \"#53BF56\" },\n\t\t\t\t\t\"-2\": { text: \"−4–6 %\", color: \"#7BDD7E\" },\n\t\t\t\t\t\"-1\": { text: \"−1–3 %\", color: \"#A4FBA6\" },\n\t\t\t\t\t\"0\": { text: \"0 %\", color: \"#ffcc99\" },\n\t\t\t\t\t\"1\": { text: \"1–3 %\", color: \"#F29898\" },\n\t\t\t\t\t\"2\": { text: \"4–6 %\", color: \"#E07575\" },\n\t\t\t\t\t\"3\": { text: \"7–9 %\", color: \"#CF5352\" },\n\t\t\t\t\t\"4\": { text: \"10–15 %\", color: \"#BE312F\" },\n\t\t\t\t\t\"5\": { text: \"16 % +\", color: \"#AD0F0C\" }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.waytypes]: {\n\t\t\t\t\t\"0\": { text: i18n.t(\"heightgraph.waytype-other\"), color: \"#30959e\" },\n\t\t\t\t\t\"1\": { text: i18n.t(\"heightgraph.waytype-state-road\"), color: \"#3f9da6\" },\n\t\t\t\t\t\"2\": { text: i18n.t(\"heightgraph.waytype-road\"), color: \"#4ea5ae\" },\n\t\t\t\t\t\"3\": { text: i18n.t(\"heightgraph.waytype-street\"), color: \"#5baeb5\" },\n\t\t\t\t\t\"4\": { text: i18n.t(\"heightgraph.waytype-path\"), color: \"#67b5bd\" },\n\t\t\t\t\t\"5\": { text: i18n.t(\"heightgraph.waytype-track\"), color: \"#73bdc4\" },\n\t\t\t\t\t\"6\": { text: i18n.t(\"heightgraph.waytype-cycleway\"), color: \"#7fc7cd\" },\n\t\t\t\t\t\"7\": { text: i18n.t(\"heightgraph.waytype-footway\"), color: \"#8acfd5\" },\n\t\t\t\t\t\"8\": { text: i18n.t(\"heightgraph.waytype-steps\"), color: \"#96d7dc\" },\n\t\t\t\t\t\"9\": { text: i18n.t(\"heightgraph.waytype-ferry\"), color: \"#a2dfe5\" },\n\t\t\t\t\t\"10\": { text: i18n.t(\"heightgraph.waytype-construction\"), color: \"#ade8ed\" }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.surface]: {\n\t\t\t\t\t\"0\": { text: i18n.t(\"heightgraph.surface-other\"), color: \"#ddcdeb\" },\n\t\t\t\t\t\"1\": { text: i18n.t(\"heightgraph.surface-paved\"), color: \"#cdb8df\" },\n\t\t\t\t\t\"2\": { text: i18n.t(\"heightgraph.surface-unpaved\"), color: \"#d2c0e3\" },\n\t\t\t\t\t\"3\": { text: i18n.t(\"heightgraph.surface-asphalt\"), color: \"#bca4d3\" },\n\t\t\t\t\t\"4\": { text: i18n.t(\"heightgraph.surface-contrete\"), color: \"#c1abd7\" },\n\t\t\t\t\t\"5\": { text: i18n.t(\"heightgraph.surface-cobblestone\"), color: \"#c7b2db\" },\n\t\t\t\t\t\"6\": { text: i18n.t(\"heightgraph.surface-metal\"), color: \"#e8dcf3\" },\n\t\t\t\t\t\"7\": { text: i18n.t(\"heightgraph.surface-wood\"), color: \"#eee3f7\" },\n\t\t\t\t\t\"8\": { text: i18n.t(\"heightgraph.surface-compacted-gravel\"), color: \"#d8c6e7\" },\n\t\t\t\t\t\"9\": { text: i18n.t(\"heightgraph.surface-fine-gravel\"), color: \"#8f9de4\" },\n\t\t\t\t\t\"10\": { text: i18n.t(\"heightgraph.surface-gravel\"), color: \"#e3d4ef\" },\n\t\t\t\t\t\"11\": { text: i18n.t(\"heightgraph.surface-dirt\"), color: \"#99a6e7\" },\n\t\t\t\t\t\"12\": { text: i18n.t(\"heightgraph.surface-ground\"), color: \"#a3aeeb\" },\n\t\t\t\t\t\"13\": { text: i18n.t(\"heightgraph.surface-ice\"), color: \"#acb6ee\" },\n\t\t\t\t\t\"14\": { text: i18n.t(\"heightgraph.surface-paving-stones\"), color: \"#b6c0f2\" },\n\t\t\t\t\t\"15\": { text: i18n.t(\"heightgraph.surface-sand\"), color: \"#c9d1f8\" },\n\t\t\t\t\t\"16\": { text: i18n.t(\"heightgraph.surface-woodchips\"), color: \"#c0c8f5\" },\n\t\t\t\t\t\"17\": { text: i18n.t(\"heightgraph.surface-grass\"), color: \"#d2dafc\" },\n\t\t\t\t\t\"18\": { text: i18n.t(\"heightgraph.surface-grass-paver\"), color: \"#dbe3ff\" }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.suitability]: {\n\t\t\t\t\t\"3\": { text: \"3/10\", color: \"#3D3D3D\" },\n\t\t\t\t\t\"4\": { text: \"4/10\", color: \"#4D4D4D\" },\n\t\t\t\t\t\"5\": { text: \"5/10\", color: \"#5D5D5D\" },\n\t\t\t\t\t\"6\": { text: \"6/10\", color: \"#6D6D6D\" },\n\t\t\t\t\t\"7\": { text: \"7/10\", color: \"#7C7C7C\" },\n\t\t\t\t\t\"8\": { text: \"8/10\", color: \"#8D8D8D\" },\n\t\t\t\t\t\"9\": { text: \"9/10\", color: \"#9D9D9D\" },\n\t\t\t\t\t\"10\": { text: \"10/10\", color: \"#ADADAD\" }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.green]: {\n\t\t\t\t\t\"3\": { text: \"10/10\", color: \"#8ec639\" },\n\t\t\t\t\t\"4\": { text: \"9/10\", color: \"#99c93c\" },\n\t\t\t\t\t\"5\": { text: \"8/10\", color: \"#a4cc40\" },\n\t\t\t\t\t\"6\": { text: \"7/10\", color: \"#afcf43\" },\n\t\t\t\t\t\"7\": { text: \"6/10\", color: \"#bbd246\" },\n\t\t\t\t\t\"8\": { text: \"5/10\", color: \"#c6d54a\" },\n\t\t\t\t\t\"9\": { text: \"4/10\", color: \"#d1d84e\" },\n\t\t\t\t\t\"10\": { text: \"3/10\", color: \"#dcdc51\" }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.noise]: {\n\t\t\t\t\t\"7\": { text: \"7/10\", color: \"#F8A056\" },\n\t\t\t\t\t\"8\": { text: \"8/10\", color: \"#EA7F27\" },\n\t\t\t\t\t\"9\": { text: \"9/10\", color: \"#A04900\" },\n\t\t\t\t\t\"10\": { text: \"10/10\", color: \"#773600\" }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.tollways]: {\n\t\t\t\t\t\"0\": { text: i18n.t(\"heightgraph.tollway-no\"), color: \"#6ca97b\" },\n\t\t\t\t\t\"1\": { text: i18n.t(\"heightgraph.tollway-yes\"), color: \"#ffb347\" }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.avgspeed]: {\n\t\t\t\t\t// TODO: Make these available in miles\n\t\t\t\t\t\"3\": { text: \"3 km/h\", color: \"#f2fdff\" },\n\t\t\t\t\t\"4\": { text: \"4 km/h\", color: \"#D8FAFF\" },\n\t\t\t\t\t\"5\": { text: \"5 km/h\", color: \"bff7ff\" },\n\t\t\t\t\t\"6\": { text: \"6–8 km/h\", color: \"#f2f7ff\" },\n\t\t\t\t\t\"9\": { text: \"9–12 km/h\", color: \"#d8e9ff\" },\n\t\t\t\t\t\"13\": { text: \"13–16 km/h\", color: \"#bedaff\" },\n\t\t\t\t\t\"17\": { text: \"17–20 km/h\", color: \"#a5cbff\" },\n\t\t\t\t\t\"21\": { text: \"21–24 km/h\", color: \"#8cbcff\" },\n\t\t\t\t\t\"25\": { text: \"25–29 km/h\", color: \"#72aeff\" },\n\t\t\t\t\t\"30\": { text: \"30–34 km/h\", color: \"#599fff\" },\n\t\t\t\t\t\"35\": { text: \"35–39 km/h\", color: \"#3f91ff\" },\n\t\t\t\t\t\"40\": { text: \"40–44 km/h\", color: \"#2682ff\" },\n\t\t\t\t\t\"45\": { text: \"45–49 km/h\", color: \"#0d73ff\" },\n\t\t\t\t\t\"50\": { text: \"50–59 km/h\", color: \"#0067f2\" },\n\t\t\t\t\t\"60\": { text: \"60–69 km/h\", color: \"#005cd9\" },\n\t\t\t\t\t\"70\": { text: \"70–79 km/h\", color: \"#0051c0\" },\n\t\t\t\t\t\"80\": { text: \"80–99 km/h\", color: \"#0046a6\" },\n\t\t\t\t\t\"100\": { text: \"100–119 km/h\", color: \"#003c8d\" },\n\t\t\t\t\t\"120\": { text: \"+120 km/h\", color: \"#003174\" }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.traildifficulty]: {\n\t\t\t\t\t\"0\": { text: i18n.t(\"heightgraph.traildifficulty-unknown\"), color: \"#dfecec\" },\n\t\t\t\t\t\"1\": { text: \"S0\", color: \"#9fc6c6\" },\n\t\t\t\t\t\"2\": { text: \"S1\", color: \"#80b3b3\" },\n\t\t\t\t\t\"3\": { text: \"S2\", color: \"#609f9f\" },\n\t\t\t\t\t\"4\": { text: \"S3\", color: \"#4d8080\" },\n\t\t\t\t\t\"5\": { text: \"S4\", color: \"#396060\" },\n\t\t\t\t\t\"6\": { text: \"S5\", color: \"#264040\" },\n\t\t\t\t\t\"7\": { text: \">S5\", color: \"#132020\" }\n\t\t\t\t},\n\t\t\t\t[translatedMapping.roadaccessrestrictions]: {\n\t\t\t\t\t\"0\": { text: i18n.t(\"heightgraph.access-yes\"), color: \"#fe7f6c\" },\n\t\t\t\t\t\"1\": { text: i18n.t(\"heightgraph.access-no\"), color: \"#FE7F9C\" },\n\t\t\t\t\t\"2\": { text: i18n.t(\"heightgraph.access-customers\"), color: \"#FDAB9F\" },\n\t\t\t\t\t\"4\": { text: i18n.t(\"heightgraph.access-destination\"), color: \"#FF66CC\" },\n\t\t\t\t\t\"8\": { text: i18n.t(\"heightgraph.access-delivery\"), color: \"#FDB9C8\" },\n\t\t\t\t\t\"16\": { text: i18n.t(\"heightgraph.access-private\"), color: \"#F64A8A\" },\n\t\t\t\t\t\"32\": { text: i18n.t(\"heightgraph.access-permissive\"), color: \"#E0115F\" }\n\t\t\t\t}\n\t\t\t},\n\t\t\t...options\n\t\t});\n\n\t\tthis.translatedMapping = translatedMapping;\n\t}\n\n\taddData(extraInfo: ExtraInfo | undefined, trackPoints: TrackPoints): void {\n\t\tconst translatedExtraInfo = extraInfo && Object.fromEntries(Object.entries(extraInfo).map(([k, v]) => [(this.translatedMapping as any)[k] ?? k, v]));\n\n\t\tconst data = createGeoJsonForHeightGraph(translatedExtraInfo, trackPoints);\n\n\t\tif(this._container)\n\t\t\tsuper.addData(data);\n\t\telse\n\t\t\tthis._data = data;\n\t}\n\n\t_internalMousemoveHandler(...args: any[]): void {\n\t\tsuper._internalMousemoveHandler(...args);\n\n\t\t// Hack: Replace distance, elevation, segment length kilometers/meters with configured unit\n\t\tconst dist = this._distTspan.text().match(/(\\d+(\\.\\d+)) km/);\n\t\tif (dist) {\n\t\t\tthis._distTspan.text(` ${formatDistance(Number(dist[1]))}`);\n\t\t}\n\t\tconst alt = this._altTspan.text().match(/(\\d+(\\.\\d+)) m/);\n\t\tif (alt) {\n\t\t\tthis._altTspan.text(` ${formatElevation(Number(alt[1]))}`);\n\t\t}\n\t\tconst area = this._areaTspan.text().match(/(\\d+(\\.\\d+)) km/);\n\t\tif (area) {\n\t\t\tthis._areaTspan.text(` ${formatDistance(Number(area[1]))}`);\n\t\t}\n\t}\n\n\t_appendScales(): void {\n\t\tsuper._appendScales();\n\n\t\t// Hack: Replace distance/elevation kilometers/meters in x/y axis labels with configured unit.\n\t\t// Steps are still according to round numbers of kilometers/meters, but at least the units are right.\n\t\tthis._xAxis.tickFormat((d: number) => formatDistance(d));\n\t\tthis._yAxis.tickFormat((d: number) => formatElevation(d));\n\t}\n\n\t_prepareData(): void {\n\t\tsuper._prepareData();\n\n\t\t// Hack: Append the total distance for each result type to the legend\n\t\tfor (let i = 0; i < this._categories.length; i++) {\n\t\t\tconst category = this._categories[i];\n\t\t\tconst featureCollection = this._data[i];\n\t\t\tcategory.legend = Object.fromEntries(Object.entries(category.legend).map(([k, v]: [any, any]) => [k, {\n\t\t\t\t...v,\n\t\t\t\ttext: getI18n().t(\"heightgraph.label-with-total\", { label: v.text, total: formatDistance(featureCollection.properties.distances[v.type]) })\n\t\t\t}]));\n\t\t}\n\t}\n\n\t_showMapMarker(...args: any[]): void {\n\t\t// Heightgraph renders the map marker (when hovering the heightgraph) to the hard-coded element .leaflet-overlay-pane svg\n\n\t\t// First, we need to initialize the renderer to make sure that the element is even there\n\t\tthis._map.getRenderer(new Polyline([], { pane: this.options.mapMarkerPane }));\n\n\t\t// Then, we temporarily change class names to make the desired pane (our custom option mapMarkerPane) match the hard-coded class name\n\t\tif (this.options.mapMarkerPane) {\n\t\t\tconst overlayPane = this._map.getPane(\"overlayPane\");\n\t\t\tconst overlayPaneClass = overlayPane.className;\n\t\t\tconst mapMarkerPane = this._map.getPane(this.options.mapMarkerPane);\n\t\t\tconst mapMarkerPaneClass = mapMarkerPane.className;\n\n\t\t\toverlayPane.classList.remove(\"leaflet-overlay-pane\");\n\t\t\tmapMarkerPane.classList.add(\"leaflet-overlay-pane\");\n\n\t\t\ttry {\n\t\t\t\tsuper._showMapMarker(...args);\n\t\t\t} finally {\n\t\t\t\toverlayPane.className = overlayPaneClass;\n\t\t\t\tmapMarkerPane.className = mapMarkerPaneClass;\n\t\t\t}\n\t\t} else {\n\t\t\tsuper._showMapMarker(...args);\n\t\t}\n\t}\n\n}","import Modal from \"bootstrap/js/dist/modal\";\nimport { type Ref, shallowRef, watchEffect, reactive, readonly, effectScope, onActivated, ref, onDeactivated } from \"vue\";\nimport { useMaxBreakpoint } from \"./bootstrap\";\nimport { fixOnCleanup } from \"./vue\";\n\nexport interface ModalConfig {\n\t/** Will be called when the fade-in animation has finished. */\n\tonShown?: (event: Modal.Event) => void;\n\t/** Will be called before the fade-out animation when the modal is closed. */\n\tonHide?: (event: Modal.Event) => void;\n\t/** Will be called after the fade-out animation when the modal is closed. */\n\tonHidden?: (event: Modal.Event) => void;\n\t/** If true, the modal can not be closed by clicking the backdrop. */\n\tstatic?: Ref<boolean>;\n\t/** If true, the modal can not be closed by pressing Escape. */\n\tnoEscape?: Ref<boolean>;\n}\n\nexport interface ModalActions {\n\thide: () => void;\n}\n\n/**\n * Enables a Bootstrap modal dialog on the element that is saved in the returned {@link ModalActions#ref}.\n */\nexport function useModal(modalRef: Ref<HTMLElement | undefined>, { onShown, onHide, onHidden, static: isStatic, noEscape }: ModalConfig): Readonly<ModalActions> {\n\tconst modal = shallowRef<Modal>();\n\tlet lastFocusedEl: Element | undefined;\n\n\tconst handleShown = (e: Event) => {\n\t\tconst focusEl = (\n\t\t\tmodalRef.value?.querySelector<HTMLElement>(\"[autofocus],.fm-autofocus\")\n\t\t\t?? modalRef.value?.querySelector<HTMLElement>(\"input:not([type=button]):not([type=hidden]):not([type=image]):not([type=reset]):not([type=submit]),textarea,select\")\n\t\t\t?? modalRef.value?.querySelector<HTMLElement>(\".modal-footer input[type=submit],.modal-footer button[type=submit]\")\n\t\t);\n\t\tfocusEl?.focus();\n\n\t\tonShown?.(e as Modal.Event);\n\t};\n\n\tconst handleHide = (e: Event) => {\n\t\tonHide?.(e as Modal.Event);\n\t};\n\n\tconst handleHidden = (e: Event) => {\n\t\tif (lastFocusedEl instanceof HTMLElement) {\n\t\t\tlastFocusedEl.focus();\n\t\t}\n\t\tonHidden?.(e as Modal.Event);\n\t};\n\n\tconst result = reactive<ModalActions>({\n\t\thide: () => {\n\t\t\tif (!modal.value) {\n\t\t\t\tthrow new Error('Modal is not initialized.');\n\t\t\t}\n\t\t\tmodal.value.hide();\n\t\t}\n\t});\n\n\tconst isActivated = ref(true);\n\tonActivated(() => {\n\t\tisActivated.value = true;\n\t});\n\tonDeactivated(() => {\n\t\tisActivated.value = false;\n\t});\n\n\twatchEffect((onCleanup_) => {\n\t\tconst onCleanup = fixOnCleanup(onCleanup_);\n\n\t\tif (modalRef.value && isActivated.value) {\n\t\t\tconst newRef = modalRef.value;\n\n\t\t\tif (!lastFocusedEl) {\n\t\t\t\tlastFocusedEl = document.activeElement ?? undefined;\n\t\t\t}\n\n\t\t\tmodal.value = new Modal(newRef);\n\t\t\tmodal.value.show();\n\n\t\t\tconst existingModals = [...document.querySelectorAll(\".modal\")].filter((el) => el !== newRef);\n\t\t\tconst zIndex = 1 + Math.max(1056, ...existingModals.map((el) => Number(getComputedStyle(el).zIndex) || -Infinity));\n\t\t\tnewRef.style.zIndex = `${zIndex}`;\n\t\t\t((modal.value as any)._backdrop._element as HTMLElement).style.zIndex = `${zIndex - 1}`;\n\n\t\t\tconst stackLevel = existingModals.length;\n\t\t\tconst content = newRef.querySelector<HTMLElement>(\".modal-dialog\");\n\t\t\tif (content) {\n\t\t\t\tconst scope = effectScope();\n\t\t\t\tscope.run(() => {\n\t\t\t\t\tconst isTight = useMaxBreakpoint(\"md\");\n\t\t\t\t\twatchEffect(() => {\n\t\t\t\t\t\tif (isTight.value) {\n\t\t\t\t\t\t\tcontent.style.padding = `calc(var(--bs-modal-margin) * ${stackLevel})`;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontent.style.padding = `${20*stackLevel}px ${40*stackLevel}px`;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\tonCleanup(() => {\n\t\t\t\t\tscope.stop();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tnewRef.addEventListener('shown.bs.modal', handleShown);\n\t\t\tnewRef.addEventListener('hide.bs.modal', handleHide);\n\t\t\tnewRef.addEventListener('hidden.bs.modal', handleHidden);\n\n\t\t\tonCleanup(() => {\n\t\t\t\tmodal.value!.dispose();\n\t\t\t\tmodal.value = undefined;\n\t\t\t\tnewRef.removeEventListener('shown.bs.modal', handleShown);\n\t\t\t\tnewRef.removeEventListener('hide.bs.modal', handleHide);\n\t\t\t\tnewRef.removeEventListener('hidden.bs.modal', handleHidden);\n\t\t\t});\n\t\t}\n\t});\n\n\twatchEffect(() => {\n\t\tif (modal.value) {\n\t\t\tconst config = (modal.value as any)._config as Modal.Options;\n\t\t\tconfig.backdrop = isStatic?.value ? \"static\" : true;\n\t\t\tconfig.keyboard = !noEscape?.value;\n\t\t}\n\t});\n\n\treturn readonly(result);\n}\n\nexport function hideAllModals(): void {\n\tfor(const el of [...document.querySelectorAll(\".modal\")]) {\n\t\tModal.getInstance(el)?.hide();\n\t}\n}\n","import type { ID, SearchResult } from \"facilmap-types\";\nimport { DomEvent, Evented, Handler, type LatLngBounds, type LeafletEvent, type Map, type Point, Polyline, Util } from \"leaflet\";\nimport { LinesLayer, MarkerLayer, MarkersLayer, type OverpassElement, OverpassLayer, SearchResultsLayer } from \"facilmap-leaflet\";\nimport BoxSelection from \"./box-selection\";\nimport type { DeepReadonly } from \"vue\";\n\nexport type SelectedItem = {\n\ttype: \"marker\" | \"line\";\n\tid: ID;\n} | {\n\ttype: \"searchResult\";\n\tresult: SearchResult;\n\tlayerId: number;\n} | {\n\ttype: \"overpass\";\n\telement: OverpassElement;\n};\n\nfunction isAllowedSibling(a: DeepReadonly<SelectedItem>, b: DeepReadonly<SelectedItem>) {\n\tif ([\"marker\", \"line\"].includes(a.type) && [\"marker\", \"line\"].includes(b.type))\n\t\treturn true;\n\telse if (a.type == \"searchResult\" && b.type == \"searchResult\")\n\t\treturn a.layerId == b.layerId;\n\telse if (a.type == \"overpass\" && b.type == \"overpass\")\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nfunction byType<T extends SelectedItem[\"type\"]>(items: Array<DeepReadonly<SelectedItem>>, type: T): Array<SelectedItem & { type: T }> {\n\treturn items.filter((i) => i.type === type) as any;\n}\n\nfunction isSame(a: DeepReadonly<SelectedItem>, b: DeepReadonly<SelectedItem>): boolean {\n\tif ((a.type == \"marker\" && b.type == \"marker\") || (a.type == \"line\" && b.type == \"line\"))\n\t\treturn a.id == b.id;\n\telse if (a.type == \"searchResult\" && b.type == \"searchResult\")\n\t\treturn a.result === b.result;\n\telse if (a.type == \"overpass\" && b.type == \"overpass\")\n\t\treturn a.element === b.element;\n\telse\n\t\treturn false;\n}\n\nexport default class SelectionHandler extends Handler {\n\n\t_selection: Array<DeepReadonly<SelectedItem>> = [];\n\n\t_markersLayer: MarkersLayer;\n\t_linesLayer: LinesLayer;\n\t_searchResultLayers: SearchResultsLayer[];\n\t_overpassLayer: OverpassLayer;\n\n\t_boxSelectionHandler: BoxSelection;\n\t_selectionBeforeBox: Array<DeepReadonly<SelectedItem>> = [];\n\t_isBoxInteraction = false;\n\n\t_mapInteraction: number = 0;\n\t_isLongClick: boolean = false;\n\n\tconstructor(map: Map, markersLayer: MarkersLayer, linesLayer: LinesLayer, searchResultsLayer: SearchResultsLayer, overpassLayer: OverpassLayer) {\n\t\tsuper(map);\n\n\t\tthis._boxSelectionHandler = new BoxSelection(map)\n\t\t\t.on(\"selectstart\", this.handleBoxSelectStart)\n\t\t\t.on(\"select\", this.handleBoxSelect)\n\t\t\t.on(\"selectend\", this.handleBoxSelectEnd);\n\n\t\tthis._markersLayer = markersLayer;\n\t\tthis._linesLayer = linesLayer;\n\t\tthis._searchResultLayers = [searchResultsLayer];\n\t\tthis._overpassLayer = overpassLayer;\n\t}\n\n\tenable(): this {\n\t\tsuper.enable();\n\t\tthis._boxSelectionHandler.enable();\n\t\treturn this;\n\t}\n\n\tdisable(): this {\n\t\tthis._boxSelectionHandler.disable();\n\t\tsuper.disable();\n\t\treturn this;\n\t}\n\n\taddHooks(): void {\n\t\tthis._markersLayer.on(\"click\", this.handleClickMarker);\n\t\tthis._linesLayer.on(\"click\", this.handleClickLine);\n\t\tfor (const layer of this._searchResultLayers)\n\t\t\tlayer.on(\"click\", this.handleClickSearchResult);\n\t\tthis._overpassLayer.on(\"click\", this.handleClickOverpass);\n\t\tthis._map.on(\"click\", this.handleClickMap);\n\t\tthis._map.on(\"fmInteractionStart\", this.handleMapInteractionStart);\n\t\tthis._map.on(\"fmInteractionEnd\", this.handleMapInteractionEnd);\n\n\t\tthis._map.getContainer().addEventListener(\"click\", this.handleMapClickCapture, { capture: true });\n\t\tthis._map.getContainer().addEventListener(\"mousedown\", this.handleMapMouseDown);\n\t\tthis._map.getContainer().addEventListener(\"touchstart\", this.handleMapMouseDown);\n\t}\n\n\tremoveHooks(): void {\n\t\tthis._markersLayer.off(\"click\", this.handleClickMarker);\n\t\tthis._linesLayer.off(\"click\", this.handleClickLine);\n\t\tfor (const layer of this._searchResultLayers)\n\t\t\tlayer.off(\"click\", this.handleClickSearchResult);\n\t\tthis._overpassLayer.off(\"click\", this.handleClickOverpass);\n\t\tthis._map.off(\"click\", this.handleClickMap);\n\t\tthis._map.off(\"fmInteractionStart\", this.handleMapInteractionStart);\n\t\tthis._map.off(\"fmInteractionEnd\", this.handleMapInteractionEnd);\n\t\tthis._map.getContainer().removeEventListener(\"click\", this.handleMapClickCapture, { capture: true });\n\t\tthis._map.getContainer().removeEventListener(\"mousedown\", this.handleMapMouseDown);\n\t\tthis._map.getContainer().removeEventListener(\"touchstart\", this.handleMapMouseDown);\n\t}\n\n\taddSearchResultLayer(layer: SearchResultsLayer): void {\n\t\tif (this._searchResultLayers.includes(layer))\n\t\t\treturn;\n\n\t\tif (this._enabled)\n\t\t\tlayer.on(\"click\", this.handleClickSearchResult);\n\n\t\tthis._searchResultLayers.push(layer);\n\t}\n\n\tremoveSearchResultLayer(layer: SearchResultsLayer): void {\n\t\tconst idx = this._searchResultLayers.indexOf(layer);\n\t\tif (idx == -1)\n\t\t\treturn;\n\n\t\tlayer.off(\"click\", this.handleClickSearchResult);\n\t\tthis._searchResultLayers.splice(idx, 1);\n\n\t\tconst layerId = Util.stamp(layer);\n\t\tconst without = this._selection.filter((item) => item.type != \"searchResult\" || item.layerId != layerId);\n\t\tif (without.length != this._selection.length)\n\t\t\tthis.setSelectedItems(without);\n\t}\n\n\tgetSelection(): Array<DeepReadonly<SelectedItem>> {\n\t\treturn this._selection;\n\t}\n\n\tsetSelectedItems(items: Array<DeepReadonly<SelectedItem>>, open = false): void {\n\t\tthis._selection = items;\n\n\t\tthis._markersLayer.setHighlightedMarkers(new Set(\n\t\t\tbyType(items, \"marker\").map((i) => i.id)\n\t\t));\n\t\tthis._linesLayer.setHighlightedLines(new Set(\n\t\t\tbyType(items, \"line\").map((i) => i.id)\n\t\t));\n\t\tfor (const layer of this._searchResultLayers) {\n\t\t\tconst layerId = Util.stamp(layer);\n\t\t\tlayer.setHighlightedResults(new Set(\n\t\t\t\tbyType(items, \"searchResult\").filter((i) => i.layerId == layerId).map((i) => i.result)\n\t\t\t));\n\t\t}\n\t\tthis._overpassLayer.setHighlightedElements(new Set(\n\t\t\tbyType(items, \"overpass\").map((i) => i.element)\n\t\t));\n\n\t\tthis.fire(\"fmChangeSelection\", { open });\n\t}\n\n\tisSelected(item: SelectedItem): boolean {\n\t\treturn this._selection.some((i) => isSame(i, item));\n\t}\n\n\tselectItem(item: SelectedItem, open = false): void {\n\t\tif (!this.isSelected(item))\n\t\t\tthis.setSelectedItems([...this._selection, item], open);\n\t\telse if (open)\n\t\t\tthis.fire(\"fmChangeSelection\", { open });\n\t}\n\n\tunselectItem(item: SelectedItem): void {\n\t\tthis.setSelectedItems(this._selection.filter((i) => !isSame(i, item)));\n\t}\n\n\ttoggleItem(item: SelectedItem, open = false): void {\n\t\tif (this.isSelected(item))\n\t\t\tthis.unselectItem(item);\n\t\telse if (!this._selection.some((i) => !isAllowedSibling(item, i)))\n\t\t\tthis.selectItem(item, open);\n\t}\n\n\thandleClickItem(item: SelectedItem, e: LeafletEvent): void {\n\t\tif (this._mapInteraction)\n\t\t\treturn;\n\n\t\tDomEvent.stopPropagation(e);\n\t\tif ((e.originalEvent as any).ctrlKey)\n\t\t\tthis.toggleItem(item, true);\n\t\telse\n\t\t\tthis.setSelectedItems([item], true);\n\t}\n\n\thandleClickMarker = (e: LeafletEvent): void => {\n\t\tif (e.propagatedFrom?.marker?.id)\n\t\t\tthis.handleClickItem({ type: \"marker\", id: e.propagatedFrom.marker.id }, e);\n\t}\n\n\thandleClickLine = (e: LeafletEvent): void => {\n\t\tif (e.propagatedFrom?.line?.id)\n\t\t\tthis.handleClickItem({ type: \"line\", id: e.propagatedFrom.line.id }, e);\n\t}\n\n\thandleClickSearchResult = (e: LeafletEvent): void => {\n\t\tif (e.propagatedFrom?._fmSearchResult)\n\t\t\tthis.handleClickItem({ type: \"searchResult\", result: e.propagatedFrom._fmSearchResult, layerId: Util.stamp(e.target) }, e);\n\t}\n\n\thandleClickOverpass = (e: LeafletEvent): void => {\n\t\tif (e.propagatedFrom?._fmOverpassElement)\n\t\t\tthis.handleClickItem({ type: \"overpass\", element: e.propagatedFrom._fmOverpassElement }, e);\n\t}\n\n\thandleClickMap = (e: LeafletEvent): void => {\n\t\tif (this._mapInteraction || this._isLongClick || this._isBoxInteraction)\n\t\t\treturn;\n\n\t\tif (!(e.originalEvent as any).ctrlKey)\n\t\t\tthis.setSelectedItems([]);\n\t}\n\n\thandleMapClickCapture = (e: MouseEvent): void => {\n\t\tif (this._isLongClick) {\n\t\t\t// Prevent click on map object under mouse cursor\n\t\t\te.stopPropagation();\n\t\t}\n\t}\n\n\thandleMapMouseDown = (e: MouseEvent | TouchEvent): void => {\n\t\tif (\"button\" in e && e.button != null && e.button != 0) // Only react to left click\n\t\t\treturn;\n\t\tif (\"touches\" in e && e.touches && e.touches.length != 1)\n\t\t\treturn;\n\t\tif (this._mapInteraction) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst pos: Point = this._map.mouseEventToContainerPoint((\"touches\" in e ? e.touches[0] : e) as any);\n\t\tlet fired = false;\n\t\tlet timeout = setTimeout(() => {\n\t\t\tthis._isLongClick = true;\n\t\t\tthis.fire(\"fmLongClick\", { latlng: this._map.mouseEventToLatLng((\"touches\" in e ? e.touches[0] : e) as any) });\n\t\t\tfired = true;\n\t\t}, 500);\n\n\t\tconst handleMouseMove = (e: any) => {\n\t\t\tif(pos.distanceTo(this._map.mouseEventToContainerPoint((\"touches\" in e ? e.touches[0] : e) as any)) > (this._map.dragging as any)._draggable.options.clickTolerance) {\n\t\t\t\tclear();\n\n\t\t\t\tif (fired) {\n\t\t\t\t\tthis.fire(\"fmLongClickAbort\");\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tconst handleContextMenu = (e: any) => {\n\t\t\tDomEvent.preventDefault(e);\n\t\t}\n\n\t\tconst clear = () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tthis._map.getContainer().removeEventListener(\"mousemove\", handleMouseMove);\n\t\t\tthis._map.getContainer().removeEventListener(\"touchmove\", handleMouseMove);\n\t\t\tthis._map.getContainer().removeEventListener(\"mouseup\", clear);\n\t\t\tthis._map.getContainer().removeEventListener(\"touchend\", clear);\n\t\t\tthis._map.getContainer().removeEventListener(\"contextmenu\", handleContextMenu);\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis._isLongClick = false;\n\t\t\t}, 0);\n\t\t}\n\n\t\tthis._map.getContainer().addEventListener(\"mousemove\", handleMouseMove);\n\t\tthis._map.getContainer().addEventListener(\"touchmove\", handleMouseMove);\n\t\tthis._map.getContainer().addEventListener(\"mouseup\", clear);\n\t\tthis._map.getContainer().addEventListener(\"touchend\", clear);\n\t\tthis._map.getContainer().addEventListener(\"contextmenu\", handleContextMenu);\n\t}\n\n\thandleMapInteractionStart = (): void => {\n\t\tthis._mapInteraction++;\n\t}\n\n\thandleMapInteractionEnd = (): void => {\n\t\tthis._mapInteraction--;\n\t}\n\n\thandleBoxSelectStart = (e: any): void => {\n\t\tthis._isBoxInteraction = true;\n\t\tthis._selectionBeforeBox = e.ctrlKey ? [...this._selection] : [];\n\t}\n\n\thandleBoxSelect = (e: any): void => {\n\t\tconst bounds: LatLngBounds = e.bounds;\n\n\t\tconst selection = [\n\t\t\t...this._markersLayer.getLayers()\n\t\t\t\t.filter((layer) => layer instanceof MarkerLayer && bounds.contains(layer.getLatLng()))\n\t\t\t\t.map((layer): SelectedItem => ({ type: \"marker\", id: (layer as any).marker.id })),\n\t\t\t...this._linesLayer.getLayers()\n\t\t\t\t.filter((layer) => layer instanceof Polyline && bounds.contains(layer.getBounds()))\n\t\t\t\t.map((layer): SelectedItem => ({ type: \"line\", id: (layer as any).line.id }))\n\t\t].filter((item1) => !this._selectionBeforeBox.some((item2) => isSame(item1, item2)));\n\n\t\tif (selection.length == 0)\n\t\t\tthis.setSelectedItems(this._selectionBeforeBox, true);\n\t\telse {\n\t\t\tthis.setSelectedItems([\n\t\t\t\t...this._selectionBeforeBox.filter((item) => isAllowedSibling(selection[0], item)),\n\t\t\t\t...selection\n\t\t\t], true);\n\t\t}\n\t}\n\n\thandleBoxSelectEnd = (): void => {\n\t\tthis._selectionBeforeBox = [];\n\n\t\tsetTimeout(() => {\n\t\t\tthis._isBoxInteraction = false;\n\t\t}, 0);\n\t}\n\n}\n\n// eslint-disable-next-line no-redeclare\nexport default interface SelectionHandler extends Evented {}\nObject.assign(SelectionHandler.prototype, Evented.prototype);\n","import type { PadId } from \"facilmap-types\";\nimport { isEqual } from \"lodash-es\";\nimport { reactive, watch } from \"vue\";\n\nexport interface Bookmark {\n\t/** ID used to open the map */\n\tid: PadId;\n\t/** Read-only ID of the map */\n\tpadId: PadId;\n\t/** Last known name of the map */\n\tname: string;\n\t/** If this is defined, it is shown instead of the map name. */\n\tcustomName?: string;\n}\n\nexport interface Storage {\n\tzoomToAll: boolean;\n\tautoZoom: boolean;\n\tbookmarks: Bookmark[];\n}\n\nconst storage: Storage = reactive({\n\tzoomToAll: false,\n\tautoZoom: true,\n\tbookmarks: []\n});\n\nexport default storage;\n\nfunction load(): void {\n\ttry {\n\t\tconst val = localStorage.getItem(\"facilmap\");\n\t\tif (val) {\n\t\t\tconst parsed = JSON.parse(val);\n\t\t\tstorage.zoomToAll = !!parsed.zoomToAll;\n\t\t\tstorage.autoZoom = !!parsed.autoZoom;\n\t\t\tstorage.bookmarks = parsed.bookmarks || [];\n\t\t}\n\t} catch (err) {\n\t\tconsole.error(\"Error reading local storage\", err);\n\t}\n}\n\nasync function save() {\n\ttry {\n\t\tconst currentItem = JSON.parse(localStorage.getItem(\"facilmap\") || \"null\");\n\t\tif (!currentItem || !isEqual(currentItem, storage)) {\n\t\t\tlocalStorage.setItem(\"facilmap\", JSON.stringify(storage));\n\n\t\t\tif (storage.bookmarks.length > 0 && !isEqual(currentItem?.bookmarks, storage.bookmarks) && navigator.storage?.persist)\n\t\t\t\tawait navigator.storage.persist();\n\t\t}\n\t} catch (err) {\n\t\tconsole.error(\"Error saving to local storage\", err);\n\t}\n}\n\nload();\nwindow.addEventListener(\"storage\", load);\n\nwatch(() => storage, save, { deep: true });","import Tooltip from \"bootstrap/js/dist/tooltip\";\nimport type { Directive } from \"vue\";\n\ndeclare global {\n\tinterface Element {\n\t\t_fmTooltip?: Tooltip;\n\t}\n}\n\ndeclare module \"bootstrap\" {\n\tinterface Tooltip {\n\t\ttip: Element | null;\n\t\t_newContent: Record<string, string> | null;\n\t}\n}\n\nconst allTooltips = new Set<Tooltip>();\n\nexport function hideAllTooltips(): void {\n\tfor (const tooltip of allTooltips) {\n\t\ttooltip.hide();\n\t}\n}\n\nexport type TooltipPlacement = \"top\" | \"left\" | \"right\" | \"bottom\";\n\nconst updateTooltip: Directive<Element, string | undefined> = (el, binding) => {\n\tif (binding.value) {\n\t\tif (!el._fmTooltip) {\n\t\t\tel._fmTooltip = new Tooltip(el, {\n\t\t\t\tplacement: (\n\t\t\t\t\tbinding.modifiers.bottom ? 'bottom' :\n\t\t\t\t\tbinding.modifiers.left ? 'left' :\n\t\t\t\t\tbinding.modifiers.right ? 'right' :\n\t\t\t\t\t'top'\n\t\t\t\t),\n\t\t\t\ttitle: binding.value ?? '',\n\t\t\t\ttrigger: 'hover focus'\n\t\t\t});\n\t\t\tallTooltips.add(el._fmTooltip);\n\t\t}\n\n\t\tel._fmTooltip._newContent = { '.tooltip-inner': binding.value ?? \"\" };\n\n\t\tconst tooltipInner = el._fmTooltip.tip?.querySelector<HTMLElement>('.tooltip-inner');\n\t\tif (tooltipInner) {\n\t\t\ttooltipInner.innerText = binding.value;\n\t\t}\n\t} else if (el._fmTooltip) {\n\t\tdisposeTooltip(el);\n\t}\n};\n\nconst disposeTooltip = (el: Element): void => {\n\tif (el._fmTooltip) {\n\t\tallTooltips.delete(el._fmTooltip);\n\t\tel._fmTooltip.dispose();\n\t\tdelete el._fmTooltip;\n\t}\n}\n\nconst vTooltip: Directive<Element, string | undefined> = {\n\tmounted: updateTooltip,\n\tupdated: updateTooltip,\n\tbeforeUnmount: disposeTooltip\n}\n\nexport default vTooltip;\n","import { RAINBOW_STOPS } from \"facilmap-leaflet\";\nimport { getUniqueId } from \"./utils\";\nimport type { Stroke } from \"facilmap-types\";\nimport { isBright } from \"facilmap-utils\";\n\nfunction getLinePlaceholderDashArray(width: number, length: number, stroke: Stroke): string | undefined {\n\tif (stroke === \"dotted\") {\n\t\t// Fixed dashWidth = width, variable spacing >= 0.6 * width\n\t\tconst dashWidth = width\n\t\tconst minSpaceWidth = 0.6 * dashWidth;\n\n\t\t// (numberOfDashes * dashWidth) + ((numberOfDashes - 1) * minSpaceWidth) = length\n\t\t// (numberOfDashes * dashWidth) + (numberOfDashes * minSpaceWidth) - minSpaceWidth = length\n\t\t// numberOfDashes * (dashWidth + minSpaceWidth) = length + minSpaceWidth\n\t\t// numberOfDashes = (length + minSpaceWidth) / (dashWidth + minSpaceWidth)\n\t\tconst numberOfDashes = Math.max(3, Math.floor((length + minSpaceWidth) / (dashWidth + minSpaceWidth)));\n\n\t\tconst spaceWidth = (length - (dashWidth * numberOfDashes)) / (numberOfDashes - 1);\n\t\treturn `${dashWidth - width} ${spaceWidth + width - 0.01}`;\n\t} else if (stroke === \"dashed\") {\n\t\t// At least 2 dashes, fixed dash/space ratio 1:0.6\n\t\tconst minDashWidth = Math.max(2 * width, 5);\n\t\tconst minSpaceWidth = minDashWidth * 0.6;\n\t\tconst numberOfDashes = Math.floor((length + minSpaceWidth) / (minDashWidth + minSpaceWidth));\n\n\t\tif (numberOfDashes >= 2) {\n\t\t\t// numberOfDashes * dashWidth + (numberOfDashes - 1) * dashWidth * 0.6 = length\n\t\t\t// numberOfDashes * dashWidth + numberOfDashes * dashWidth * 0.6 - dashWidth * 0.6 = length\n\t\t\t// dashWidth * (numberOfDashes + numberOfDashes * 0.6 - 0.6) = length\n\t\t\t// dashWidth = length / (numberOfDashes + numberOfDashes * 0.6 - 0.6)\n\t\t\t// dashWidth = length / (1.6 * numberOfDashes - 0.6)\n\t\t\tconst dashWidth = length / (1.6 * numberOfDashes - 0.6);\n\t\t\tconst spaceWidth = dashWidth * 0.6;\n\n\t\t\treturn `${dashWidth - width} ${spaceWidth + width - 0.01}`;\n\t\t} else {\n\t\t\t// Not enough space for 2 dashes with the minimum dash width.\n\t\t\t// Try to fit 2 dashes without minimum width at a dash/space ratio 1:0.6\n\n\t\t\t// 2 * dashWidth + 0.6 * dashWidth = length\n\t\t\tconst dashWidth = length / 2.6;\n\t\t\tif (dashWidth >= width) {\n\t\t\t\tconst spaceWidth = dashWidth * 0.6;\n\t\t\t\treturn `${dashWidth - width} ${spaceWidth + width - 0.01}`;\n\t\t\t} else {\n\t\t\t\t// Not enough space to fit 2 dashes at 1:0.6\n\t\t\t\t// Show 2 dots with a variable space width\n\t\t\t\tconst spaceWidth = length - (width * 2);\n\t\t\t\treturn `0 ${spaceWidth + width - 0.01}`;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function createLinePlaceholderHtml(colour: string, width: number, length: number, stroke: Stroke): string {\n\tconst rainbowId = (colour == \"rainbow\" && getUniqueId(\"fm-line-rainbow\"));\n\tconst renderBorder = colour !== \"rainbow\" && isBright(colour);\n\n\tconst pathStyle = {\n\t\t\"stroke\": rainbowId ? `url(#${rainbowId})` : colour,\n\t\t\"stroke-width\": `${Math.max(0.8, width - (renderBorder ? 1 : 0))}px`,\n\t\t\"stroke-linecap\": \"round\",\n\t\t\"stroke-dasharray\": getLinePlaceholderDashArray(width, length, stroke),\n\t};\n\n\tconst borderStyle = {\n\t\t...pathStyle,\n\t\t\"stroke\": \"#000000\",\n\t\t\"stroke-width\": `${width}px`\n\t};\n\n\treturn (\n\t\t`<svg width=\"${length}\" height=\"${width}\">` +\n\t\t\t(rainbowId ? `<defs><linearGradient id=\"${rainbowId}\" x2=\"100%\" y2=\"0\" gradientUnits=\"userSpaceOnUse\">${RAINBOW_STOPS}</linearGradient></defs>` : ``) +\n\t\t\t(renderBorder ? `<path d=\"M${width / 2} ${width / 2} h${length - width}\" style=\"${Object.entries(borderStyle).flatMap(([k, v]) => v ? [`${k}: ${v}`] : []).join(\"; \")}\"/>` : \"\") +\n\t\t\t`<path d=\"M${width / 2} ${width / 2} h${length - width}\" style=\"${Object.entries(pathStyle).flatMap(([k, v]) => v ? [`${k}: ${v}`] : []).join(\"; \")}\"/>` +\n\t\t`</svg>`\n\t);\n}\n\nexport function getGridColumnsCount(grid: Element): number {\n\t// https://stackoverflow.com/a/58393617/242365\n\treturn getComputedStyle(grid).getPropertyValue(\"grid-template-columns\").split(\" \").length;\n}\n\nexport function arrowNavigation<V>(values: V[], value: V | undefined, grid: Element, event: KeyboardEvent): V | undefined {\n\tif (![\"ArrowUp\", \"ArrowLeft\", \"ArrowDown\", \"ArrowRight\"].includes(event.key) || event.shiftKey || event.ctrlKey || event.metaKey)\n\t\treturn;\n\tif ([\"ArrowLeft\", \"ArrowRight\"].includes(event.key) && (event.target as HTMLElement | undefined)?.closest(\"input:not(.fm-keyboard-navigation-exception)\"))\n\t\treturn;\n\n\tevent.preventDefault();\n\n\tconst columns = getGridColumnsCount(grid);\n\tconst idx = value && values.includes(value) ? values.indexOf(value) : undefined;\n\n\tif (idx == null)\n\t\treturn [\"ArrowDown\", \"ArrowRight\"].includes(event.key) ? values[0] : value;\n\n\treturn values[idx + {\n\t\tArrowUp: -columns,\n\t\tArrowLeft: -1,\n\t\tArrowDown: columns,\n\t\tArrowRight: 1\n\t}[event.key]!] ?? value;\n}","import { type LatLng, latLng, type LatLngBounds, latLngBounds, type Map } from \"leaflet\";\nimport { fmToLeafletBbox, type HashQuery, type OverpassElement } from \"facilmap-leaflet\";\nimport type { RouteWithTrackPoints } from \"facilmap-client\";\nimport type { SelectedItem } from \"./selection\";\nimport type { FindOnMapLine, FindOnMapMarker, FindOnMapResult, Line, Marker, SearchResult } from \"facilmap-types\";\nimport type { Geometry } from \"geojson\";\nimport { isMapResult } from \"./search\";\nimport { decodeLonLatUrl, decodeRouteQuery, encodeRouteQuery, normalizeLineName, normalizeMarkerName, parseRouteQuery } from \"facilmap-utils\";\nimport type { ClientContext } from \"../components/facil-map-context-provider/client-context\";\nimport type { FacilMapContext } from \"../components/facil-map-context-provider/facil-map-context\";\nimport { requireClientContext, requireMapContext } from \"../components/facil-map-context-provider/facil-map-context-provider.vue\";\nimport { toRef, type DeepReadonly } from \"vue\";\n\nexport type ZoomDestination = {\n\tcenter?: LatLng;\n\tzoom?: number;\n\tbounds?: LatLngBounds;\n};\n\nexport function getZoomDestinationForGeoJSON(geojson: DeepReadonly<Geometry>): ZoomDestination | undefined {\n\tif (geojson.type == \"GeometryCollection\")\n\t\treturn combineZoomDestinations(geojson.geometries.map((geo) => getZoomDestinationForGeoJSON(geo)));\n\telse if (geojson.type == \"Point\")\n\t\treturn { center: latLng(geojson.coordinates[1], geojson.coordinates[0]) };\n\telse if (geojson.type == \"LineString\" || geojson.type == \"MultiPoint\")\n\t\treturn combineZoomDestinations(geojson.coordinates.map((pos) => ({ center: latLng(pos[1], pos[0]) })));\n\telse if (geojson.type == \"Polygon\" || geojson.type == \"MultiLineString\")\n\t\treturn combineZoomDestinations(geojson.coordinates.flat().map((pos) => ({ center: latLng(pos[1], pos[0]) })));\n\telse if (geojson.type == \"MultiPolygon\")\n\t\treturn combineZoomDestinations(geojson.coordinates.flat().flat().map((pos) => ({ center: latLng(pos[1], pos[0]) })));\n\telse\n\t\treturn undefined;\n}\n\nexport function getZoomDestinationForMarker(marker: Marker | FindOnMapMarker | OverpassElement): ZoomDestination {\n\treturn { center: latLng(marker.lat, marker.lon), zoom: 15 };\n}\n\nexport function getZoomDestinationForLine(line: Line | FindOnMapLine): ZoomDestination {\n\treturn { bounds: fmToLeafletBbox(line) };\n}\n\nexport function getZoomDestinationForRoute(route: RouteWithTrackPoints): ZoomDestination {\n\treturn { bounds: fmToLeafletBbox(route) };\n}\n\nexport function getZoomDestinationForSearchResult(result: DeepReadonly<SearchResult>): ZoomDestination | undefined {\n\tconst dest: ZoomDestination = {};\n\n\tif (result.boundingbox)\n\t\tdest.bounds = latLngBounds([[result.boundingbox[0], result.boundingbox[3]], [result.boundingbox[1], result.boundingbox[2]]]);\n\telse if (result.geojson)\n\t\tdest.bounds = getZoomDestinationForGeoJSON(result.geojson)?.bounds;\n\n\tif (result.lat && result.lon)\n\t\tdest.center = latLng(Number(result.lat), Number(result.lon));\n\telse if (result.geojson)\n\t\tdest.center = getZoomDestinationForGeoJSON(result.geojson)?.center;\n\n\tif (result.zoom != null)\n\t\tdest.zoom = result.zoom;\n\n\treturn Object.keys(dest).length == 0 ? undefined : dest;\n}\n\nexport function getZoomDestinationForMapResult(result: FindOnMapResult): ZoomDestination {\n\tif (result.kind == \"marker\")\n\t\treturn getZoomDestinationForMarker(result);\n\telse\n\t\treturn getZoomDestinationForLine(result);\n}\n\nexport function getZoomDestinationForResults(results: Array<SearchResult | FindOnMapResult>): ZoomDestination | undefined {\n\treturn combineZoomDestinations(results\n\t\t.map((result) => (isMapResult(result) ? getZoomDestinationForMapResult(result) : getZoomDestinationForSearchResult(result)))\n\t\t.filter((result) => !!result) as ZoomDestination[]\n\t);\n}\n\nexport function combineZoomDestinations(destinations: Array<ZoomDestination | undefined>): ZoomDestination | undefined {\n\tif (destinations.length == 0)\n\t\treturn undefined;\n\telse if (destinations.length == 1)\n\t\treturn destinations[0];\n\n\tconst bounds = latLngBounds(undefined as any);\n\tfor (const destination of destinations) {\n\t\tif (destination)\n\t\t\tbounds.extend((destination.bounds || destination.center)!);\n\t}\n\treturn { bounds };\n}\n\nexport function normalizeZoomDestination(map: Map, destination: ZoomDestination): Required<ZoomDestination> & Pick<ZoomDestination, \"bounds\"> {\n\tconst result = { ...destination };\n\tif (result.center == null)\n\t\tresult.center = destination.bounds!.getCenter();\n\tif (result.zoom == null)\n\t\tresult.zoom = result.bounds ? Math.min(15, map.getBoundsZoom(result.bounds)) : 15;\n\treturn result as any;\n}\n\nexport function flyTo(map: Map, destination: ZoomDestination, smooth = true): void {\n\tconst dest = normalizeZoomDestination(map, destination);\n\tif (map._loaded && smooth)\n\t\tmap.flyTo(dest.center, dest.zoom);\n\telse\n\t\tmap.setView(dest.center, dest.zoom, { animate: false });\n}\n\nexport function getHashQuery(map: Map, client: ClientContext, items: DeepReadonly<SelectedItem>[]): HashQuery | undefined {\n\tif (items.length == 1) {\n\t\tif (items[0].type == \"searchResult\") {\n\t\t\tconst destination = getZoomDestinationForSearchResult(items[0].result);\n\t\t\tif (items[0].result.id && destination)\n\t\t\t\treturn { query: items[0].result.id, ...normalizeZoomDestination(map, destination), description: items[0].result.short_name };\n\t\t\telse\n\t\t\t\treturn undefined;\n\t\t} else if (items[0].type == \"marker\") {\n\t\t\tconst marker = client.markers[items[0].id];\n\t\t\treturn {\n\t\t\t\tquery: `m${items[0].id}`,\n\t\t\t\t...(marker ? { ...normalizeZoomDestination(map, getZoomDestinationForMarker(marker)), description: normalizeMarkerName(marker.name) } : {})\n\t\t\t};\n\t\t} else if (items[0].type == \"line\") {\n\t\t\tconst line = client.lines[items[0].id];\n\t\t\treturn {\n\t\t\t\tquery: `l${items[0].id}`,\n\t\t\t\t...(line ? { ...normalizeZoomDestination(map, getZoomDestinationForLine(line)), description: normalizeLineName(line.name) } : {})\n\t\t\t};\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nexport async function openSpecialQuery(query: string, context: FacilMapContext, zoom: boolean, smooth = true): Promise<boolean> {\n\tconst mapContext = requireMapContext(context);\n\tconst client = requireClientContext(context);\n\tconst searchBoxContext = toRef(() => context.components.searchBox);\n\tconst routeFormTabContext = toRef(() => context.components.routeFormTab);\n\n\tif(searchBoxContext.value && routeFormTabContext.value) {\n\t\tconst split1 = decodeRouteQuery(query); // A route hash query encoded in a predictable format in English by the route form\n\t\tif (split1.queries.length >= 2) {\n\t\t\trouteFormTabContext.value.setQuery(query, zoom, smooth);\n\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-route-form-tab`, { autofocus: true });\n\t\t\treturn true;\n\t\t}\n\n\t\tconst split2 = parseRouteQuery(query); // A free-text route query specified by the user in the current language\n\t\tif (split2.queries.length >= 2) {\n\t\t\trouteFormTabContext.value.setQuery(encodeRouteQuery(split2), zoom, smooth);\n\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-route-form-tab`, { autofocus: true });\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tconst lonlat = decodeLonLatUrl(query);\n\tif(lonlat) {\n\t\tif (zoom)\n\t\t\tflyTo(mapContext.value.components.map, { center: latLng(lonlat.lat, lonlat.lon), zoom: lonlat.zoom }, smooth);\n\t\treturn true;\n\t}\n\n\tconst markerId = Number(query.match(/^m(\\d+)$/)?.[1]);\n\tif (markerId) {\n\t\tlet marker = client.value.markers[markerId];\n\t\tif (!marker) {\n\t\t\ttry {\n\t\t\t\tmarker = await client.value.getMarker({ id: markerId });\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(\"Could not find marker\", err);\n\t\t\t}\n\t\t}\n\n\t\tif (marker) {\n\t\t\tmapContext.value.components.selectionHandler.setSelectedItems([{ type: \"marker\", id: marker.id }], true);\n\n\t\t\tif (zoom)\n\t\t\t\tflyTo(mapContext.value.components.map, getZoomDestinationForMarker(marker), smooth);\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tsearchBoxContext.value?.activateTab(`fm${context.id}-marker-info-tab`);\n\t\t\t}, 0);\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tconst lineId = Number(query.match(/^l(\\d+)$/)?.[1]);\n\tif (lineId && client.value.lines[lineId]) {\n\t\tconst line = client.value.lines[lineId];\n\n\t\tmapContext.value.components.selectionHandler.setSelectedItems([{ type: \"line\", id: line.id }], true);\n\n\t\tif (zoom)\n\t\t\tflyTo(mapContext.value.components.map, getZoomDestinationForLine(line), smooth);\n\n\t\tsetTimeout(() => {\n\t\t\tsearchBoxContext.value?.activateTab(`fm${context.id}-line-info-tab`);\n\t\t}, 0);\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}","import type { CRU, FieldUpdate, Type } from \"facilmap-types\";\nimport { mergeObject } from \"facilmap-utils\";\nimport { cloneDeep } from \"lodash-es\";\n\nfunction getIdxForInsertingField(targetFields: FieldUpdate[], targetField: FieldUpdate, mergedFields: FieldUpdate[]): number {\n\t// Check which field comes after the field in the target field list, and return the index of that field in mergedFields\n\n\tfor(let i = targetFields.indexOf(targetField) + 1; i < targetFields.length; i++) {\n\t\tif(!targetFields[i].oldName)\n\t\t\tcontinue;\n\n\t\tlet thisIdxInMergedFields = mergedFields.findIndex(field => field.oldName == targetFields[i].oldName);\n\t\tif(thisIdxInMergedFields != -1)\n\t\t\treturn thisIdxInMergedFields;\n\t}\n\n\treturn mergedFields.length;\n}\n\nfunction mergeFields(oldFields: FieldUpdate[], newFields: FieldUpdate[], customFields: FieldUpdate[]): FieldUpdate[] {\n\tlet mergedFields = newFields.map((newField) => {\n\t\tlet oldField = oldFields.find((field) => (field.name == newField.name));\n\t\tlet customField = customFields.find((field) => (field.oldName == newField.name));\n\n\t\tif(oldField && !customField) // Field has been removed in customFields\n\t\t\treturn null;\n\t\telse if(!customField)\n\t\t\treturn Object.assign({}, newField, {oldName: newField.name});\n\n\t\tlet mergedField = cloneDeep(customField);\n\t\tmergeObject(oldField, newField, mergedField);\n\n\t\treturn mergedField;\n\t}).filter(field => field != null) as FieldUpdate[];\n\n\t// Fields that don't have an oldName have been created, so we have to add them again\n\tfor(let customField of customFields.filter(field => !field.oldName))\n\t\tmergedFields.splice(getIdxForInsertingField(customFields, customField, mergedFields), 0, customField);\n\n\treturn mergedFields;\n}\n\nexport function mergeTypeObject(oldObject: Type, newObject: Type, targetObject: Type<CRU.CREATE_VALIDATED | CRU.READ>): void {\n\tlet customFields = cloneDeep(targetObject.fields);\n\n\tmergeObject(oldObject, newObject, targetObject);\n\n\ttargetObject.fields = mergeFields(oldObject.fields, newObject.fields, customFields);\n};","<script lang=\"ts\">\n\timport { computed, ref, toRef, watch, watchEffect } from \"vue\";\n\timport Popover from \"bootstrap/js/dist/popover\";\n\timport Tooltip from \"bootstrap/js/dist/tooltip\";\n\timport { useResizeObserver } from \"../../utils/vue\";\n\timport { useDomEventListener } from \"../../utils/utils\";\n\timport { getMaxSizeModifiers } from \"../../utils/bootstrap\";\n\n\t/**\n\t * Like Bootstrap Popover, but uses an existing popover element rather than creating a new one. This way, the popover\n\t * content can be made reactive.\n\t */\n\texport class CustomPopover extends Popover {\n\t\tdeclare _popper: any;\n\t\tcontentEl: Element;\n\n\t\tconstructor(element: string | Element, options: Partial<Popover.Options> & { content: Element }) {\n\t\t\tsuper(element, {\n\t\t\t\t...options,\n\t\t\t\tcontent: ' '\n\t\t\t});\n\t\t\tthis.contentEl = options.content;\n\t\t}\n\n\t\t_createTipElement(): Element {\n\t\t\t// Return content element rather than creating a new one\n\t\t\treturn this.contentEl;\n\t\t}\n\n\t\t_disposePopper(): void {\n\t\t\t// Do not remove content element here\n\t\t\tif (this._popper) {\n\t\t\t\tthis._popper.destroy()\n\t\t\t\tthis._popper = null\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<script lang=\"ts\" setup>\n\tconst props = withDefaults(defineProps<{\n\t\telement: HTMLElement | undefined;\n\t\tshow: boolean;\n\t\thideOnOutsideClick?: boolean;\n\t\t/** If true, the width of the popover will be fixed to the width of the element. */\n\t\tenforceElementWidth?: boolean;\n\t\tplacement?: Tooltip.PopoverPlacement;\n\t}>(), {\n\t\tplacement: \"bottom\"\n\t});\n\n\tconst emit = defineEmits<{\n\t\t\"update:show\": [show: boolean];\n\t\tshown: [];\n\t\thide: [];\n\t\thidden: [];\n\t}>();\n\n\tconst popover = ref<CustomPopover>();\n\tconst popoverContent = ref<HTMLElement>();\n\tconst renderPopover = ref(false);\n\n\twatchEffect((onCleanup) => {\n\t\tif (props.element && popoverContent.value) {\n\t\t\tpopover.value = new CustomPopover(props.element, {\n\t\t\t\tplacement: props.placement,\n\t\t\t\tcontent: popoverContent.value,\n\t\t\t\ttrigger: 'manual',\n\t\t\t\tpopperConfig: (defaultConfig) => ({\n\t\t\t\t\t...defaultConfig,\n\t\t\t\t\tmodifiers: [\n\t\t\t\t\t\t...(defaultConfig.modifiers ?? []),\n\t\t\t\t\t\t...getMaxSizeModifiers()\n\t\t\t\t\t],\n\t\t\t\t\tstrategy: \"fixed\"\n\t\t\t\t})\n\t\t\t});\n\t\t\tpopover.value.show();\n\n\t\t\tonCleanup(() => {\n\t\t\t\tpopover.value!.dispose();\n\t\t\t\tpopover.value = undefined;\n\t\t\t});\n\t\t}\n\t});\n\n\tuseDomEventListener(toRef(() => props.element), \"shown.bs.popover\", () => {\n\t\temit(\"shown\");\n\t});\n\n\tuseDomEventListener(toRef(() => props.element), \"hide.bs.popover\", () => {\n\t\temit(\"hide\");\n\t});\n\n\tuseDomEventListener(toRef(() => props.element), \"hidden.bs.popover\", () => {\n\t\trenderPopover.value = false;\n\t\temit(\"hidden\");\n\t});\n\n\twatch(() => props.show, (show) => {\n\t\tif (show) {\n\t\t\trenderPopover.value = true;\n\t\t} else {\n\t\t\tpopover.value?.hide();\n\t\t}\n\t});\n\n\tuseDomEventListener(() => props.element, \"focusout\", (e: Event) => {\n\t\tconst event = e as FocusEvent;\n\t\t// relatedTarget == null: target is out of viewport (ignore to allow focussing dev tools)\n\t\tif (props.show && event.relatedTarget && !popoverContent.value?.contains(event.relatedTarget as Node) && !props.element?.contains(event.relatedTarget as Node)) {\n\t\t\temit(\"update:show\", false);\n\t\t}\n\t});\n\n\tfunction handlePopoverFocusOut(event: FocusEvent) {\n\t\t// relatedTarget == null: target is out of viewport (ignore to allow focussing dev tools)\n\t\tif (props.show && event.relatedTarget && !popoverContent.value?.contains(event.relatedTarget as Node) && !props.element?.contains(event.relatedTarget as Node)) {\n\t\t\temit(\"update:show\", false);\n\t\t}\n\t}\n\n\tuseDomEventListener(document, \"click\", (e: Event) => {\n\t\tif (props.show && props.hideOnOutsideClick && e.target instanceof Node && !props.element?.contains(e.target) && !popoverContent.value?.contains(e.target)) {\n\t\t\temit(\"update:show\", false);\n\t\t}\n\t}, { capture: true });\n\n\tconst elementSize = useResizeObserver(computed(() => props.enforceElementWidth ? props.element : undefined));\n</script>\n\n<template>\n\t<div\n\t\tv-if=\"renderPopover\"\n\t\tclass=\"popover fm-popover fade bs-popover-auto\"\n\t\tref=\"popoverContent\"\n\t\t:style=\"props.enforceElementWidth && elementSize ? { maxWidth: 'none', width: `${elementSize.contentRect.width}px` } : undefined\"\n\t\t@focusout=\"handlePopoverFocusOut\"\n\t\t:tabindex=\"-1 /* Allow focusing by click (for focusout event relatedTarget), do not allow focusing by tab */\"\n\t>\n\t\t<div class=\"popover-arrow\"></div>\n\t\t<h3 v-if=\"$slots.header\" class=\"popover-header\">\n\t\t\t<slot name=\"header\"></slot>\n\t\t</h3>\n\t\t<div class=\"popover-body\">\n\t\t\t<slot></slot>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-popover.fm-popover {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\n\t\t> .popover-body {\n\t\t\toverflow: auto;\n\n\t\t\t> *:first-child {\n\t\t\t\tmargin-top: 0;\n\t\t\t}\n\n\t\t\t> *:last-child {\n\t\t\t\tmargin-bottom: 0;\n\t\t\t}\n\t\t}\n\t}\n</style>","<script lang=\"ts\">\n\timport { isEqual } from \"lodash-es\";\n\timport { computed, onBeforeUpdate, reactive, ref, useAttrs, watch } from \"vue\";\n\n\t/**\n\t * Renders an element that preserves attributes manually added through the DOM.\n\t *\n\t * Usually Vue removes any attributes that are not part of the template when the component is rerendered.\n\t * This makes it hard to work with third-party libraries that modify the DOM directly. This component\n\t * creates a copy of any attributes in the DOM before each component update and renders these attributes\n\t * again during the update. Any DOM attributes that are (or have ever been) part of the component props\n\t * are ignored and rendered according to the prop value.\n\t *\n\t * Class names are handled separately in the same way: The component keeps track of class names manually\n\t * added through DOM operations and adds them again during render. Class names that are (or have ever been)\n\t * part of the \"class\" prop are ignored.\n\t */\n\texport default {};\n</script>\n\n<script setup lang=\"ts\">\n\tconst props = defineProps<{\n\t\ttag: string;\n\t\tclass?: string | Record<string, boolean> | Array<string | Record<string, boolean>>;\n\t}>();\n\n\tconst elementRef = ref<HTMLElement>();\n\n\tconst ownAttributeNames = reactive(new Set<string>());\n\tconst ownClassNames = reactive(new Set<string>());\n\n\twatch(props, () => {\n\t\tfor (const attrName of Object.keys(props)) {\n\t\t\townAttributeNames.add(attrName);\n\t\t}\n\t}, { immediate: true });\n\n\twatch(() => props.class, () => {\n\t\tconst classNames = (\n\t\t\ttypeof props.class === 'string' ? props.class.split(\" \") :\n\t\t\tArray.isArray(props.class) ? props.class.flatMap((className) => typeof className === 'string' ? [className] : Object.keys(className)) :\n\t\t\tprops.class ? Object.keys(props.class) :\n\t\t\t[]\n\t\t);\n\t\tfor (const className of classNames) {\n\t\t\townClassNames.add(className);\n\t\t}\n\t}, { immediate: true, deep: true });\n\n\n\tconst manualAttributes = ref<Record<string, string>>({});\n\tconst manualClassNames = ref<string[]>([]);\n\n\tonBeforeUpdate(() => {\n\t\tif (elementRef.value) {\n\t\t\tconst attributes = Object.fromEntries([...elementRef.value.attributes].flatMap((attr) => {\n\t\t\t\treturn attr.nodeValue != null ? [[attr.nodeName, attr.nodeValue]] : [];\n\t\t\t}));\n\t\t\tif (!isEqual(attributes, manualAttributes.value)) {\n\t\t\t\tmanualAttributes.value = attributes;\n\t\t\t}\n\n\t\t\tconst classNames = [...elementRef.value.classList];\n\t\t\tif (!isEqual(classNames, manualClassNames.value)) {\n\t\t\t\tmanualClassNames.value = classNames;\n\t\t\t}\n\t\t}\n\t});\n\n\tconst attrs = useAttrs();\n\n\tconst attributes = computed(() => Object.fromEntries([\n\t\t...Object.entries(manualAttributes.value).filter(([k, v]) => !ownAttributeNames.has(k)),\n\t\t...Object.entries(attrs).filter(([k, v]) => ![\"class\", \"tag\"].includes(k))\n\t]));\n\n\tconst className = computed(() => [\n\t\t...manualClassNames.value.filter((c) => !ownClassNames.has(c)),\n\t\tprops.class ?? ''\n\t].join(' '));\n\n\tdefineExpose({\n\t\telementRef\n\t});\n</script>\n\n<template>\n\t<component\n\t\tv-bind=\"attributes\"\n\t\t:is=\"props.tag\"\n\t\t:class=\"className\"\n\t\tref=\"elementRef\"\n\t>\n\t\t<slot></slot>\n\t</component>\n</template>","<script lang=\"ts\">\n\timport { ref, toRef, watch } from \"vue\";\n\timport { useModal } from \"../../utils/modal\";\n\timport { useMaxBreakpoint } from \"../../utils/bootstrap\";\n\timport Popover from \"./popover.vue\";\n\timport { useRefWithOverride } from \"../../utils/vue\";\n\timport AttributePreservingElement from \"./attribute-preserving-element.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\texport const hybridPopoverShouldUseModal = useMaxBreakpoint(\"xs\");\n\n\t/**\n\t * Renders an element that opens a popover on large screens and a modal on small screens.\n\t */\n\texport default {};\n</script>\n\n<script setup lang=\"ts\">\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tshow?: boolean;\n\t\ttitle?: string;\n\t\tcustomClass?: string;\n\t\t/** If true, the width of the popover will be fixed to the width of the element. */\n\t\tenforceElementWidth?: boolean;\n\t\t/** If true, a click of the reference element will not toggle the popover. */\n\t\tignoreClick?: boolean;\n\t}>(), {\n\t\tshow: undefined\n\t});\n\n\tconst emit = defineEmits<{\n\t\t\"update:show\": [show: boolean];\n\t\tshown: [];\n\t\thide: [];\n\t\thidden: [];\n\t}>();\n\n\tconst show = useRefWithOverride(false, () => props.show, (show) => {\n\t\temit(\"update:show\", show);\n\t});\n\tconst showModal = ref(false);\n\tconst showPopover = ref(false);\n\n\twatch(show, () => {\n\t\tif (!show.value) {\n\t\t\tif (showModal.value) {\n\t\t\t\tmodal.hide();\n\t\t\t}\n\t\t\tshowPopover.value = false;\n\t\t} else if (!showModal.value && !showPopover.value) {\n\t\t\tif (hybridPopoverShouldUseModal.value) {\n\t\t\t\tshowModal.value = true;\n\t\t\t} else {\n\t\t\t\tshowPopover.value = true;\n\t\t\t}\n\t\t}\n\t});\n\n\tconst trigger = ref<HTMLElement>();\n\n\tconst modalElementRef = ref<InstanceType<typeof AttributePreservingElement>>();\n\tconst modalRef = toRef(() => modalElementRef.value?.elementRef);\n\tconst modal = useModal(modalRef, {\n\t\tonShown: () => {\n\t\t\temit(\"shown\");\n\t\t},\n\t\tonHide: () => {\n\t\t\temit(\"hide\");\n\t\t},\n\t\tonHidden: () => {\n\t\t\tshowModal.value = false;\n\t\t\tshow.value = false;\n\t\t\temit(\"hidden\");\n\t\t}\n\t});\n\n\tconst handleShowPopoverChange = (newShowPopover: boolean) => {\n\t\tshowPopover.value = newShowPopover;\n\t\tshow.value = newShowPopover;\n\t};\n\n\tconst handleClick = () => {\n\t\tif (!props.ignoreClick) {\n\t\t\tshow.value = !show.value;\n\t\t}\n\t};\n\n\tconst close = () => {\n\t\tshow.value = false;\n\t};\n</script>\n\n<template>\n\t<div class=\"fm-hybrid-popover\">\n\t\t<div ref=\"trigger\" @click=\"handleClick()\">\n\t\t\t<slot name=\"trigger\"></slot>\n\t\t</div>\n\n\t\t<Popover\n\t\t\t:show=\"showPopover\"\n\t\t\t@update:show=\"handleShowPopoverChange\"\n\t\t\t:element=\"trigger\"\n\t\t\t:class=\"props.customClass\"\n\t\t\thideOnOutsideClick\n\t\t\t:enforceElementWidth=\"props.enforceElementWidth\"\n\t\t\t@shown=\"emit('shown')\"\n\t\t\t@hide=\"emit('hide')\"\n\t\t\t@hidden=\"emit('hidden')\"\n\t\t>\n\t\t\t<template v-slot:header>\n\t\t\t\t{{props.title}}\n\t\t\t</template>\n\t\t\t<slot :is-modal=\"false\" :close=\"close\"></slot>\n\t\t</Popover>\n\n\t\t<Teleport to=\"body\">\n\t\t\t<AttributePreservingElement\n\t\t\t\tv-if=\"showModal\"\n\t\t\t\ttag=\"div\"\n\t\t\t\tclass=\"modal fade\"\n\t\t\t\t:class=\"props.customClass\"\n\t\t\t\ttabindex=\"-1\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t\tref=\"modalElementRef\"\n\t\t\t>\n\t\t\t\t<div class=\"modal-dialog modal-dialog-scrollable\">\n\t\t\t\t\t<div class=\"modal-content\">\n\t\t\t\t\t\t<div v-if=\"props.title\" class=\"modal-header\">\n\t\t\t\t\t\t\t<h1 class=\"modal-title fs-5\">{{props.title}}</h1>\n\t\t\t\t\t\t\t<button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" :aria-label=\"i18n.t('hybrid-popover.close-label')\"></button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"modal-body\">\n\t\t\t\t\t\t\t<slot :is-modal=\"false\" :close=\"close\"></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"modal-footer\">\n\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-primary\" data-bs-dismiss=\"modal\">{{i18n.t(\"hybrid-popover.ok-label\")}}</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</AttributePreservingElement>\n\t\t</Teleport>\n\t</div>\n</template>","<script lang=\"ts\">\n\timport { type Ref, onScopeDispose, reactive, readonly, ref, watchEffect, toRef, computed } from \"vue\";\n\timport { type ExtendableEventMixin, extendableEventMixin, useDomEventListener } from \"../../../utils/utils\";\n\timport { useToasts } from \"../toasts/toasts.vue\";\n\n\texport interface ValidatedFormData {\n\t\tisTouched: boolean;\n\t\tisSubmitting: boolean;\n\t\tisValidating: boolean;\n\t\tformValidationError: string | undefined;\n\t\tsubmit: () => Promise<void>;\n\t\tsetValidationPromise: (element: Element, promise: Promise<any> | undefined) => void;\n\t}\n\n\texport interface CustomSubmitEvent extends ExtendableEventMixin {\n\t\tpreventDefault(): void;\n\t}\n\n\tconst allForms = reactive(new Map<Ref<HTMLFormElement | undefined>, ValidatedFormData>());\n\n\texport function useValidatedForm(\n\t\tformRef: Ref<HTMLFormElement | undefined>,\n\t\tonSubmit: (event: CustomSubmitEvent) => void,\n\t\t{ noValidate, formValidationError }: {\n\t\t\tnoValidate?: Ref<boolean>;\n\t\t\t/** A form validation error that will prevent the form from submitting. */\n\t\t\tformValidationError?: Ref<string | undefined>;\n\t\t} = {}\n\t): Readonly<ValidatedFormData> {\n\t\tconst toasts = useToasts();\n\t\tconst validationPromises = new Map<Element, Promise<any>>();\n\t\tconst isValidating = reactive(new Map<Element, boolean>());\n\n\t\tconst data: ValidatedFormData = reactive<Omit<ValidatedFormData, \"formValidationError\"> & { formValidationError: Ref<string | undefined> }>({\n\t\t\tisTouched: false,\n\t\t\tisSubmitting: false,\n\t\t\tisValidating: false,\n\t\t\tformValidationError: toRef(formValidationError),\n\t\t\tsubmit: toasts.toastErrors(async () => {\n\t\t\t\tdata.isTouched = true;\n\t\t\t\tdata.isSubmitting = true;\n\n\t\t\t\ttry {\n\t\t\t\t\tif (!noValidate?.value) {\n\t\t\t\t\t\tawait Promise.all(validationPromises.values());\n\n\t\t\t\t\t\tif (!formRef.value!.checkValidity() || formValidationError?.value) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tlet prevented = false;\n\t\t\t\t\tconst event = {\n\t\t\t\t\t\t...extendableEventMixin,\n\t\t\t\t\t\tpreventDefault() {\n\t\t\t\t\t\t\tprevented = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tonSubmit(event);\n\t\t\t\t\tawait event._awaitPromises();\n\n\t\t\t\t\tif (!prevented) {\n\t\t\t\t\t\tformRef.value?.submit();\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tdata.isSubmitting = false;\n\t\t\t\t}\n\t\t\t}),\n\t\t\tsetValidationPromise: (element, promise) => {\n\t\t\t\tif (promise) {\n\t\t\t\t\tif (validationPromises.get(element) !== promise) {\n\t\t\t\t\t\tvalidationPromises.set(element, promise);\n\t\t\t\t\t\tisValidating.set(element, true);\n\t\t\t\t\t\tvoid promise.finally(() => {\n\t\t\t\t\t\t\tif (validationPromises.get(element) === promise) {\n\t\t\t\t\t\t\t\tisValidating.set(element, false);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvalidationPromises.delete(element);\n\t\t\t\t\tisValidating.delete(element);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\twatchEffect(() => {\n\t\t\tdata.isValidating = [...isValidating.values()].some((v) => v);\n\t\t});\n\n\t\tuseDomEventListener(formRef, \"submit\", (e) => {\n\t\t\te.preventDefault();\n\t\t\tvoid data.submit();\n\t\t});\n\n\t\tallForms.set(formRef, data);\n\n\t\tonScopeDispose(() => {\n\t\t\tallForms.delete(formRef);\n\t\t});\n\n\t\treturn readonly(data);\n\t}\n\n\texport function getValidatedForm(form: HTMLFormElement): Readonly<ValidatedFormData> | undefined {\n\t\tfor (const [formRef, formData] of allForms) {\n\t\t\tif (formRef.value === form) {\n\t\t\t\treturn formData;\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<script setup lang=\"ts\">\n\tconst props = defineProps<{\n\t\taction?: string;\n\t\ttarget?: string;\n\t\tnoValidate?: boolean;\n\t\tformValidationError?: string | undefined;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\tsubmit: [event: CustomSubmitEvent];\n\t}>();\n\n\tconst formRef = ref<HTMLFormElement>();\n\tconst formData = useValidatedForm(formRef, (event) => {\n\t\temit(\"submit\", event);\n\t}, {\n\t\tnoValidate: toRef(() => props.noValidate),\n\t\tformValidationError: toRef(() => props.formValidationError)\n\t});\n\n\tconst actionWithoutQuery = computed(() => {\n\t\tif (props.action != null) {\n\t\t\tconst url = new URL(props.action);\n\t\t\turl.search = \"\";\n\t\t\treturn url.toString();\n\t\t}\n\t});\n\tconst actionParams = computed(() => {\n\t\tif (props.action != null) {\n\t\t\tconst url = new URL(props.action);\n\t\t\treturn url.searchParams;\n\t\t}\n\t});\n\n\tdefineExpose({ formData });\n</script>\n\n<template>\n\t<form\n\t\tnovalidate\n\t\tref=\"formRef\"\n\t\t:action=\"actionWithoutQuery ?? 'javascript:'\"\n\t\t:target=\"props.target\"\n\t\t:class=\"{ 'fm-was-validated': formData.isTouched }\"\n\t>\n\t\t<template v-for=\"[key, value] in actionParams?.entries()\" :key=\"key\">\n\t\t\t<input type=\"hidden\" :name=\"key\" :value=\"value\" />\n\t\t</template>\n\n\t\t<slot :formData=\"formData\"/>\n\t</form>\n</template>","<script lang=\"ts\">\n\timport { ref, watchEffect, computed, watchSyncEffect } from \"vue\";\n\timport { isPromise } from \"facilmap-utils\";\n\timport { useDomEventListener } from \"../../../utils/utils\";\n\timport { getValidatedForm } from \"./validated-form.vue\";\n\timport { useToasts } from \"../toasts/toasts.vue\";\n\timport pDebounce from \"p-debounce\";\n\timport { useI18n } from \"../../../utils/i18n\";\n\n\ttype SyncValidationResult = string | undefined;\n\ttype AsyncValidationResult = Promise<SyncValidationResult>;\n\ttype ValidationResult = SyncValidationResult | AsyncValidationResult;\n\texport type Validator<T> = (value: T, signal: AbortSignal) => ValidationResult;\n\n\tfunction validate<T>(value: T, validators: Array<Validator<T>>, signal: AbortSignal): ValidationResult {\n\t\tfor (let i = 0; i < validators.length; i++) {\n\t\t\tif (signal.aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst result = validators[i](value, signal);\n\t\t\tif (isPromise(result)) {\n\t\t\t\treturn resolveValidationResult([\n\t\t\t\t\tresult,\n\t\t\t\t\t...validators.slice(i + 1).map((validator) => validator(value, signal))\n\t\t\t\t], signal);\n\t\t\t} else if (result) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tfunction resolveValidationResult(results: ValidationResult[], signal: AbortSignal): AsyncValidationResult {\n\t\treturn new Promise<SyncValidationResult>((resolve, reject) => {\n\t\t\tfor (const result of results) {\n\t\t\t\tvoid Promise.resolve(result).then((res) => {\n\t\t\t\t\tif (res) {\n\t\t\t\t\t\tresolve(res);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tPromise.all(results).then(() => {\n\t\t\t\tresolve(undefined);\n\t\t\t}).catch(reject);\n\t\t});\n\t}\n</script>\n\n<script setup lang=\"ts\" generic=\"T\">\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tvalue: T;\n\t\tvalidators?: Array<Validator<T>>;\n\t\ttag?: string;\n\t\t/** If true, show the validation status also if the value is valid. */\n\t\treportValid?: boolean;\n\t\t/** If true, validate the field immediately without waiting for a change/blur/submit. */\n\t\timmediate?: boolean;\n\t\tdebounceMs?: number;\n\t}>(), {\n\t\ttag: \"div\",\n\t\tvalidators: () => []\n\t});\n\n\ttype FormElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n\n\tconst inputRef = ref<FormElement>();\n\tconst formRef = ref<HTMLFormElement>();\n\n\twatchEffect((onCleanup) => {\n\t\tif (inputRef.value) {\n\t\t\tformRef.value = inputRef.value.form ?? undefined;\n\n\t\t\tconst obs = new MutationObserver(() => {\n\t\t\t\tformRef.value = inputRef.value?.form ?? undefined;\n\t\t\t});\n\t\t\tobs.observe(inputRef.value, { attributes: true });\n\t\t\tonCleanup(() => {\n\t\t\t\tobs.disconnect();\n\t\t\t});\n\t\t} else {\n\t\t\tformRef.value = undefined;\n\t\t}\n\t});\n\tconst validatedForm = computed(() => formRef.value && getValidatedForm(formRef.value));\n\n\tconst validationErrorPromise = ref<Promise<void>>();\n\tconst resolvedValidationError = ref<string | undefined>();\n\tconst isValidating = ref(false);\n\n\tlet debouncedValidate: typeof validate;\n\twatchSyncEffect(() => {\n\t\tdebouncedValidate = pDebounce(validate, props.debounceMs ?? 0);\n\t});\n\n\t// Memoize validators prop with a shallow equality check, since mostly we specify them using an inline array\n\tconst memoizedValidators = ref<Array<Validator<T>>>([]);\n\twatchEffect(() => {\n\t\tif (props.validators.length !== memoizedValidators.value.length || props.validators.some((v, i) => memoizedValidators.value[i] !== v)) {\n\t\t\tmemoizedValidators.value = props.validators;\n\t\t}\n\t});\n\n\twatchEffect((onCleanup) => {\n\t\tconst abortController = new AbortController();\n\t\tonCleanup(() => {\n\t\t\tabortController.abort();\n\t\t});\n\n\t\ttry {\n\t\t\ttoasts.hideToast(\"fm-validity-error\");\n\n\t\t\tconst result = (props.debounceMs ? debouncedValidate : validate)(props.value, memoizedValidators.value, abortController.signal);\n\t\t\tif (isPromise(result)) {\n\t\t\t\tisValidating.value = true;\n\t\t\t\tconst promise = validationErrorPromise.value = result.then((res) => {\n\t\t\t\t\tif (validationErrorPromise.value === promise) {\n\t\t\t\t\t\tresolvedValidationError.value = res;\n\t\t\t\t\t\tisValidating.value = false;\n\t\t\t\t\t}\n\t\t\t\t}).catch((err) => {\n\t\t\t\t\tif (validationErrorPromise.value === promise) {\n\t\t\t\t\t\ttoasts.showErrorToast(\"fm-validity-error\", () => i18n.t(\"validated-field.validation-error\"), err);\n\t\t\t\t\t\tresolvedValidationError.value = i18n.t(\"validated-field.validation-error\");\n\t\t\t\t\t\tisValidating.value = false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tvalidationErrorPromise.value = undefined;\n\t\t\t\tresolvedValidationError.value = result;\n\t\t\t\tisValidating.value = false;\n\t\t\t}\n\t\t} catch (err: any) {\n\t\t\ttoasts.showErrorToast(\"fm-validity-error\", () => i18n.t(\"validated-field.validation-error\"), err);\n\t\t\tvalidationErrorPromise.value = undefined;\n\t\t\tresolvedValidationError.value = i18n.t(\"validated-field.validation-error\");\n\t\t\tisValidating.value = false;\n\t\t}\n\t});\n\n\twatchEffect(() => {\n\t\tif (inputRef.value) {\n\t\t\tinputRef.value.setCustomValidity(resolvedValidationError.value ?? \"\");\n\t\t}\n\t});\n\n\twatchEffect(() => {\n\t\tif (validatedForm.value && inputRef.value) {\n\t\t\tvalidatedForm.value.setValidationPromise(inputRef.value, validationErrorPromise.value);\n\t\t}\n\t});\n\n\tconst touched = ref(false);\n\n\tfunction handleTouched() {\n\t\tsetTimeout(() => { // Give validators a chance to run on the updated value first\n\t\t\ttouched.value = true;\n\t\t}, 0);\n\t}\n\n\tuseDomEventListener(inputRef, \"input\", handleTouched);\n\tuseDomEventListener(inputRef, \"blur\", handleTouched);\n\tuseDomEventListener(inputRef, \"focusout\", handleTouched);\n\tuseDomEventListener(formRef, \"submit\", handleTouched);\n\n\tconst wasValidated = computed(() => !isValidating.value && (props.immediate || touched.value) && (props.reportValid || !!resolvedValidationError.value));\n\n\tfunction setInputRef(el: any | null): void {\n\t\tinputRef.value = el as FormElement ?? undefined;\n\t}\n</script>\n\n<template>\n\t<component\n\t\t:is=\"props.tag\"\n\t\t:class=\"{\n\t\t\t'was-validated': wasValidated\n\t\t}\"\n\t>\n\t\t<slot\n\t\t\t:isValidating=\"isValidating\"\n\t\t\t:validationError=\"resolvedValidationError\"\n\t\t\t:inputRef=\"setInputRef\"\n\t\t></slot>\n\t</component>\n</template>","<script setup lang=\"ts\">\n\timport { type StyleValue, computed, ref } from \"vue\";\n\timport HybridPopover, { hybridPopoverShouldUseModal } from \"./hybrid-popover.vue\";\n\timport { useDomEventListener, useNonClickFocusHandler, useNonDragClickHandler } from \"../../utils/utils\";\n\timport ValidatedField, { type Validator } from \"./validated-form/validated-field.vue\";\n\n\tconst props = withDefaults(defineProps<{\n\t\tid?: string;\n\t\tcustomClass?: string;\n\t\tdisabled?: boolean;\n\t\tvalidators?: Array<Validator<string>>;\n\t\tmodelValue: string;\n\t\t/** If true, the width of the popover will be fixed to the width of the element. */\n\t\tenforceElementWidth?: boolean;\n\t\tpreviewStyle?: StyleValue;\n\t}>(), {\n\t\tenforceElementWidth: false,\n\t\tdisabled: false\n\t});\n\n\tconst emit = defineEmits<{\n\t\tkeydown: [event: KeyboardEvent];\n\t\t\"update:modelValue\": [value: string];\n\t\tfocusPopover: [];\n\t}>();\n\n\tconst value = computed({\n\t\tget: () => props.modelValue,\n\t\tset: (value) => {\n\t\t\temit(\"update:modelValue\", value!);\n\t\t}\n\t});\n\n\tconst focusFilterOnNextOpen = ref(false);\n\tconst isOpen = ref(false);\n\n\tconst containerRef = ref<HTMLElement>();\n\tconst inputRef = ref<HTMLInputElement>();\n\n\tuseDomEventListener(document.body, \"keydown\", handleBodyKeyDownCapture, { capture: true });\n\tuseDomEventListener(document.body, \"keydown\", handleBodyKeyDown, { capture: true });\n\n\tfunction handleBodyKeyDownCapture(e: Event): void {\n\t\tif (isOpen.value) {\n\t\t\tconst event = e as KeyboardEvent;\n\t\t\tif (event.key == \"Enter\") {\n\t\t\t\tinputRef.value?.focus();\n\t\t\t\tisOpen.value = false;\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\t\t\t} else if (event.key == \"Escape\") {\n\t\t\t\tisOpen.value = false;\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\t\t\t\tinputRef.value?.focus();\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction handleBodyKeyDown(e: Event): void {\n\t\tif (isOpen.value) {\n\t\t\temit(\"keydown\", e as KeyboardEvent);\n\t\t}\n\t}\n\n\tfunction handleInputKeyDown(event: KeyboardEvent): void {\n\t\tif ([\"ArrowDown\", \"ArrowUp\"].includes(event.key) && !isOpen.value) {\n\t\t\tfocusFilterOnNextOpen.value = true;\n\t\t\tisOpen.value = true;\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t} else if (event.key == \"Escape\" && isOpen.value) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation(); // Prevent closing outer modal\n\t\t\tisOpen.value = false;\n\t\t}\n\t}\n\n\tuseNonClickFocusHandler(() => inputRef.value, () => {\n\t\tif (!hybridPopoverShouldUseModal.value) {\n\t\t\topen();\n\t\t}\n\t});\n\tuseNonDragClickHandler(() => inputRef.value, open);\n\n\tfunction open() {\n\t\tfocusFilterOnNextOpen.value = true;\n\t\tisOpen.value = true;\n\t}\n\n\tfunction handleInputDblClick() {\n\t\tfocusFilterOnNextOpen.value = false;\n\t\tinputRef.value?.focus();\n\t}\n\n\tfunction handleToggleButtonClick() {\n\t\tif (isOpen.value) {\n\t\t\tisOpen.value = false;\n\t\t} else {\n\t\t\topen();\n\t\t}\n\t}\n\n\tfunction handleShown() {\n\t\tif (focusFilterOnNextOpen.value) {\n\t\t\temit(\"focusPopover\");\n\t\t}\n\t}\n</script>\n\n<template>\n\t<div class=\"fm-picker\" ref=\"containerRef\">\n\t\t<HybridPopover\n\t\t\tv-model:show=\"isOpen\"\n\t\t\t:enforceElementWidth=\"props.enforceElementWidth\"\n\t\t\t:customClass=\"props.customClass\"\n\t\t\t@shown=\"handleShown\"\n\t\t\tignoreClick\n\t\t>\n\t\t\t<template #trigger>\n\t\t\t\t<ValidatedField\n\t\t\t\t\t:value=\"value\"\n\t\t\t\t\t:validators=\"props.validators\"\n\t\t\t\t\tclass=\"input-group has-validation position-relative\"\n\t\t\t\t>\n\t\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclass=\"input-group-text\"\n\t\t\t\t\t\t\t@click=\"inputRef?.focus()\"\n\t\t\t\t\t\t\t:style=\"props.previewStyle\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<slot name=\"preview\"></slot>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\t\tautocomplete=\"off\"\n\t\t\t\t\t\t\t:disabled=\"disabled\"\n\t\t\t\t\t\t\tv-model=\"value\"\n\t\t\t\t\t\t\t:id=\"id\"\n\t\t\t\t\t\t\t:ref=\"(r) => { inputRef = r as any; slotProps.inputRef(r) }\"\n\t\t\t\t\t\t\t@keydown=\"handleInputKeyDown\"\n\t\t\t\t\t\t\t@dblclick=\"handleInputDblClick\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"btn btn-secondary dropdown-toggle\"\n\t\t\t\t\t\t\t:class=\"{ active: isOpen }\"\n\t\t\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t\t\t@click=\"handleToggleButtonClick()\"\n\t\t\t\t\t\t></button>\n\t\t\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</ValidatedField>\n\t\t\t</template>\n\n\t\t\t<template #default=\"{ isModal, close }\">\n\t\t\t\t<slot :is-modal=\"isModal\" :close=\"close\"></slot>\n\t\t\t</template>\n\t\t</HybridPopover>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-picker-modal {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t}\n</style>","<script lang=\"ts\">\n\timport ColorMixin from \"@ckpack/vue-color/src/mixin/color.js\";\n\timport { Hue, Saturation } from \"@ckpack/vue-color\";\n\timport Picker from \"./picker.vue\";\n\timport { makeTextColour } from \"facilmap-utils\";\n\timport { arrowNavigation } from \"../../utils/ui\";\n\timport { type StyleValue, computed, nextTick, ref } from \"vue\";\n\timport type { Validator } from \"./validated-form/validated-field.vue\";\n\timport { getI18n } from \"../../utils/i18n\";\n\n\tfunction normalizeData(value: string) {\n\t\treturn ColorMixin.data.apply({ modelValue: value }).val;\n\t}\n\n\tfunction isValidColour(colour: string) {\n\t\treturn !!colour?.match(/^[0-9a-f]{6}$/i);\n\t}\n\n\tfunction validateColour(colour: string): string | undefined {\n\t\tif (!isValidColour(colour)) {\n\t\t\treturn getI18n().t(\"colour-picker.format-error\");\n\t\t}\n\t}\n\n\tconst colours = [ \"ffffff\", \"ffccc9\", \"ffce93\", \"fffc9e\", \"ffffc7\", \"9aff99\", \"96fffb\", \"cdffff\", \"cbcefb\", \"cfcfcf\", \"fd6864\",\n\t\"fe996b\", \"fffe65\", \"fcff2f\", \"67fd9a\", \"38fff8\", \"68fdff\", \"9698ed\", \"c0c0c0\", \"fe0000\", \"f8a102\", \"ffcc67\", \"f8ff00\", \"34ff34\",\n\t\"68cbd0\", \"34cdf9\", \"6665cd\", \"9b9b9b\", \"cb0000\", \"f56b00\", \"ffcb2f\", \"ffc702\", \"32cb00\", \"00d2cb\", \"3166ff\", \"6434fc\", \"656565\",\n\t\"9a0000\", \"ce6301\", \"cd9934\", \"999903\", \"009901\", \"329a9d\", \"3531ff\", \"6200c9\", \"343434\", \"680100\", \"963400\", \"986536\", \"646809\",\n\t\"036400\", \"34696d\", \"00009b\", \"303498\", \"000000\", \"330001\", \"643403\", \"663234\", \"343300\", \"013300\", \"003532\", \"010066\", \"340096\" ];\n</script>\n\n<script setup lang=\"ts\">\n\tconst props = defineProps<{\n\t\tmodelValue: string;\n\t\tvalidators?: Array<Validator<string>>;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [colour: string];\n\t}>();\n\n\tconst gridRef = ref<HTMLElement>();\n\n\tconst value = computed({\n\t\tget: () => props.modelValue,\n\t\tset: (value) => {\n\t\t\temit(\"update:modelValue\", value!);\n\t\t}\n\t});\n\n\tconst val = computed(() => normalizeData(value.value ?? \"\"));\n\n\tconst previewStyle = computed((): StyleValue => {\n\t\tconst bg = isValidColour(value.value) ? value.value : 'ffffff';\n\t\treturn {\n\t\t\tbackgroundColor: `#${bg}`,\n\t\t\tcolor: makeTextColour(`#${bg}`)\n\t\t};\n\t});\n\n\tfunction handleChange(val: any): void {\n\t\tvalue.value = normalizeData(val).hex.replace(/^#/, '').toLowerCase();\n\t}\n\n\tfunction handleKeyDown(event: KeyboardEvent): void {\n\t\tif (gridRef.value) {\n\t\t\tconst newVal = arrowNavigation(colours, value.value, gridRef.value, event);\n\t\t\tif (newVal) {\n\t\t\t\temit('update:modelValue', newVal);\n\t\t\t\tvoid nextTick(() => {\n\t\t\t\t\t(gridRef.value?.querySelector(\".active a\") as HTMLAnchorElement | undefined)?.focus();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<template>\n\t<Picker\n\t\tcustomClass=\"fm-colour-field\"\n\t\tv-model=\"value\"\n\t\t@keydown=\"handleKeyDown\"\n\t\t:validators=\"[...props.validators ?? [], validateColour]\"\n\t\t:previewStyle=\"previewStyle\"\n\t>\n\t\t<template #preview>\n\t\t\t<span style=\"width: 1.4em\"></span>\n\t\t</template>\n\n\t\t<template #default=\"{ isModal }\">\n\t\t\t<div class=\"fm-colour-field-content\">\n\t\t\t\t<input\n\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\tv-show=\"isModal\"\n\t\t\t\t\tv-model=\"value\"\n\t\t\t\t\t:style=\"previewStyle\"\n\t\t\t\t/>\n\t\t\t\t<Saturation :value=\"val\" @change=\"handleChange\"></Saturation>\n\t\t\t\t<Hue :value=\"val\" @change=\"handleChange\"></Hue>\n\t\t\t\t<ul ref=\"gridRef\">\n\t\t\t\t\t<li v-for=\"colour in colours\" :key=\"colour\" :class=\"{ active: value == colour }\">\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t:style=\"{ backgroundColor: `#${colour}` }\"\n\t\t\t\t\t\t\t@click=\"emit('update:modelValue', colour)\"\n\t\t\t\t\t\t\ttabindex=\"-1\"\n\t\t\t\t\t\t></a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</template>\n\t</Picker>\n</template>\n\n<style lang=\"scss\">\n\t.fm-colour-field {\n\t\t.fm-colour-field-content {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\talign-items: center;\n\n\t\t\t> * + * {\n\t\t\t\tmargin-top: 0.5rem;\n\t\t\t}\n\n\t\t\t.vc-saturation {\n\t\t\t\tposition: relative;\n\t\t\t\tflex-basis: 100px;\n\t\t\t\twidth: 100%;\n\t\t\t}\n\n\t\t\t.vc-hue {\n\t\t\t\tposition: static;\n\t\t\t\theight: 15px;\n\t\t\t\twidth: 100%;\n\t\t\t\tflex-shrink: 0;\n\t\t\t}\n\n\t\t\tul {\n\t\t\t\tmargin-left: 0;\n\t\t\t\tmargin-bottom: 0;\n\t\t\t\tpadding: 0;\n\t\t\t\tlist-style-type: none;\n\t\t\t\tdisplay: grid;\n\t\t\t\tgrid-template-columns: repeat(9, 15px);\n\t\t\t\tgrid-auto-rows: 15px;\n\t\t\t\tgap: 5px;\n\n\t\t\t\tli {\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t}\n\n\t\t\t\ta {\n\t\t\t\t\tflex-grow: 1;\n\t\t\t\t\tborder-radius: 3px;\n\t\t\t\t\tbox-shadow: inset 0 0 0 1px rgb(0 0 0 / 15%);\n\t\t\t\t\tborder: none;\n\t\t\t\t}\n\n\t\t\t\tli.active a {\n\t\t\t\t\tbox-shadow: inset 0 0 0 2px rgb(0 0 0 / 60%), 0 0 3px rgb(0 0 0 / 60%);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { quoteHtml } from \"facilmap-utils\";\n\timport { computed, ref, watchEffect } from \"vue\";\n\n\tconst props = defineProps<{\n\t\tvalue: string | undefined;\n\t\titems: Record<string, string>;\n\t\t/** If true, tabindex=\"-1\" will be set on all elements. */\n\t\tnoFocus?: boolean;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\tclick: [item: string];\n\t}>();\n\n\tconst containerRef = ref<HTMLElement>();\n\n\tconst code = computed(() => Object.entries(props.items).map(([key, val]) => (`\n\t\t<li class=\"list-group-item list-group-item-action\" data-fm-item=\"${quoteHtml(key)}\">\n\t\t\t<a href=\"javascript:\"${props.noFocus ? ` tabindex=\"-1\"` : \"\"}>\n\t\t\t\t${val}\n\t\t\t</a>\n\t\t</li>\n\t`)).join(''));\n\n\twatchEffect(() => {\n\t\tif (containerRef.value) {\n\t\t\tfor (const el of containerRef.value.querySelectorAll(\".active\")) {\n\t\t\t\tel.classList.remove(\"active\");\n\t\t\t\tel.removeAttribute(\"aria-current\");\n\t\t\t}\n\n\t\t\tconst active = props.value != null && [...containerRef.value.querySelectorAll<HTMLElement>(\"[data-fm-item]\")].find((el) => el.getAttribute(\"data-fm-item\") === props.value);\n\t\t\tif (active) {\n\t\t\t\tactive.classList.add(\"active\");\n\t\t\t\tactive.setAttribute(\"aria-current\", \"true\");\n\t\t\t}\n\t\t}\n\t});\n\n\tfunction handleClick(e: MouseEvent): void {\n\t\tconst item = (e.target as HTMLElement).closest(\"[data-fm-item]\")?.getAttribute(\"data-fm-item\");\n\t\tif (item)\n\t\t\temit(\"click\", item);\n\t}\n\n\tdefineExpose({\n\t\tcontainerRef\n\t});\n</script>\n\n<template>\n\t<ul\n\t\tref=\"containerRef\"\n\t\tv-show=\"Object.keys(items).length > 0\"\n\t\tv-html=\"code\"\n\t\t@click=\"handleClick\"\n\t\tclass=\"fm-prerendered-list list-group\"\n\t></ul>\n</template>\n\n<style lang=\"scss\">\n\t.fm-prerendered-list.fm-prerendered-list.fm-prerendered-list {\n\t\tborder-radius: unset;\n\n\t\tli {\n\t\t\tpadding: 0;\n\t\t\tborder: none;\n\t\t\tborder-radius: unset;\n\t\t}\n\t}\n</style>","<script lang=\"ts\">\n\timport { getMarkerUrl, shapeList } from \"facilmap-leaflet\";\n\timport { quoteHtml } from \"facilmap-utils\";\n\timport Picker from \"./picker.vue\";\n\timport type { Shape } from \"facilmap-types\";\n\timport { arrowNavigation } from \"../../utils/ui\";\n\timport PrerenderedList from \"./prerendered-list.vue\";\n\timport { computed, nextTick, ref } from \"vue\";\n\timport type { Validator } from \"./validated-form/validated-field.vue\";\n\timport { computedAsync } from \"../../utils/vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst items = computedAsync(async () => {\n\t\tconst list = await Promise.all(shapeList.map(async (s) => (\n\t\t\t[s, `<img src=\"${quoteHtml(await getMarkerUrl(\"#000000\", 25, undefined, s))}\">`] as const\n\t\t)));\n\t\treturn Object.fromEntries(list);\n\t});\n</script>\n\n<script setup lang=\"ts\">\n\tconst i18n = useI18n();\n\n\tconst gridRef = ref<InstanceType<typeof PrerenderedList>>();\n\n\tconst props = defineProps<{\n\t\tmodelValue: Shape;\n\t\tid?: string;\n\t\tvalidators?: Array<Validator<string>>;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [value: Shape];\n\t}>();\n\n\tconst value = computed({\n\t\tget: () => props.modelValue,\n\t\tset: (value) => {\n\t\t\temit(\"update:modelValue\", value);\n\t\t}\n\t});\n\n\tconst valueSrc = computedAsync(async () => await getMarkerUrl(\"#000000\", 21, undefined, props.modelValue));\n\n\tfunction validateShape(shape: string) {\n\t\tif (shape && !shapeList.includes(shape)) {\n\t\t\treturn i18n.t(\"shape-picker.unknown-shape-error\");\n\t\t}\n\t}\n\n\tfunction handleClick(shape: Shape, close: () => void): void {\n\t\temit(\"update:modelValue\", shape);\n\t\tclose();\n\t}\n\n\tfunction handleKeyDown(event: KeyboardEvent): void {\n\t\tconst newVal = arrowNavigation(Object.keys(items), props.modelValue, gridRef.value!.containerRef!, event);\n\t\tif (newVal) {\n\t\t\temit(\"update:modelValue\", newVal);\n\t\t\tvoid nextTick(() => {\n\t\t\t\tgridRef.value?.containerRef?.querySelector<HTMLElement>(\".active > a\")?.focus();\n\t\t\t});\n\t\t}\n\t}\n</script>\n\n<template>\n\t<Picker\n\t\t:id=\"id\"\n\t\tv-model=\"value\"\n\t\tcustomClass=\"fm-shape-field\"\n\t\t:validators=\"[...props.validators ?? [], validateShape]\"\n\t\t@keydown=\"handleKeyDown\"\n\t>\n\t\t<template #preview>\n\t\t\t<span style=\"width: 1.4em\"><img :src=\"valueSrc\"></span>\n\t\t</template>\n\n\t\t<template #default=\"{ close }\">\n\t\t\t<div v-if=\"!items\" class=\"d-flex align-items-center justify-content-center p-4\">\n\t\t\t\t<div class=\"spinner-border\"></div>\n\t\t\t</div>\n\n\t\t\t<template v-else>\n\t\t\t\t<div v-if=\"Object.keys(items).length == 0\" class=\"alert alert-danger mt-2 mb-1\">{{i18n.t(\"shape-picker.no-shapes-error\")}}</div>\n\n\t\t\t\t<PrerenderedList\n\t\t\t\t\t:items=\"items\"\n\t\t\t\t\t:value=\"modelValue\"\n\t\t\t\t\t@click=\"handleClick($event, close)\"\n\t\t\t\t\tref=\"gridRef\"\n\t\t\t\t\tnoFocus\n\t\t\t\t></PrerenderedList>\n\t\t\t</template>\n\t\t</template>\n\t</Picker>\n</template>\n\n<style lang=\"scss\">\n\t.fm-shape-field {\n\t\tmax-width: none;\n\n\t\t.popover-body {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\n\t\t\tul {\n\t\t\t\tmax-height: 200px;\n\t\t\t}\n\t\t}\n\n\t\tul {\n\t\t\tmargin: 10px 0 0 0;\n\t\t\tpadding: 0;\n\t\t\tlist-style-type: none;\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: repeat(5, 40px);\n\t\t\toverflow-y: auto;\n\n\t\t\tli {\n\t\t\t\tdisplay: flex;\n\t\t\t}\n\n\t\t\ta {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\tflex-grow: 1;\n\t\t\t\tcolor: inherit;\n\t\t\t\tpadding: 5px;\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { coreSymbolList, getSymbolHtml } from \"facilmap-leaflet\";\n\timport { vHtmlAsync } from \"../../utils/vue\";\n\timport { computed, watchEffect } from \"vue\";\n\n\tconst props = withDefaults(defineProps<{\n\t\ticon: string | undefined;\n\t\talt?: string; // TODO\n\t\tsize?: string;\n\t\tasync?: boolean;\n\t}>(), {\n\t\tsize: \"1.35em\"\n\t});\n\n\twatchEffect(() => {\n\t\tif (props.icon && !props.async && !coreSymbolList.includes(props.icon)) {\n\t\t\tconsole.warn(`Icon \"${props.icon}\" is not in core icons.`);\n\t\t}\n\t});\n\n\tconst iconCodeP = computed(() => getSymbolHtml(\"currentColor\", props.size, props.icon));\n</script>\n\n<template>\n\t<span class=\"fm-icon\" v-html-async=\"iconCodeP\"></span>\n</template>\n\n<style lang=\"scss\">\n</style>","<script lang=\"ts\">\n\timport { getSymbolHtml, symbolList } from \"facilmap-leaflet\";\n\timport Icon from \"./icon.vue\";\n\timport Picker from \"./picker.vue\";\n\timport { arrowNavigation } from \"../../utils/ui\";\n\timport PrerenderedList from \"./prerendered-list.vue\";\n\timport { computed, nextTick, ref } from \"vue\";\n\timport type { Validator } from \"./validated-form/validated-field.vue\";\n\timport { computedAsync } from \"../../utils/vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tlet allItemsP: Promise<Record<string, string>>;\n\tasync function getAllItems(): Promise<Record<string, string>> {\n\t\tif (!allItemsP) { // eslint-disable-line @typescript-eslint/no-misused-promises\n\t\t\tallItemsP = Promise.all(symbolList.map(async (s) => (\n\t\t\t\t[s, await getSymbolHtml(\"currentColor\", \"1.5em\", s)] as const\n\t\t\t))).then((l) => Object.fromEntries(l));\n\t\t}\n\t\treturn await allItemsP;\n\t}\n</script>\n\n<script setup lang=\"ts\">\n\tconst i18n = useI18n();\n\n\tconst gridRef = ref<InstanceType<typeof PrerenderedList>>();\n\n\tconst props = defineProps<{\n\t\tmodelValue: string;\n\t\tid?: string;\n\t\tvalidators?: Array<Validator<string>>;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [value: string];\n\t}>();\n\n\tconst value = computed({\n\t\tget: () => props.modelValue,\n\t\tset: (value) => {\n\t\t\temit(\"update:modelValue\", value!);\n\t\t}\n\t});\n\n\tconst filter = ref(\"\");\n\tconst filterRef = ref<HTMLElement>();\n\n\tconst items = computedAsync(async () => {\n\t\treturn Object.fromEntries<string>((await Promise.all([\n\t\t\t(async (): Promise<Array<[string, string]>> => {\n\t\t\t\tif (filter.value.length == 1) {\n\t\t\t\t\treturn [[filter.value, await getSymbolHtml(\"currentColor\", \"1.5em\", filter.value)]];\n\t\t\t\t} else {\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t})(),\n\t\t\t(async (): Promise<Array<[string, string]>> => {\n\t\t\t\tif (props.modelValue?.length == 1 && props.modelValue != filter.value) {\n\t\t\t\t\treturn [[props.modelValue, await getSymbolHtml(\"currentColor\", \"1.5em\", props.modelValue)]];\n\t\t\t\t} else {\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t})(),\n\t\t\t(async (): Promise<Array<[string, string]>> => {\n\t\t\t\tconst lowerFilter = filter.value.trim().toLowerCase();\n\t\t\t\treturn Object.entries(await getAllItems()).flatMap(([k, v]) => {\n\t\t\t\t\tif (k.toLowerCase().includes(lowerFilter)) {\n\t\t\t\t\t\treturn [[k, v]];\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn [];\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t})()\n\t\t])).flat());\n\t});\n\n\tfunction validateSymbol(symbol: string) {\n\t\tif (symbol && symbol.length !== 1 && !symbolList.includes(symbol)) {\n\t\t\treturn i18n.t(\"symbol-picker.unknown-icon-error\");\n\t\t}\n\t}\n\n\tfunction handleClick(symbol: string, close: () => void): void {\n\t\temit(\"update:modelValue\", symbol);\n\t\tclose();\n\t}\n\n\tasync function handleKeyDown(event: KeyboardEvent): Promise<void> {\n\t\tif (items.value) {\n\t\t\tconst newVal = arrowNavigation(Object.keys(items.value), props.modelValue, gridRef.value!.containerRef!, event);\n\t\t\tif (newVal) {\n\t\t\t\tfilterRef.value?.focus();\n\t\t\t\temit(\"update:modelValue\", newVal);\n\t\t\t\tawait nextTick();\n\t\t\t\tgridRef.value?.containerRef?.querySelector<HTMLElement>(\".active\")?.focus();\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction handleFocusPopover() {\n\t\tfilterRef.value?.focus();\n\t}\n</script>\n\n<template>\n\t<Picker\n\t\t:id=\"id\"\n\t\tv-model=\"value\"\n\t\tcustomClass=\"fm-symbol-field\"\n\t\t:validators=\"[...props.validators ?? [], validateSymbol]\"\n\t\t@keydown=\"handleKeyDown\"\n\t\tenforceElementWidth\n\t\t@focusPopover=\"handleFocusPopover()\"\n\t>\n\t\t<template #preview>\n\t\t\t<Icon :icon=\"modelValue\" async></Icon>\n\t\t</template>\n\n\t\t<template #default=\"{ close }\">\n\t\t\t<input\n\t\t\t\ttype=\"search\"\n\t\t\t\tclass=\"form-control fm-keyboard-navigation-exception\"\n\t\t\t\tv-model=\"filter\"\n\t\t\t\t:placeholder=\"i18n.t('symbol-picker.filter-placeholder')\"\n\t\t\t\tautocomplete=\"off\"\n\t\t\t\tref=\"filterRef\"\n\t\t\t\ttabindex=\"-1\"\n\t\t\t/>\n\n\t\t\t<div v-if=\"!items\" class=\"d-flex align-items-center justify-content-center p-4\">\n\t\t\t\t<div class=\"spinner-border\"></div>\n\t\t\t</div>\n\n\t\t\t<template v-else>\n\t\t\t\t<div v-if=\"Object.keys(items).length == 0\" class=\"alert alert-danger mt-2 mb-1\">{{i18n.t(\"symbol-picker.no-icons-found-error\")}}</div>\n\n\t\t\t\t<PrerenderedList\n\t\t\t\t\t:items=\"items\"\n\t\t\t\t\t:value=\"modelValue\"\n\t\t\t\t\tnoFocus\n\t\t\t\t\t@click=\"handleClick($event, close)\"\n\t\t\t\t\tref=\"gridRef\"\n\t\t\t\t></PrerenderedList>\n\t\t\t</template>\n\t\t</template>\n\t</Picker>\n</template>\n\n<style lang=\"scss\">\n\t.fm-symbol-field {\n\t\t.popover-body {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\n\t\t\tul {\n\t\t\t\tmax-height: 200px;\n\t\t\t}\n\t\t}\n\n\t\tul {\n\t\t\tmargin: 10px 0 0 0;\n\t\t\tpadding: 0;\n\t\t\tlist-style-type: none;\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: repeat(auto-fill, 37px);\n\t\t\toverflow-y: auto;\n\n\t\t\tli {\n\t\t\t\tdisplay: flex;\n\t\t\t}\n\n\t\t\ta {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\tflex-grow: 1;\n\t\t\t\tcolor: inherit;\n\t\t\t\tpadding: 5px 8px;\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { type SlotsType, computed, defineComponent, h, ref, shallowRef, useSlots, watch, watchEffect } from \"vue\";\n\timport { getMaxSizeModifiers, type ButtonSize, type ButtonVariant, useMaxBreakpoint } from \"../../utils/bootstrap\";\n\timport Dropdown from \"bootstrap/js/dist/dropdown\";\n\timport vLinkDisabled from \"../../utils/link-disabled\";\n\timport type { TooltipPlacement } from \"../../utils/tooltip\";\n\timport AttributePreservingElement from \"./attribute-preserving-element.vue\";\n\n\tconst props = withDefaults(defineProps<{\n\t\tisOpen?: boolean;\n\t\tnoWrapper?: boolean;\n\t\tclass?: string;\n\t\tbuttonClass?: string;\n\t\tmenuClass?: string;\n\t\tvariant?: ButtonVariant;\n\t\tnoCaret?: boolean;\n\t\tlabel?: string;\n\t\tsize?: ButtonSize;\n\t\tisDisabled?: boolean;\n\t\t/** Disables the dropdown and shows a spinner on the button. */\n\t\tisBusy?: boolean;\n\t\t/** Shows a spinner instead of the dropdown items. */\n\t\tisLoading?: boolean;\n\t\ttag?: string;\n\t\tisLink?: boolean;\n\t\ttabindex?: number;\n\t\ttooltip?: string; // TODO\n\t\ttooltipPlacement?: TooltipPlacement;\n\t\tmaxWidth?: string;\n\t}>(), {\n\t\tisOpen: undefined,\n\t\tnoWrapper: false,\n\t\tvariant: \"secondary\",\n\t\tnoCaret: false,\n\t\ttag: \"div\"\n\t});\n\n\tconst emit = defineEmits<{\n\t\t\"update:isOpen\": [boolean];\n\t}>();\n\n\tconst buttonRef = ref<InstanceType<typeof AttributePreservingElement>>();\n\tconst dropdownRef = shallowRef<Dropdown>();\n\n\tconst isNarrow = useMaxBreakpoint(\"sm\");\n\n\tclass CustomDropdown extends Dropdown {\n\t\t_detectNavbar() {\n\t\t\t// Bootstrap Dropdown disables the \"applyStyles\" modifier if the dropdown trigger is a descendant\n\t\t\t// of a navbar, causing the dropdown to ignore any popper styles and be positioned statically\n\t\t\t// instead.\n\t\t\t// In wide mode, we want to use the regular popper positioning so that we can rely on the maxSizeModifers.\n\t\t\t// In narrow mode, navbars are collapsed and dropdowns expand in between to navbar items, rather than\n\t\t\t// being absolutely positioned. We want to keep that behaviour.\n\t\t\tif (isNarrow.value) {\n\t\t\t\t// @ts-ignore\n\t\t\t\treturn super._detectNavbar();\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\twatch(() => buttonRef.value?.elementRef, (newRef, oldRef, onCleanup) => {\n\t\tif (newRef) {\n\t\t\tdropdownRef.value = new CustomDropdown(newRef, {\n\t\t\t\tpopperConfig: (defaultConfig) => ({\n\t\t\t\t\t...defaultConfig,\n\t\t\t\t\tmodifiers: [\n\t\t\t\t\t\t...(defaultConfig.modifiers ?? []),\n\t\t\t\t\t\t...getMaxSizeModifiers({ maxWidth: props.maxWidth })\n\t\t\t\t\t],\n\t\t\t\t\tstrategy: \"fixed\"\n\t\t\t\t})\n\t\t\t});\n\t\t\tonCleanup(() => {\n\t\t\t\tdropdownRef.value!.dispose();\n\t\t\t\tdropdownRef.value = undefined;\n\t\t\t});\n\t\t}\n\t}, { immediate: true });\n\n\twatchEffect(() => {\n\t\tif (dropdownRef.value) {\n\t\t\tif (props.isOpen === true) {\n\t\t\t\tdropdownRef.value.show();\n\t\t\t} else if (props.isOpen === false) {\n\t\t\t\tdropdownRef.value.hide();\n\t\t\t}\n\t\t}\n\t});\n\n\tconst Wrapper = defineComponent({\n\t\tslots: Object as SlotsType<{\n\t\t\tdefault: void\n\t\t}>,\n\n\t\tsetup(innerProps, { slots }) {\n\t\t\treturn () => {\n\t\t\t\tif (props.noWrapper) {\n\t\t\t\t\treturn slots.default();\n\t\t\t\t} else {\n\t\t\t\t\treturn h(props.tag, {\n\t\t\t\t\t\tclass: [\"dropdown\", \"fm-dropdown-menu-container\", props.class]\n\t\t\t\t\t}, slots.default());\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n\n\tconst slots = useSlots();\n\tconst isEmptyLabel = computed(() => !slots.label && !props.label);\n\n\tconst buttonClass = computed((): string[] => [\n\t\t\"fm-dropdown-menu-toggle\",\n\t\t...(props.buttonClass != null ? [props.buttonClass] : []),\n\t\t...(props.size ? [`btn-${props.size}`] : []),\n\t\t...(props.noCaret ? [] : [\"dropdown-toggle\"]),\n\t\t...(props.isLink ? [] : [\"btn\", `btn-${props.variant}`]),\n\t\t...(isEmptyLabel.value ? [\"isEmptyLabel\"] : [])\n\t]);\n\n\tconst menuClass = computed((): string[] => [\n\t\t\"fm-dropdown-menu-menu\",\n\t\t\"dropdown-menu\",\n\t\t\"text-break\",\n\t\t...(props.menuClass != null ? [props.menuClass] : []),\n\t\t...(props.isLoading ? [\"isLoading\"] : [])\n\t]);\n\n\tfunction handleHidden() {\n\t\tif (props.isOpen !== false) {\n\t\t\temit(\"update:isOpen\", false);\n\t\t}\n\t}\n\n\tfunction handleShown() {\n\t\tif (props.isOpen !== true) {\n\t\t\temit(\"update:isOpen\", true);\n\t\t}\n\t}\n\n\twatchEffect(() => {\n\t\tif (props.isDisabled || props.isBusy) {\n\t\t\tdropdownRef.value?.hide();\n\t\t}\n\t});\n\n</script>\n\n<template>\n\t<Wrapper>\n\t\t<template v-if=\"props.isLink\">\n\t\t\t<AttributePreservingElement\n\t\t\t\ttag=\"a\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t:class=\"buttonClass\"\n\t\t\t\tv-on=\"{\n\t\t\t\t\t'hidden.bs.dropdown': handleHidden,\n\t\t\t\t\t'shown.bs.dropdown': handleShown\n\t\t\t\t}\"\n\t\t\t\tref=\"buttonRef\"\n\t\t\t\tdata-bs-toggle=\"dropdown\"\n\t\t\t\tv-link-disabled=\"props.isDisabled || props.isBusy\"\n\t\t\t\t:tabindex=\"props.tabindex\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>\n\t\t\t\t<slot name=\"label\">\n\t\t\t\t\t<div v-if=\"props.isBusy\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t{{props.label}}\n\t\t\t\t</slot>\n\t\t\t</AttributePreservingElement>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<AttributePreservingElement\n\t\t\t\ttag=\"button\"\n\t\t\t\ttype=\"button\"\n\t\t\t\t:class=\"buttonClass\"\n\t\t\t\tv-on=\"{\n\t\t\t\t\t'hidden.bs.dropdown': handleHidden,\n\t\t\t\t\t'shown.bs.dropdown': handleShown\n\t\t\t\t}\"\n\t\t\t\tref=\"buttonRef\"\n\t\t\t\tdata-bs-toggle=\"dropdown\"\n\t\t\t\t:disabled=\"props.isDisabled || props.isBusy\"\n\t\t\t\t:tabindex=\"props.tabindex\"\n\t\t\t>\n\t\t\t\t<slot name=\"label\">\n\t\t\t\t\t<div v-if=\"props.isBusy\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t{{props.label}}\n\t\t\t\t</slot>\n\t\t\t</AttributePreservingElement>\n\t\t</template>\n\n\t\t<AttributePreservingElement\n\t\t\ttag=\"ul\"\n\t\t\t:class=\"menuClass\"\n\t\t>\n\t\t\t<template v-if=\"props.isLoading\">\n\t\t\t\t<li class=\"spinner-border\"></li>\n\t\t\t</template>\n\t\t\t<template v-else>\n\t\t\t\t<slot></slot>\n\t\t\t</template>\n\t\t</AttributePreservingElement>\n\t</Wrapper>\n</template>\n\n<style lang=\"scss\">\n\t.fm-dropdown-menu-toggle.isEmptyLabel::after {\n\t\tmargin-left: 0;\n\t}\n\n\t.fm-dropdown-menu-menu {\n\t\toverflow: auto;\n\n\t\t.dropdown-item {\n\t\t\t// Wrap in connection with the text-break class on the menu\n\t\t\twhite-space: normal;\n\t\t}\n\t}\n\n\t.fm-dropdown-menu-menu.isLoading.show {\n\t\tdisplay: flex !important;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t}\n</style>","<script setup lang=\"ts\">\n\timport type { RouteMode as RouteModeType } from \"facilmap-types\";\n\timport { type DecodedRouteMode, decodeRouteMode, encodeRouteMode } from \"facilmap-utils\";\n\timport Icon from \"./icon.vue\";\n\timport { computed, ref, watch } from \"vue\";\n\timport { getUniqueId } from \"../../utils/utils\";\n\timport vTooltip, { type TooltipPlacement } from \"../../utils/tooltip\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\timport { injectContextRequired } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\n\ttype Mode = Exclude<DecodedRouteMode['mode'], 'track'>;\n\ttype Type = DecodedRouteMode['type'];\n\n\tconst context = injectContextRequired();\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tmodelValue: RouteModeType;\n\t\ttabindex?: number;\n\t\tdisabled?: boolean;\n\t\ttooltipPlacement?: TooltipPlacement;\n\t}>(), {\n\t\ttooltipPlacement: \"top\"\n\t});\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [value: RouteModeType];\n\t}>();\n\n\tconst id = getUniqueId(\"fm-route-mode\");\n\n\tconst constants = computed((): {\n\t\tmodes: Array<Mode>;\n\t\tmodeIcon: Record<Mode, string>;\n\t\tmodeAlt: Record<Mode, string>;\n\t\tmodeTitle: Record<Mode, string>;\n\t\ttypes: Record<Mode, Array<Type>>;\n\t\ttypeText: Record<Mode, Partial<Record<Type, string>>>;\n\t\tpreferences: Array<DecodedRouteMode['preference']>;\n\t\tpreferenceText: Record<DecodedRouteMode['preference'], string>;\n\t\tavoid: DecodedRouteMode['avoid'];\n\t\tavoidAllowed: Record<DecodedRouteMode['avoid'][0], (mode: DecodedRouteMode['mode'], type: Type) => boolean>;\n\t\tavoidText: Record<DecodedRouteMode['avoid'][0], string>;\n\t} => ({\n\t\tmodes: [\"car\", \"bicycle\", \"pedestrian\", \"\"],\n\n\t\tmodeIcon: {\n\t\t\tcar: \"car\",\n\t\t\tbicycle: \"person-biking\",\n\t\t\tpedestrian: \"person-walking\",\n\t\t\t\"\": \"slash\"\n\t\t},\n\n\t\tmodeAlt: {\n\t\t\tcar: i18n.t(\"route-mode.car-alt\"),\n\t\t\tbicycle: i18n.t(\"route-mode.bicycle-alt\"),\n\t\t\tpedestrian: i18n.t(\"route-mode.pedestrian-alt\"),\n\t\t\t\"\": i18n.t(\"route-mode.straight-alt\")\n\t\t},\n\n\t\tmodeTitle: {\n\t\t\tcar: i18n.t(\"route-mode.car-title\"),\n\t\t\tbicycle: i18n.t(\"route-mode.bicycle-title\"),\n\t\t\tpedestrian: i18n.t(\"route-mode.pedestrian-title\"),\n\t\t\t\"\": i18n.t(\"route-mode.straight-title\")\n\t\t},\n\n\t\ttypes: {\n\t\t\tcar: [\"\", \"hgv\"],\n\t\t\tbicycle: [\"\", \"road\", \"mountain\", \"electric\"],\n\t\t\tpedestrian: [\"\", \"hiking\", \"wheelchair\"],\n\t\t\t\"\": [\"\"]\n\t\t},\n\n\t\ttypeText: {\n\t\t\tcar: {\n\t\t\t\t\"\": i18n.t(\"route-mode.car\"),\n\t\t\t\t\"hgv\": i18n.t(\"route-mode.hgv\")\n\t\t\t},\n\t\t\tbicycle: {\n\t\t\t\t\"\": i18n.t(\"route-mode.bicycle\"),\n\t\t\t\troad: i18n.t(\"route-mode.road-bike\"),\n\t\t\t\tmountain: i18n.t(\"route-mode.mountain-bike\"),\n\t\t\t\telectric: i18n.t(\"route-mode.electric-bike\")\n\t\t\t},\n\t\t\tpedestrian: {\n\t\t\t\t\"\": i18n.t(\"route-mode.walking\"),\n\t\t\t\thiking: i18n.t(\"route-mode.hiking\"),\n\t\t\t\twheelchair: i18n.t(\"route-mode.wheelchair\")\n\t\t\t},\n\t\t\t\"\": {\n\t\t\t\t\"\": i18n.t(\"route-mode.straight\")\n\t\t\t}\n\t\t},\n\n\t\tpreferences: [\"fastest\", \"shortest\"],\n\n\t\tpreferenceText: {\n\t\t\tfastest: i18n.t(\"route-mode.fastest\"),\n\t\t\tshortest: i18n.t(\"route-mode.shortest\")\n\t\t},\n\n\t\tavoid: [\"highways\", \"tollways\", \"ferries\", \"fords\", \"steps\"],\n\n\t\t// driving: highways, tollways, ferries\n\t\t// cycling: ferries, steps, fords\n\t\t// foot: ferries, fords, steps\n\t\t// wheelchair: ferries, steps\n\t\tavoidAllowed: {\n\t\t\thighways: (mode) => (mode == \"car\"),\n\t\t\ttollways: (mode) => (mode == \"car\"),\n\t\t\tferries: (mode) => (!!mode),\n\t\t\tfords: (mode, type) => (mode == \"bicycle\" || (mode == \"pedestrian\" && type != \"wheelchair\")),\n\t\t\tsteps: (mode) => (mode == \"bicycle\" || mode == \"pedestrian\")\n\t\t},\n\n\t\tavoidText: {\n\t\t\thighways: i18n.t(\"route-mode.avoid-highways\"),\n\t\t\ttollways: i18n.t(\"route-mode.avoid-toll-roads\"),\n\t\t\tferries: i18n.t(\"route-mode.avoid-ferries\"),\n\t\t\tfords: i18n.t(\"route-mode.avoid-fords\"),\n\t\t\tsteps: i18n.t(\"route-mode.avoid-steps\")\n\t\t}\n\t}));\n\n\tconst decodedMode = ref(decodeRouteMode(props.modelValue));\n\n\twatch(() => props.modelValue, () => {\n\t\tdecodedMode.value = decodeRouteMode(props.modelValue);\n\t});\n\n\twatch(() => decodedMode.value, () => {\n\t\tconst newValue = encodeRouteMode(decodedMode.value);\n\t\tif (newValue !== props.modelValue) {\n\t\t\temit(\"update:modelValue\", newValue);\n\t\t}\n\t}, { deep: true });\n\n\tconst types = computed(() => (Object.keys(constants.value.types) as Mode[]).map((mode) => constants.value.types[mode].map((type) => ([mode, type] as [Mode, Type]))).flat());\n\n\tfunction isTypeActive(mode: DecodedRouteMode['mode'], type: DecodedRouteMode['type']): boolean {\n\t\treturn (!mode && !decodedMode.value.mode || mode == decodedMode.value.mode) && (!type && !decodedMode.value.type || type == decodedMode.value.type);\n\t}\n\n\tfunction setMode(mode: DecodedRouteMode['mode'], type: DecodedRouteMode['type']): void {\n\t\tdecodedMode.value.mode = mode;\n\t\tdecodedMode.value.type = type;\n\n\t\tif(decodedMode.value.avoid) {\n\t\t\tfor(let i=0; i < decodedMode.value.avoid.length; i++) {\n\t\t\t\tif(!constants.value.avoidAllowed[decodedMode.value.avoid[i]](decodedMode.value.mode, decodedMode.value.type))\n\t\t\t\t\tdecodedMode.value.avoid.splice(i--, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction toggleAvoid(avoid: DecodedRouteMode['avoid'][0]): void {\n\t\tif(!decodedMode.value.avoid)\n\t\t\tdecodedMode.value.avoid = [];\n\n\t\tlet idx = decodedMode.value.avoid.indexOf(avoid);\n\t\tif(idx == -1)\n\t\t\tdecodedMode.value.avoid.push(avoid);\n\t\telse\n\t\t\tdecodedMode.value.avoid.splice(idx, 1);\n\t}\n</script>\n\n<template>\n\t<div class=\"fm-route-mode position-relative\">\n\t\t<div class=\"btn-group\" role=\"group\">\n\t\t\t<template v-for=\"(mode, idx) in constants.modes\" :key=\"mode\">\n\t\t\t\t<input\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tclass=\"btn-check\"\n\t\t\t\t\t:id=\"`${id}-mode-${mode}`\"\n\t\t\t\t\t:name=\"`${id}-mode`\"\n\t\t\t\t\tv-model=\"decodedMode.mode\"\n\t\t\t\t\t:value=\"mode\"\n\t\t\t\t\t:tabindex=\"tabindex != null ? tabindex + idx : undefined\"\n\t\t\t\t\t:disabled=\"disabled\"\n\t\t\t\t/>\n\t\t\t\t<label class=\"btn btn-secondary\" :for=\"`${id}-mode-${mode}`\" v-tooltip:[tooltipPlacement]=\"constants.modeTitle[mode]\">\n\t\t\t\t\t<Icon :icon=\"constants.modeIcon[mode]\" :alt=\"constants.modeAlt[mode]\"></Icon>\n\t\t\t\t</label>\n\t\t\t</template>\n\n\t\t\t<div v-if=\"context.settings.advancedRouting\" class=\"btn-group\">\n\t\t\t\t<DropdownMenu\n\t\t\t\t\t:tabindex=\"tabindex != null ? tabindex + constants.modes.length : undefined\"\n\t\t\t\t\ttooltip=\"Customize\"\n\t\t\t\t\t:tooltipPlacement=\"tooltipPlacement\"\n\t\t\t\t\t:isDisabled=\"disabled\"\n\t\t\t\t\tnoWrapper\n\t\t\t\t\tmenuClass=\"fm-route-mode-customize\"\n\t\t\t\t\tmaxWidth=\"32rem\"\n\t\t\t\t>\n\t\t\t\t\t<template #label>\n\t\t\t\t\t\t<Icon icon=\"cog\" :alt=\"i18n.t('route-mode.custom-alt')\"/>\n\t\t\t\t\t</template>\n\n\t\t\t\t\t<template #default>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t@click.capture.stop.prevent=\"decodedMode.details = !decodedMode.details\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon :icon=\"decodedMode.details ? 'check' : 'unchecked'\"></Icon> {{i18n.t(\"route-mode.load-details\")}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\n\t\t\t\t\t\t<li><hr class=\"dropdown-divider\"></li>\n\n\t\t\t\t\t\t<template v-for=\"t in types\" :key=\"t.id\">\n\t\t\t\t\t\t\t<li class=\"column\">\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\t@click.capture.stop.prevent=\"setMode(t[0], t[1])\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon :icon=\"isTypeActive(t[0], t[1]) ? 'check' : 'unchecked'\"></Icon> {{constants.typeText[t[0]][t[1]]}}\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</template>\n\n\t\t\t\t\t\t<li><hr class=\"dropdown-divider\"></li>\n\n\t\t\t\t\t\t<template v-for=\"(pText, p) in constants.preferenceText\" :key=\"p\">\n\t\t\t\t\t\t\t<template v-if=\"decodedMode.mode\">\n\t\t\t\t\t\t\t\t<li class=\"column\">\n\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\t\t@click.capture.stop.prevent=\"decodedMode.preference = p\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Icon :icon=\"decodedMode.preference == p ? 'check' : 'unchecked'\"></Icon> {{pText}}\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</template>\n\n\t\t\t\t\t\t<li><hr class=\"dropdown-divider\"></li>\n\n\t\t\t\t\t\t<template v-for=\"avoid in constants.avoid\" :key=\"avoid\">\n\t\t\t\t\t\t\t<template v-if=\"constants.avoidAllowed[avoid](decodedMode.mode, decodedMode.type)\">\n\t\t\t\t\t\t\t\t<li class=\"column\">\n\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\t\t@click.capture.stop.prevent=\"toggleAvoid(avoid)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Icon :icon=\"decodedMode.avoid.includes(avoid) ? 'check' : 'unchecked'\"></Icon> {{constants.avoidText[avoid]}}\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</template>\n\t\t\t\t</DropdownMenu>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-route-mode {\n\t\t.btn-group .btn {\n\t\t\tpadding-left: 10px;\n\t\t\tpadding-right: 10px;\n\t\t}\n\t}\n\n\t.fm-route-mode-customize {\n\t\tfont-size: 0; /* https://stackoverflow.com/a/5647640/242365 */\n\n\t\tli {\n\t\t\tfont-size: 14px;\n\n\t\t\t&.column {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 50%;\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport type { Field } from \"facilmap-types\";\n\timport { computed } from \"vue\";\n\timport { formatFieldName, normalizeFieldValue } from \"facilmap-utils\";\n\n\tconst props = withDefaults(defineProps<{\n\t\tfield: Field;\n\t\tignoreDefault?: boolean;\n\t\tmodelValue?: string;\n\t\tid?: string;\n\t\tshowCheckboxLabel?: boolean;\n\t}>(), {\n\t\tignoreDefault: false\n\t});\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [value: string | undefined];\n\t}>();\n\n\tconst value = computed<string | undefined>({\n\t\tget: () => normalizeFieldValue(props.field, props.modelValue, props.ignoreDefault),\n\t\tset: (value) => {\n\t\t\temit(\"update:modelValue\", value);\n\t\t}\n\t});\n</script>\n\n<template>\n\t<div class=\"fm-field-input\">\n\t\t<template v-if=\"field.type === 'textarea'\">\n\t\t\t<textarea class=\"form-control\" :id=\"id\" v-model=\"value\"></textarea>\n\t\t</template>\n\t\t<template v-else-if=\"field.type === 'dropdown'\">\n\t\t\t<select class=\"form-select\" :id=\"id\" v-model=\"value\">\n\t\t\t\t<option v-for=\"option in props.field.options\" :key=\"option.value\">\n\t\t\t\t\t{{option.value}}\n\t\t\t\t</option>\n\t\t\t</select>\n\t\t</template>\n\t\t<template v-else-if=\"field.type === 'checkbox'\">\n\t\t\t<template v-if=\"props.showCheckboxLabel\">\n\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"id\"\n\t\t\t\t\t\t:checked=\"value === '1'\"\n\t\t\t\t\t\t@input=\"value = ($event.target as HTMLInputElement).checked ? '1' : '0'\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label v-if=\"props.showCheckboxLabel\" :for=\"id\" class=\"form-check-label\">\n\t\t\t\t\t\t{{formatFieldName(field.name)}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t\t<template v-else>\n\t\t\t\t<input\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tclass=\"form-check-input fm-large-checkbox\"\n\t\t\t\t\t:id=\"id\"\n\t\t\t\t\t:checked=\"value === '1'\"\n\t\t\t\t\t@input=\"value = ($event.target as HTMLInputElement).checked ? '1' : '0'\"\n\t\t\t\t/>\n\t\t\t</template>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<input type=\"text\" class=\"form-control\" :id=\"id\" v-model=\"value\"/>\n\t\t</template>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-field-input {\n\n\t\t.fm-large-checkbox {\n\t\t\tmargin-top: 0;\n\t\t\theight: 1.5rem;\n\t\t\twidth: 1.5rem;\n\t\t}\n\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { computed } from \"vue\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport type { Validator } from \"./validated-form/validated-field.vue\";\n\timport ValidatedField from \"./validated-form/validated-field.vue\";\n\n\tconst props = defineProps<{\n\t\tmodelValue: number;\n\t\tvalidators?: Array<Validator<number>>;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [value: number];\n\t}>();\n\n\tconst value = computed({\n\t\tget: () => props.modelValue,\n\t\tset: (value) => {\n\t\t\temit(\"update:modelValue\", value!);\n\t\t}\n\t});\n</script>\n\n<template>\n\t<ValidatedField\n\t\t:value=\"value\"\n\t\t:validators=\"props.validators\"\n\t\tclass=\"fm-width-picker position-relative\"\n\t>\n\t\t<template #default=\"slotProps\">\n\t\t\t<input\n\t\t\t\ttype=\"range\"\n\t\t\t\tclass=\"custom-range\"\n\t\t\t\tmin=\"1\"\n\t\t\t\tv-model.number=\"value\"\n\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\tv-tooltip=\"`${value}`\"\n\t\t\t/>\n\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t{{slotProps.validationError}}\n\t\t\t</div>\n\t\t</template>\n\t</ValidatedField>\n</template>\n\n<style lang=\"scss\">\n\t.fm-width-picker input {\n\t\twidth: 100%;\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { computed } from \"vue\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport ValidatedField, { type Validator } from \"./validated-form/validated-field.vue\";\n\n\tconst props = defineProps<{\n\t\tmodelValue: number;\n\t\tvalidators?: Array<Validator<number>>;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [value: number];\n\t}>();\n\n\tconst value = computed({\n\t\tget: () => props.modelValue,\n\t\tset: (value) => {\n\t\t\temit(\"update:modelValue\", value!);\n\t\t}\n\t});\n</script>\n\n<template>\n\t<ValidatedField\n\t\tclass=\"fm-size-picker position-relative\"\n\t\t:value=\"value\"\n\t\t:validators=\"props.validators\"\n\t>\n\t\t<template #default=\"slotProps\">\n\t\t\t<input\n\t\t\t\ttype=\"range\"\n\t\t\t\tclass=\"custom-range\"\n\t\t\t\tmin=\"15\"\n\t\t\t\tv-model.number=\"value\"\n\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\tv-tooltip=\"`${value}`\"\n\t\t\t/>\n\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t{{slotProps.validationError}}\n\t\t\t</div>\n\t\t</template>\n\t</ValidatedField>\n</template>\n\n<style lang=\"scss\">\n\t.fm-size-picker input {\n\t\twidth: 100%;\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { computed, readonly, ref, toRef } from \"vue\";\n\timport { useModal } from \"../../utils/modal\";\n\timport ValidatedForm, { type CustomSubmitEvent } from \"./validated-form/validated-form.vue\";\n\timport type { ThemeColour } from \"../../utils/bootstrap\";\n\timport { useUnloadHandler } from \"../../utils/utils\";\n\timport AttributePreservingElement from \"./attribute-preserving-element.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\ttitle?: string;\n\t\tclass?: string;\n\t\t/** If true, the user is prevented from closing the dialog. */\n\t\tnoCancel?: boolean;\n\t\tisBusy?: boolean;\n\t\t/** If true, the Save button will always be shown (also if isModified is false). */\n\t\tisCreate?: boolean;\n\t\t/** If false, a Close button will be shown instead of a Save button (except is isCreate is true). */\n\t\tisModified?: boolean;\n\t\tsize?: \"sm\" | \"default\" | \"lg\" | \"xl\";\n\t\tokLabel?: string;\n\t\tokVariant?: ThemeColour;\n\t\tformValidationError?: string | undefined;\n\t\taction?: string;\n\t\ttarget?: string;\n\t}>(), {\n\t\tisModified: false,\n\t\tsize: \"lg\"\n\t});\n\n\tconst emit = defineEmits<{\n\t\tshown: [];\n\t\thide: [];\n\t\thidden: [];\n\t\tsubmit: [event: CustomSubmitEvent];\n\t}>();\n\n\tconst validatedFormRef = ref<InstanceType<typeof ValidatedForm>>();\n\tconst isSubmitting = computed(() => validatedFormRef.value?.formData.isSubmitting);\n\n\tconst modalElementRef = ref<InstanceType<typeof AttributePreservingElement>>();\n\tconst modalRef = toRef(() => modalElementRef.value?.elementRef);\n\tconst modal = useModal(modalRef, {\n\t\tonShown: () => {\n\t\t\temit(\"shown\");\n\t\t},\n\t\tonHide: () => {\n\t\t\temit(\"hide\");\n\t\t},\n\t\tonHidden: () => {\n\t\t\temit(\"hidden\");\n\t\t},\n\t\tstatic: computed(() => isSubmitting.value || props.isBusy || props.noCancel || props.isModified),\n\t\tnoEscape: computed(() => isSubmitting.value || props.isBusy || props.noCancel)\n\t});\n\n\tuseUnloadHandler(() => props.isModified);\n\n\tconst isCloseButton = computed(() => !props.isCreate && !props.isModified);\n\n\tfunction handleSubmit(event: CustomSubmitEvent) {\n\t\tif (isCloseButton.value) {\n\t\t\tevent.preventDefault();\n\t\t\tmodal.hide();\n\t\t} else {\n\t\t\tif (!props.action) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\n\t\t\temit(\"submit\", event);\n\t\t}\n\t}\n\n\tconst expose = readonly({\n\t\tformData: toRef(() => validatedFormRef.value?.formData),\n\t\tmodal\n\t});\n\tdefineExpose(expose);\n</script>\n\n<template>\n\t<Teleport to=\"body\">\n\t\t<AttributePreservingElement\n\t\t\ttag=\"div\"\n\t\t\tclass=\"modal fade fm-modal\"\n\t\t\t:class=\"[\n\t\t\t\tprops.size !== 'default' ? `modal-${props.size}` : undefined,\n\t\t\t\tprops.class\n\t\t\t]\"\n\t\t\ttabindex=\"-1\"\n\t\t\taria-hidden=\"true\"\n\t\t\tref=\"modalElementRef\"\n\t\t>\n\t\t\t<div class=\"modal-dialog modal-dialog-scrollable\">\n\t\t\t\t<ValidatedForm\n\t\t\t\t\tclass=\"modal-content\"\n\t\t\t\t\t:action=\"props.action\"\n\t\t\t\t\t:target=\"props.target\"\n\t\t\t\t\t@submit=\"handleSubmit\"\n\t\t\t\t\tref=\"validatedFormRef\"\n\t\t\t\t\t:noValidate=\"isCloseButton\"\n\t\t\t\t\t:formValidationError=\"formValidationError\"\n\t\t\t\t>\n\t\t\t\t\t<div class=\"modal-header\">\n\t\t\t\t\t\t<h1 class=\"modal-title fs-5\">{{props.title}}</h1>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tv-if=\"!props.noCancel\"\n\t\t\t\t\t\t\t:disabled=\"isSubmitting || props.isBusy\"\n\t\t\t\t\t\t\t@click=\"modal.hide()\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"btn-close\"\n\t\t\t\t\t\t\t:aria-label=\"i18n.t('modal-dialog.close')\"\n\t\t\t\t\t\t></button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"modal-body\">\n\t\t\t\t\t\t<slot v-bind=\"expose\"></slot>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"modal-footer\">\n\t\t\t\t\t\t<slot name=\"footer-left\" v-bind=\"expose\"></slot>\n\n\t\t\t\t\t\t<div style=\"flex-grow: 1\"></div>\n\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tv-if=\"!props.noCancel && !isCloseButton\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t\t\t@click=\"modal.hide()\"\n\t\t\t\t\t\t\t:disabled=\"isSubmitting || props.isBusy\"\n\t\t\t\t\t\t>{{i18n.t('modal-dialog.cancel')}}</button>\n\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tclass=\"btn btn-primary\"\n\t\t\t\t\t\t\t:class=\"props.okVariant && `btn-${props.okVariant}`\"\n\t\t\t\t\t\t\t:disabled=\"isSubmitting || props.isBusy\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div v-if=\"isSubmitting\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t{{props.okLabel ?? (isCloseButton ? i18n.t('modal-dialog.close') : i18n.t('modal-dialog.save'))}}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</ValidatedForm>\n\t\t\t</div>\n\t\t</AttributePreservingElement>\n\t</Teleport>\n</template>\n\n<style lang=\"scss\">\n</style>","<script lang=\"ts\">\n\timport { createApp, defineComponent, h, ref, type VNode, type VNodeArrayChildren } from \"vue\";\n\timport Alert from \"./alert.vue\";\n\timport type { ThemeColour } from \"../../utils/bootstrap\";\n\timport ModalDialog from \"./modal-dialog.vue\";\n\timport ValidatedField from \"./validated-form/validated-field.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\texport type AlertProps = {\n\t\ttitle: string;\n\t\tmessage: string;\n\t\ttype?: \"alert\" | \"confirm\";\n\t\tvariant?: ThemeColour;\n\t\tokLabel?: string;\n\t};\n\n\texport interface AlertResult {\n\t\tok: boolean;\n\t}\n\n\tasync function renderAlert({ getContent, onShown, ...props }: AlertProps & {\n\t\tgetContent?: () => string | VNode | VNodeArrayChildren;\n\t\tonShown?: () => void;\n\t}): Promise<AlertResult> {\n\t\treturn await new Promise<AlertResult>((resolve) => {\n\t\t\tconst el = document.createElement('div');\n\t\t\tel.classList.add(\"fm-alert-container\");\n\t\t\tdocument.body.appendChild(el);\n\t\t\tconst app = createApp(defineComponent({\n\t\t\t\tsetup() {\n\t\t\t\t\treturn () => h(Alert, {\n\t\t\t\t\t\t...props,\n\t\t\t\t\t\tonShown: () => {\n\t\t\t\t\t\t\tonShown?.();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonHide: (result) => {\n\t\t\t\t\t\t\tresolve(result);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonHidden: () => {\n\t\t\t\t\t\t\tapp.unmount();\n\t\t\t\t\t\t\tel.remove();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, getContent);\n\t\t\t\t}\n\t\t\t}));\n\t\t\tapp.mount(el);\n\t\t});\n\t}\n\n\texport async function showAlert(props: Omit<AlertProps, 'type'>): Promise<void> {\n\t\tawait renderAlert({ ...props, type: 'alert' });\n\t}\n\n\texport async function showConfirm(props: Omit<AlertProps, 'type'>): Promise<boolean> {\n\t\tconst result = await renderAlert({ ...props, type: 'confirm' });\n\t\treturn result.ok;\n\t}\n\n\texport async function showPrompt({ initialValue = \"\", validate, ...props }: Omit<AlertProps, 'type' | 'message'> & {\n\t\tinitialValue?: string;\n\t\t/** Validate the value. Return an empty string or undefined to indicate validity. */\n\t\tvalidate?: (value: string) => string | undefined;\n\t}): Promise<string | undefined> {\n\t\tconst value = ref(initialValue);\n\t\tconst submitted = ref(false);\n\t\tconst touched = ref(false);\n\t\tconst inputRef = ref<HTMLInputElement>();\n\n\t\tconst result = await renderAlert({\n\t\t\t...props,\n\t\t\tmessage: '',\n\t\t\ttype: 'confirm',\n\t\t\tgetContent: () => h(ValidatedField, {\n\t\t\t\tclass: ['position-relative', touched.value ? 'was-validated' : ''],\n\t\t\t\tvalue: value.value,\n\t\t\t\tvalidators: validate ? [validate] as any : []\n\t\t\t}, {\n\t\t\t\tdefault: (slotProps: any) => [\n\t\t\t\t\th('input', {\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\tclass: \"form-control\",\n\t\t\t\t\t\tvalue: value.value,\n\t\t\t\t\t\tonInput: (e: InputEvent) => {\n\t\t\t\t\t\t\tvalue.value = (e.target as HTMLInputElement).value;\n\t\t\t\t\t\t\ttouched.value = true;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonBlur: () => {\n\t\t\t\t\t\t\ttouched.value = true;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tref: (el) => {\n\t\t\t\t\t\t\tslotProps.inputRef(el);\n\t\t\t\t\t\t\tinputRef.value = el as any;\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\th('div', {\n\t\t\t\t\t\tclass: \"invalid-tooltip\"\n\t\t\t\t\t}, slotProps.validationError)\n\t\t\t\t]\n\t\t\t}),\n\t\t\tonShown: () => {\n\t\t\t\tinputRef.value!.focus();\n\t\t\t}\n\t\t});\n\n\t\tsubmitted.value = true;\n\n\t\treturn result.ok ? value.value : undefined;\n\t}\n</script>\n\n<script setup lang=\"ts\">\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<AlertProps>(), {\n\t\ttype: \"alert\"\n\t});\n\n\tconst emit = defineEmits<{\n\t\tshown: [];\n\t\thide: [result: AlertResult];\n\t\thidden: [result: AlertResult];\n\t}>();\n\n\tconst result = ref<AlertResult>({\n\t\tok: false\n\t});\n\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\n\tconst handleSubmit = () => {\n\t\tresult.value.ok = true;\n\t\tmodalRef.value!.modal.hide();\n\t};\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"props.title\"\n\t\t:isCreate=\"props.type === 'confirm'\"\n\t\t:okLabel=\"props.okLabel ?? i18n.t('alert.fallback-ok-label')\"\n\t\t:okVariant=\"props.variant\"\n\t\t@shown=\"emit('shown')\"\n\t\t@hide=\"emit('hide', result)\"\n\t\t@hidden=\"emit('hidden', result)\"\n\t\t@submit=\"handleSubmit\"\n\t\tref=\"modalRef\"\n\t>\n\t\t<slot>{{props.message}}</slot>\n\t</ModalDialog>\n</template>\n\n<style lang=\"scss\">\n\t.fm-alert-container {\n\t\tposition: absolute;\n\t}\n</style>","<script setup lang=\"ts\">\n\timport type { Stroke } from 'facilmap-types';\n\timport type { Validator } from './validated-form/validated-field.vue';\n\timport { computed } from 'vue';\n\timport { useI18n } from '../../utils/i18n';\n\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tmodelValue: Stroke;\n\t\tvalidators?: Array<Validator<Stroke>>;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [stroke: Stroke];\n\t}>();\n\n\tconst value = computed({\n\t\tget: () => props.modelValue,\n\t\tset: (value) => {\n\t\t\temit(\"update:modelValue\", value!);\n\t\t}\n\t});\n</script>\n\n<template>\n\t<select\n\t\tv-model=\"value\"\n\t\tclass=\"form-select\"\n\t>\n\t\t<option value=\"\">{{i18n.t(\"stroke-picker.solid\")}}</option>\n\t\t<option value=\"dashed\">{{i18n.t(\"stroke-picker.dashed\")}}</option>\n\t\t<option value=\"dotted\">{{i18n.t(\"stroke-picker.dotted\")}}</option>\n\t</select>\n</template>","<script setup lang=\"ts\">\n\timport type { CRU, Field, FieldOptionUpdate, FieldUpdate, Type } from \"facilmap-types\";\n\timport { canControl, formatCheckboxValue, mergeObject } from \"facilmap-utils\";\n\timport { getUniqueId } from \"../../utils/utils\";\n\timport { cloneDeep, isEqual } from \"lodash-es\";\n\timport ColourPicker from \"../ui/colour-picker.vue\";\n\timport Draggable from \"vuedraggable\";\n\timport Icon from \"../ui/icon.vue\";\n\timport ModalDialog from \"../ui/modal-dialog.vue\";\n\timport ShapePicker from \"../ui/shape-picker.vue\";\n\timport SizePicker from \"../ui/size-picker.vue\";\n\timport SymbolPicker from \"../ui/symbol-picker.vue\";\n\timport WidthPicker from \"../ui/width-picker.vue\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport { computed, ref, watch } from \"vue\";\n\timport { showConfirm } from \"../ui/alert.vue\";\n\timport { injectContextRequired } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ValidatedField from \"../ui/validated-form/validated-field.vue\";\n\timport StrokePicker from \"../ui/stroke-picker.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tfunction getControlNumber(type: Type<CRU.READ | CRU.CREATE_VALIDATED>, field: FieldUpdate): number {\n\t\treturn [\n\t\t\tfield.controlColour,\n\t\t\t...(type.type == \"marker\" ? [\n\t\t\t\tfield.controlSize,\n\t\t\t\tfield.controlSymbol,\n\t\t\t\tfield.controlShape\n\t\t\t] : []),\n\t\t\t...(type.type == \"line\" ? [\n\t\t\t\tfield.controlWidth,\n\t\t\t\tfield.controlStroke\n\t\t\t] : [])\n\t\t].filter((v) => v).length;\n\t}\n\n\tconst context = injectContextRequired();\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\ttype: Type<CRU.READ | CRU.CREATE_VALIDATED>;\n\t\tfield: Field;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:field\": [field: Field];\n\t\thidden: [];\n\t}>();\n\n\tconst id = getUniqueId(\"fm-edit-type-dropdown-dialog\");\n\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\n\tconst initialField = computed(() => {\n\t\tconst field: FieldUpdate = cloneDeep(props.field);\n\n\t\tif(field.type == 'checkbox') {\n\t\t\tif(!field.options || field.options.length != 2) {\n\t\t\t\tfield.options = [\n\t\t\t\t\t{ value: '' },\n\t\t\t\t\t{ value: field.name }\n\t\t\t\t]\n\t\t\t}\n\n\t\t\t// Convert legacy format\n\t\t\tif(field.options[0].value == \"0\")\n\t\t\t\tfield.options[0].value = \"\";\n\t\t\tif(field.options[1].value == \"1\")\n\t\t\t\tfield.options[1].value = field.name;\n\t\t}\n\n\t\tfor(let option of (field.options || []))\n\t\t\toption.oldValue = option.value;\n\n\t\treturn field;\n\t});\n\n\tconst fieldValue = ref(cloneDeep(initialField.value));\n\n\twatch(() => props.field, (newField, oldField) => {\n\t\tif (fieldValue.value) {\n\t\t\tif (newField == null) {\n\t\t\t\tmodalRef.value?.modal.hide();\n\t\t\t\t// TODO: Show message\n\t\t\t} else {\n\t\t\t\tmergeObject(oldField, newField, fieldValue.value);\n\t\t\t}\n\t\t}\n\t}, { deep: true });\n\n\tconst isModified = computed(() => !isEqual(fieldValue.value, initialField.value));\n\n\tconst resolvedCanControl = computed(() => canControl(props.type, props.field));\n\n\tfunction addOption(): void {\n\t\tif(fieldValue.value.options == null)\n\t\t\tfieldValue.value.options = [ ];\n\n\t\tfieldValue.value.options!.push({ value: \"\" });\n\t}\n\n\tasync function deleteOption(option: FieldOptionUpdate): Promise<void> {\n\t\tif (!await showConfirm({\n\t\t\ttitle: i18n.t(\"edit-type-dropdown-dialog.delete-option-title\"),\n\t\t\tmessage: i18n.t(\"edit-type-dropdown-dialog.delete-option-message\", { value: option.value }),\n\t\t\tvariant: \"danger\",\n\t\t\tokLabel: i18n.t(\"edit-type-dropdown-dialog.delete-option-button\")\n\t\t}))\n\t\t\treturn;\n\n\t\tvar idx = fieldValue.value.options!.indexOf(option);\n\t\tif(idx != -1)\n\t\t\tfieldValue.value.options!.splice(idx, 1);\n\t}\n\n\tfunction save(): void {\n\t\ttoasts.hideToast(`fm${context.id}-edit-type-dropdown-error`);\n\t\temit(\"update:field\", fieldValue.value);\n\t\tmodalRef.value?.modal.hide();\n\t}\n\n\tconst controlNumber = computed(() => getControlNumber(props.type, fieldValue.value));\n\n\tconst columns = computed(() => controlNumber.value + (fieldValue.value.type === \"checkbox\" ? 2 : 3));\n\n\tfunction validateOptionValue(value: string): string | undefined {\n\t\tif (fieldValue.value.type !== \"checkbox\" && fieldValue.value.options!.filter((op) => op.value === value).length > 1) {\n\t\t\treturn i18n.t(\"edit-type-dropdown-dialog.unique-value-error\");\n\t\t}\n\t}\n\n\tconst formValidationError = computed(() => {\n\t\tif (controlNumber.value > 0 && (fieldValue.value.options?.length ?? 0) === 0) {\n\t\t\treturn i18n.t(\"edit-type-dropdown-dialog.no-options-error\");\n\t\t} else {\n\t\t\treturn undefined;\n\t\t}\n\t});\n\n\tconst typeInterpolation = computed(() => {\n\t\tif (props.type.type === \"marker\") {\n\t\t\treturn i18n.t(\"edit-type-dropdown-dialog.control-interpolation-marker\");\n\t\t} else {\n\t\t\treturn i18n.t(\"edit-type-dropdown-dialog.control-interpolation-line\");\n\t\t}\n\t});\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"fieldValue.type === 'checkbox' ? i18n.t('edit-type-dropdown-dialog.title-checkbox') : i18n.t('edit-type-dropdown-dialog.title-dropdown')\"\n\t\tclass=\"fm-edit-type-dropdown\"\n\t\t:isModified=\"isModified\"\n\t\t@submit=\"save()\"\n\t\t@hidden=\"emit('hidden')\"\n\t\t:size=\"fieldValue && controlNumber > 2 ? 'xl' : 'lg'\"\n\t\t:okLabel=\"isModified ? i18n.t('edit-type-dropdown-dialog.ok-button') : undefined\"\n\t\t:formValidationError=\"formValidationError\"\n\t\tref=\"modalRef\"\n\t>\n\t\t<div class=\"row mb-3\">\n\t\t\t<label class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dropdown-dialog.control\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:id=\"`${id}-control-colour`\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tv-model=\"fieldValue.controlColour\"\n\t\t\t\t\t\t:disabled=\"!resolvedCanControl.includes('colour')\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label\n\t\t\t\t\t\tclass=\"form-check-label\"\n\t\t\t\t\t\t:for=\"`${id}-control-colour`\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{i18n.t(\"edit-type-dropdown-dialog.control-colour\", { type: typeInterpolation })}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"type.type == 'marker'\" class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:id=\"`${id}-control-size`\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tv-model=\"fieldValue.controlSize\"\n\t\t\t\t\t\t:disabled=\"!resolvedCanControl.includes('size')\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label\n\t\t\t\t\t\tclass=\"form-check-label\"\n\t\t\t\t\t\t:for=\"`${id}-control-size`\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{i18n.t(\"edit-type-dropdown-dialog.control-size\", { type: typeInterpolation })}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"type.type == 'marker'\" class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:id=\"`${id}-control-symbol`\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tv-model=\"fieldValue.controlSymbol\"\n\t\t\t\t\t\t:disabled=\"!resolvedCanControl.includes('symbol')\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label\n\t\t\t\t\t\tclass=\"form-check-label\"\n\t\t\t\t\t\t:for=\"`${id}-control-symbol`\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{i18n.t(\"edit-type-dropdown-dialog.control-icon\", { type: typeInterpolation })}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"type.type == 'marker'\" class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:id=\"`${id}-control-shape`\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tv-model=\"fieldValue.controlShape\"\n\t\t\t\t\t\t:disabled=\"!resolvedCanControl.includes('shape')\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label\n\t\t\t\t\t\tclass=\"form-check-label\"\n\t\t\t\t\t\t:for=\"`${id}-control-shape`\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{i18n.t(\"edit-type-dropdown-dialog.control-shape\", { type: typeInterpolation })}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"type.type == 'line'\" class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:id=\"`${id}-control-width`\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tv-model=\"fieldValue.controlWidth\"\n\t\t\t\t\t\t:disabled=\"!resolvedCanControl.includes('width')\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label\n\t\t\t\t\t\tclass=\"form-check-label\"\n\t\t\t\t\t\t:for=\"`${id}-control-width`\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{i18n.t(\"edit-type-dropdown-dialog.control-width\", { type: typeInterpolation })}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"type.type == 'line'\" class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:id=\"`${id}-control-stroke`\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tv-model=\"fieldValue.controlStroke\"\n\t\t\t\t\t\t:disabled=\"!resolvedCanControl.includes('stroke')\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label\n\t\t\t\t\t\tclass=\"form-check-label\"\n\t\t\t\t\t\t:for=\"`${id}-control-stroke`\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{i18n.t(\"edit-type-dropdown-dialog.control-stroke\", { type: typeInterpolation })}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t\t<table v-if=\"fieldValue.type != 'checkbox' || controlNumber > 0\" class=\"table table-striped table-hover\">\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th>{{i18n.t(\"edit-type-dropdown-dialog.option\")}}</th>\n\t\t\t\t\t<th v-if=\"fieldValue.type == 'checkbox'\">{{i18n.t(\"edit-type-dropdown-dialog.label\")}}</th>\n\t\t\t\t\t<th v-if=\"fieldValue.controlColour\">{{i18n.t(\"edit-type-dropdown-dialog.colour\")}}</th>\n\t\t\t\t\t<th v-if=\"fieldValue.controlSize\">{{i18n.t(\"edit-type-dropdown-dialog.size\")}}</th>\n\t\t\t\t\t<th v-if=\"fieldValue.controlSymbol\">{{i18n.t(\"edit-type-dropdown-dialog.icon\")}}</th>\n\t\t\t\t\t<th v-if=\"fieldValue.controlShape\">{{i18n.t(\"edit-type-dropdown-dialog.shape\")}}</th>\n\t\t\t\t\t<th v-if=\"fieldValue.controlWidth\">{{i18n.t(\"edit-type-dropdown-dialog.width\")}}</th>\n\t\t\t\t\t<th v-if=\"fieldValue.controlStroke\">{{i18n.t(\"edit-type-dropdown-dialog.stroke\")}}</th>\n\t\t\t\t\t<th v-if=\"fieldValue.type != 'checkbox'\"></th>\n\t\t\t\t\t<th v-if=\"fieldValue.type != 'checkbox'\" class=\"move\"></th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<Draggable\n\t\t\t\tv-model=\"fieldValue.options\"\n\t\t\t\ttag=\"tbody\"\n\t\t\t\thandle=\".fm-drag-handle\"\n\t\t\t\t:itemKey=\"(option: any) => fieldValue.options!.indexOf(option)\"\n\t\t\t>\n\t\t\t\t<template #item=\"{ element: option, index: idx }\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td v-if=\"fieldValue.type == 'checkbox'\" class=\"align-middle\">\n\t\t\t\t\t\t\t<strong>{{formatCheckboxValue(idx === 0 ? \"0\" : \"1\")}}</strong>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<ValidatedField\n\t\t\t\t\t\t\ttag=\"td\"\n\t\t\t\t\t\t\tclass=\"field position-relative\"\n\t\t\t\t\t\t\t:value=\"option.value\"\n\t\t\t\t\t\t\t:validators=\"[validateOptionValue]\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\t\t\t\tv-model=\"option.value\"\n\t\t\t\t\t\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</ValidatedField>\n\t\t\t\t\t\t<td v-if=\"fieldValue.controlColour\" class=\"field\">\n\t\t\t\t\t\t\t<ColourPicker\n\t\t\t\t\t\t\t\t:modelValue=\"option.colour ?? type.defaultColour\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"option.colour = $event\"\n\t\t\t\t\t\t\t></ColourPicker>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td v-if=\"fieldValue.controlSize\" class=\"field\">\n\t\t\t\t\t\t\t<SizePicker\n\t\t\t\t\t\t\t\t:modelValue=\"option.size ?? type.defaultSize\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"option.size = $event\"\n\t\t\t\t\t\t\t\tclass=\"fm-custom-range-with-label\"\n\t\t\t\t\t\t\t></SizePicker>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td v-if=\"fieldValue.controlSymbol\" class=\"field\">\n\t\t\t\t\t\t\t<SymbolPicker\n\t\t\t\t\t\t\t\t:modelValue=\"option.symbol ?? type.defaultSymbol\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"option.symbol = $event\"\n\t\t\t\t\t\t\t></SymbolPicker>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td v-if=\"fieldValue.controlShape\" class=\"field\">\n\t\t\t\t\t\t\t<ShapePicker\n\t\t\t\t\t\t\t\t:modelValue=\"option.shape ?? type.defaultShape\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"option.shape = $event\"\n\t\t\t\t\t\t\t></ShapePicker>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td v-if=\"fieldValue.controlWidth\" class=\"field\">\n\t\t\t\t\t\t\t<WidthPicker\n\t\t\t\t\t\t\t\t:modelValue=\"option.width ?? type.defaultWidth\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"option.width = $event\"\n\t\t\t\t\t\t\t\tclass=\"fm-custom-range-with-label\"\n\t\t\t\t\t\t\t></WidthPicker>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td v-if=\"fieldValue.controlStroke\" class=\"field\">\n\t\t\t\t\t\t\t<StrokePicker\n\t\t\t\t\t\t\t\t:modelValue=\"option.stroke ?? type.defaultStroke\"\n\t\t\t\t\t\t\t\t@update:modelValue=\"option.stroke = $event\"\n\t\t\t\t\t\t\t></StrokePicker>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td v-if=\"fieldValue.type != 'checkbox'\" class=\"td-buttons\">\n\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" @click=\"deleteOption(option)\"><Icon icon=\"minus\" :alt=\"i18n.t('edit-type-dropdown-dialog.option-remove')\"></Icon></button>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td v-if=\"fieldValue.type != 'checkbox'\" class=\"td-buttons\">\n\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary fm-drag-handle\"><Icon icon=\"resize-vertical\" :alt=\"i18n.t('edit-type-dropdown-dialog.option-reorder')\"></Icon></button>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</template>\n\t\t\t</Draggable>\n\t\t\t<tfoot v-if=\"fieldValue.type != 'checkbox'\">\n\t\t\t\t<tr>\n\t\t\t\t\t<td :colspan=\"columns\">\n\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" @click=\"addOption()\"><Icon icon=\"plus\" :alt=\"i18n.t('edit-type-dropdown-dialog.option-add')\"></Icon></button>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</tfoot>\n\t\t</table>\n\n\t\t<div class=\"fm-form-invalid-feedback\" v-if=\"formValidationError\">\n\t\t\t{{formValidationError}}\n\t\t</div>\n\t</ModalDialog>\n</template>\n\n<style lang=\"scss\">\n\t.fm-edit-type-dropdown {\n\t\ttd.field {\n\t\t\tmin-width: 10rem;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { typeValidator, type Field, type ID, type Type, type CRU } from \"facilmap-types\";\n\timport { canControl, formatFieldName } from \"facilmap-utils\";\n\timport { getUniqueId, getZodValidator, validateRequired } from \"../../utils/utils\";\n\timport { mergeTypeObject } from \"./edit-type-utils\";\n\timport { cloneDeep, isEqual } from \"lodash-es\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport ColourPicker from \"../ui/colour-picker.vue\";\n\timport ShapePicker from \"../ui/shape-picker.vue\";\n\timport SymbolPicker from \"../ui/symbol-picker.vue\";\n\timport RouteMode from \"../ui/route-mode.vue\";\n\timport Draggable from \"vuedraggable\";\n\timport FieldInput from \"../ui/field-input.vue\";\n\timport Icon from \"../ui/icon.vue\";\n\timport WidthPicker from \"../ui/width-picker.vue\";\n\timport SizePicker from \"../ui/size-picker.vue\";\n\timport EditTypeDropdownDialog from \"./edit-type-dropdown-dialog.vue\";\n\timport { computed, ref, watch } from \"vue\";\n\timport ModalDialog from \"../ui/modal-dialog.vue\";\n\timport { showConfirm } from \"../ui/alert.vue\";\n\timport { injectContextRequired, requireClientContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ValidatedField from \"../ui/validated-form/validated-field.vue\";\n\timport StrokePicker from \"../ui/stroke-picker.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\ttypeId: ID | \"createMarkerType\" | \"createLineType\";\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst id = getUniqueId(\"fm-edit-type-dialog\");\n\n\tconst isCreate = computed(() => props.typeId === \"createMarkerType\" || props.typeId === \"createLineType\");\n\n\tconst originalType = computed(() => {\n\t\treturn typeof props.typeId === \"number\" ? client.value.types[props.typeId] : undefined;\n\t});\n\n\tconst initialType = computed<Type<CRU.CREATE_VALIDATED | CRU.READ>>(() => {\n\t\tlet type: Type<CRU.CREATE_VALIDATED | CRU.READ>;\n\t\tif (props.typeId === \"createMarkerType\") {\n\t\t\ttype = {\n\t\t\t\t...typeValidator.create.parse({ name: \"-\", type: \"marker\" } satisfies Type<CRU.CREATE>),\n\t\t\t\tname: \"\"\n\t\t\t};\n\t\t} else if (props.typeId === \"createLineType\") {\n\t\t\ttype = {\n\t\t\t\t...typeValidator.create.parse({ name: \"-\", type: \"line\" } satisfies Type<CRU.CREATE>),\n\t\t\t\tname: \"\"\n\t\t\t};\n\t\t} else {\n\t\t\ttype = cloneDeep(originalType.value)!;\n\t\t}\n\n\t\tfor(const field of type.fields) {\n\t\t\t(field as any).oldName = field.name;\n\t\t}\n\n\t\treturn type;\n\t});\n\n\tconst type = ref(cloneDeep(initialType.value));\n\tconst editField = ref<Field>();\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\n\tconst isModified = computed(() => {\n\t\treturn !isEqual(type.value, initialType.value);\n\t});\n\n\tconst resolvedCanControl = computed(() => canControl(type.value, null));\n\n\twatch(originalType, (newType, oldType) => {\n\t\tif (oldType && type.value) {\n\t\t\tif (!newType) {\n\t\t\t\tmodalRef.value?.modal.hide();\n\t\t\t\t// TODO: Show message\n\t\t\t} else {\n\t\t\t\tmergeTypeObject(oldType, newType, type.value);\n\t\t\t}\n\t\t}\n\t});\n\n\tfunction createField(): void {\n\t\ttype.value.fields.push({ name: \"\", type: \"input\", \"default\": \"\" });\n\t}\n\n\tasync function deleteField(field: Field): Promise<void> {\n\t\tif (!await showConfirm({\n\t\t\ttitle: i18n.t(\"edit-type-dialog.delete-field-title\"),\n\t\t\tmessage: i18n.t(\"edit-type-dialog.delete-field-message\", { fieldName: formatFieldName(field.name) }),\n\t\t\tvariant: \"danger\",\n\t\t\tokLabel: i18n.t(\"edit-type-dialog.delete-field-button\")\n\t\t}))\n\t\t\treturn;\n\n\t\tvar idx = type.value.fields.indexOf(field);\n\t\tif(idx != -1)\n\t\t\ttype.value.fields.splice(idx, 1);\n\t}\n\n\tasync function save(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-edit-type-error`);\n\n\t\ttry {\n\t\t\tif (isCreate.value)\n\t\t\t\tawait client.value.addType(type.value);\n\t\t\telse\n\t\t\t\tawait client.value.editType(type.value as Type);\n\n\t\t\tmodalRef.value?.modal.hide();\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(\n\t\t\t\t`fm${context.id}-edit-type-error`,\n\t\t\t\t() => (isCreate.value ? i18n.t(\"edit-type-dialog.create-type-error\") : i18n.t(\"edit-type-dialog.save-type-error\")),\n\t\t\t\terr\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction editDropdown(field: Field): void {\n\t\teditField.value = field;\n\t}\n\n\tfunction handleUpdateField(field: Field) {\n\t\tconst idx = type.value.fields.indexOf(editField.value!);\n\t\tif (idx === -1) {\n\t\t\ttoasts.showErrorToast(\n\t\t\t\t`fm${context.id}-edit-type-dropdown-error`,\n\t\t\t\t() => i18n.t(\"edit-type-dialog.field-update-error\"),\n\t\t\t\t() => i18n.t(\"edit-type-dialog.field-disappeared-error\")\n\t\t\t);\n\t\t}\n\t\ttype.value.fields[idx] = field;\n\t}\n\n\tfunction validateFieldName(name: string) {\n\t\tif (type.value.fields.filter((field) => field.name == name).length > 1) {\n\t\t\treturn i18n.t(\"edit-type-dialog.unique-field-name-error\");\n\t\t}\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('edit-type-dialog.title')\"\n\t\tclass=\"fm-edit-type\"\n\t\t:isModified=\"isModified\"\n\t\t:isCreate=\"isCreate\"\n\t\tref=\"modalRef\"\n\t\t@submit=\"$event.waitUntil(save())\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-name-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.name\")}}</label>\n\t\t\t<ValidatedField\n\t\t\t\t:value=\"type.name\"\n\t\t\t\t:validators=\"[validateRequired, getZodValidator(typeValidator.update.shape.name)]\"\n\t\t\t\tclass=\"col-sm-9 position-relative\"\n\t\t\t>\n\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t<input class=\"form-control\" :id=\"`${id}-name-input`\" v-model=\"type.name\" :ref=\"slotProps.inputRef\" />\n\t\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t</ValidatedField>\n\t\t</div>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-type-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.type\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<select\n\t\t\t\t\t:id=\"`${id}-type-input`\"\n\t\t\t\t\tv-model=\"type.type\"\n\t\t\t\t\tclass=\"form-select\"\n\t\t\t\t\tdisabled\n\t\t\t\t>\n\t\t\t\t\t<option value=\"marker\">{{i18n.t(\"edit-type-dialog.type-marker\")}}</option>\n\t\t\t\t\t<option value=\"line\">{{i18n.t(\"edit-type-dialog.type-line\")}}</option>\n\t\t\t\t</select>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<template v-if=\"resolvedCanControl.length > 0\">\n\t\t\t<hr/>\n\n\t\t\t<p class=\"text-muted\">\n\t\t\t\t{{i18n.t(\"edit-type-dialog.styles-introduction\")}}\n\t\t\t</p>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('colour')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-default-colour-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.default-colour\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<div class=\"row align-items-center\">\n\t\t\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t\t\t<ColourPicker\n\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-colour-input`\"\n\t\t\t\t\t\t\t\t\tv-model=\"type.defaultColour\"\n\t\t\t\t\t\t\t\t></ColourPicker>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"col-sm-3\">\n\t\t\t\t\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-colour-fixed`\"\n\t\t\t\t\t\t\t\t\t\tv-model=\"type.colourFixed\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<label :for=\"`${id}-default-colour-fixed`\" class=\"form-check-label\">{{i18n.t(\"edit-type-dialog.fixed\")}}</label>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('size')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-default-size-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.default-size\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<div class=\"row align-items-center\">\n\t\t\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t\t\t<SizePicker\n\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-size-input`\"\n\t\t\t\t\t\t\t\t\tv-model=\"type.defaultSize\"\n\t\t\t\t\t\t\t\t\tclass=\"fm-custom-range-with-label\"\n\t\t\t\t\t\t\t\t></SizePicker>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"col-sm-3\">\n\t\t\t\t\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-size-fixed`\"\n\t\t\t\t\t\t\t\t\t\tv-model=\"type.sizeFixed\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<label :for=\"`${id}-default-size-fixed`\" class=\"form-check-label\">{{i18n.t(\"edit-type-dialog.fixed\")}}</label>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('symbol')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-default-symbol-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.default-icon\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<div class=\"row align-items-center\">\n\t\t\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t\t\t<SymbolPicker\n\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-symbol-input`\"\n\t\t\t\t\t\t\t\t\tv-model=\"type.defaultSymbol\"\n\t\t\t\t\t\t\t\t></SymbolPicker>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"col-sm-3\">\n\t\t\t\t\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-symbol-fixed`\"\n\t\t\t\t\t\t\t\t\t\tv-model=\"type.symbolFixed\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<label :for=\"`${id}-default-symbol-fixed`\" class=\"form-check-label\">{{i18n.t(\"edit-type-dialog.fixed\")}}</label>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('shape')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-default-shape-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.default-shape\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<div class=\"row align-items-center\">\n\t\t\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t\t\t<ShapePicker\n\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-shape-input`\"\n\t\t\t\t\t\t\t\t\tv-model=\"type.defaultShape\"\n\t\t\t\t\t\t\t\t></ShapePicker>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"col-sm-3\">\n\t\t\t\t\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-shape-fixed`\"\n\t\t\t\t\t\t\t\t\t\tv-model=\"type.shapeFixed\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<label :for=\"`${id}-default-shape-fixed`\" class=\"form-check-label\">{{i18n.t(\"edit-type-dialog.fixed\")}}</label>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('width')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-default-width-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.default-width\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<div class=\"row align-items-center\">\n\t\t\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t\t\t<WidthPicker\n\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-width-input`\"\n\t\t\t\t\t\t\t\t\tv-model=\"type.defaultWidth\"\n\t\t\t\t\t\t\t\t\tclass=\"fm-custom-range-with-label\"\n\t\t\t\t\t\t\t\t></WidthPicker>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"col-sm-3\">\n\t\t\t\t\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-width-fixed`\"\n\t\t\t\t\t\t\t\t\t\tv-model=\"type.widthFixed\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<label :for=\"`${id}-default-width-fixed`\" class=\"form-check-label\">{{i18n.t(\"edit-type-dialog.fixed\")}}</label>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('stroke')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-default-stroke-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.default-stroke\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<div class=\"row align-items-center\">\n\t\t\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t\t\t<StrokePicker\n\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-stroke-input`\"\n\t\t\t\t\t\t\t\t\tv-model=\"type.defaultStroke\"\n\t\t\t\t\t\t\t\t></StrokePicker>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"col-sm-3\">\n\t\t\t\t\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-stroke-fixed`\"\n\t\t\t\t\t\t\t\t\t\tv-model=\"type.strokeFixed\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<label :for=\"`${id}-default-stroke-fixed`\" class=\"form-check-label\">{{i18n.t(\"edit-type-dialog.fixed\")}}</label>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('mode') && context.settings.routing\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-default-mode-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.default-route-mode\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<div class=\"row align-items-center\">\n\t\t\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t\t\t<RouteMode\n\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-mode-input`\"\n\t\t\t\t\t\t\t\t\tv-model=\"type.defaultMode\"\n\t\t\t\t\t\t\t\t></RouteMode>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"col-sm-3\">\n\t\t\t\t\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t\t\t\t:id=\"`${id}-default-mode-fixed`\"\n\t\t\t\t\t\t\t\t\t\tv-model=\"type.modeFixed\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<label :for=\"`${id}-default-mode-fixed`\" class=\"form-check-label\">{{i18n.t(\"edit-type-dialog.fixed\")}}</label>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<hr/>\n\t\t</template>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-show-in-legend-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-type-dialog.legend\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"`${id}-show-in-legend-input`\"\n\t\t\t\t\t\tv-model=\"type.showInLegend\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label :for=\"`${id}-show-in-legend-input`\" class=\"form-check-label\">{{i18n.t(\"edit-type-dialog.show-in-legend\")}}</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"form-text\">\n\t\t\t\t\t{{i18n.t(\"edit-type-dialog.show-in-legend-description\")}}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<h2>{{i18n.t(\"edit-type-dialog.fields\")}}</h2>\n\t\t<div class=\"table-responsive\">\n\t\t\t<table class=\"table table-hover table-striped\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th style=\"width: 35%; min-width: 150px\">{{i18n.t(\"edit-type-dialog.field-name\")}}</th>\n\t\t\t\t\t\t<th style=\"width: 35%; min-width: 120px\">{{i18n.t(\"edit-type-dialog.field-type\")}}</th>\n\t\t\t\t\t\t<th style=\"width: 35%; min-width: 150px\">{{i18n.t(\"edit-type-dialog.field-default-value\")}}</th>\n\t\t\t\t\t\t<th>{{i18n.t(\"edit-type-dialog.field-delete\")}}</th>\n\t\t\t\t\t\t<th></th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<Draggable\n\t\t\t\t\tv-model=\"type.fields\"\n\t\t\t\t\ttag=\"tbody\"\n\t\t\t\t\thandle=\".fm-drag-handle\"\n\t\t\t\t\t:itemKey=\"(field: any) => type.fields.indexOf(field)\"\n\t\t\t\t>\n\t\t\t\t\t<template #item=\"{ element: field }\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<ValidatedField\n\t\t\t\t\t\t\t\ttag=\"td\"\n\t\t\t\t\t\t\t\tclass=\"position-relative\"\n\t\t\t\t\t\t\t\t:value=\"field.name\"\n\t\t\t\t\t\t\t\t:validators=\"[validateRequired, validateFieldName]\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\t\t\t\t\tv-model=\"field.name\"\n\t\t\t\t\t\t\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</ValidatedField>\n\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t<div class=\"input-group\">\n\t\t\t\t\t\t\t\t\t<select class=\"form-select\" v-model=\"field.type\">\n\t\t\t\t\t\t\t\t\t\t<option value=\"input\">{{i18n.t(\"edit-type-dialog.field-type-input\")}}</option>\n\t\t\t\t\t\t\t\t\t\t<option value=\"textarea\">{{i18n.t(\"edit-type-dialog.field-type-textarea\")}}</option>\n\t\t\t\t\t\t\t\t\t\t<option value=\"dropdown\">{{i18n.t(\"edit-type-dialog.field-type-dropdown\")}}</option>\n\t\t\t\t\t\t\t\t\t\t<option value=\"checkbox\">{{i18n.t(\"edit-type-dialog.field-type-checkbox\")}}</option>\n\t\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t\t\t<template v-if=\"['dropdown', 'checkbox'].includes(field.type)\">\n\t\t\t\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" @click=\"editDropdown(field)\">{{i18n.t(\"edit-type-dialog.field-edit\")}}</button>\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"text-center align-middle\">\n\t\t\t\t\t\t\t\t<FieldInput :field=\"field\" v-model=\"field.default\" ignore-default></FieldInput>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"td-buttons\">\n\t\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" @click=\"deleteField(field)\">{{i18n.t(\"edit-type-dialog.field-delete\")}}</button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td class=\"td-buttons\">\n\t\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary fm-drag-handle\"><Icon icon=\"resize-vertical\" :alt=\"i18n.t('edit-type-dialog.field-reorder')\"></Icon></button>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</template>\n\t\t\t\t</Draggable>\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td colspan=\"4\">\n\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" @click=\"createField()\"><Icon icon=\"plus\" :alt=\"i18n.t('edit-type-dialog.field-add')\"></Icon></button>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td class=\"move\"></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\t\t\t</table>\n\t\t</div>\n\n\t\t<EditTypeDropdownDialog\n\t\t\tv-if=\"editField != null\"\n\t\t\t:type=\"type\"\n\t\t\t:field=\"editField\"\n\t\t\t@update:field=\"handleUpdateField($event)\"\n\t\t\t@hidden=\"editField = undefined\"\n\t\t></EditTypeDropdownDialog>\n\t</ModalDialog>\n</template>","import type { HistoryEntry } from \"facilmap-types\";\nimport { getObjectDiff, type ObjectDiffItem } from \"facilmap-utils\";\nimport type { ClientContext } from \"../facil-map-context-provider/client-context\";\nimport { getI18n } from \"../../utils/i18n\";\n\nfunction existsNow(client: ClientContext, entry: HistoryEntry) {\n\t// Look through the history of this particular object and see if the last entry indicates that the object exists now\n\n\tlet ret = null;\n\tlet time = 0;\n\tfor(const i in client.history) {\n\t\tconst item2 = client.history[i];\n\n\t\tconst time2 = new Date(item2.time).getTime();\n\t\tif(item2.type == entry.type && item2.objectId == entry.objectId && time2 > time) {\n\t\t\tret = (item2.action != \"delete\");\n\t\t\ttime = time2;\n\t\t}\n\t}\n\n\treturn ret;\n}\n\nexport interface HistoryEntryLabels {\n\tdescription: string;\n\trevert?: {\n\t\ttitle: string;\n\t\tmessage: string;\n\t\tbutton: string;\n\t\tokLabel: string;\n\t},\n\tdiff?: Array<ObjectDiffItem>;\n}\n\nexport function getLabelsForHistoryEntry(client: ClientContext, entry: HistoryEntry): HistoryEntryLabels {\n\tconst i18n = getI18n();\n\n\tif(entry.type == \"Pad\") {\n\t\treturn {\n\t\t\tdescription: i18n.t(\"history-utils.description-update-map\"),\n\t\t\trevert: {\n\t\t\t\ttitle: i18n.t(\"history-utils.revert-update-map-title\"),\n\t\t\t\tmessage: i18n.t(\"history-utils.revert-update-map-message\"),\n\t\t\t\tbutton: i18n.t(\"history-utils.revert-update\"),\n\t\t\t\tokLabel: i18n.t(\"history-utils.revert-update-button\")\n\t\t\t},\n\t\t\t...(entry.objectBefore && entry.objectAfter ? { diff: getObjectDiff(entry.objectBefore, entry.objectAfter) } : {}),\n\t\t};\n\t}\n\n\tconst nameStrBefore = entry.objectBefore && entry.objectBefore.name ? i18n.t(\"history-utils.description-interpolation-quotedName\", { name: entry.objectBefore.name }) : \"\";\n\tconst nameStrAfter = entry.objectAfter && entry.objectAfter.name ? i18n.t(\"history-utils.description-interpolation-quotedName\", { name: entry.objectAfter.name }) : \"\";\n\tconst exists = existsNow(client, entry);\n\tconst descriptionName = (nameStrBefore && nameStrAfter && nameStrBefore != nameStrAfter ? (\n\t\ti18n.t(\"history-utils.description-interpolation-quotedName-renamed\", { quotedBefore: nameStrBefore, quotedAfter: nameStrAfter })\n\t) : (nameStrBefore || nameStrAfter));\n\tconst diff = entry.objectBefore && entry.objectAfter ? getObjectDiff(entry.objectBefore, entry.objectAfter) : undefined;\n\tconst revert = (\n\t\tentry.action === \"create\" ? (\n\t\t\texists ? {\n\t\t\t\tbutton: i18n.t(\"history-utils.revert-create\"),\n\t\t\t\ttitle: {\n\t\t\t\t\tMarker: i18n.t(\"history-utils.revert-create-marker-title\"),\n\t\t\t\t\tLine: i18n.t(\"history-utils.revert-create-line-title\"),\n\t\t\t\t\tView: i18n.t(\"history-utils.revert-create-view-title\"),\n\t\t\t\t\tType: i18n.t(\"history-utils.revert-create-type-title\")\n\t\t\t\t}[entry.type],\n\t\t\t\tmessage: {\n\t\t\t\t\tMarker: nameStrBefore || nameStrAfter\n\t\t\t\t\t\t? i18n.t(\"history-utils.revert-create-marker-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t\t: i18n.t(\"history-utils.revert-create-marker-message-unnamed\"),\n\t\t\t\t\tLine: nameStrBefore || nameStrAfter\n\t\t\t\t\t\t? i18n.t(\"history-utils.revert-create-line-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t\t: i18n.t(\"history-utils.revert-create-line-message-unnamed\"),\n\t\t\t\t\tView: nameStrBefore || nameStrAfter\n\t\t\t\t\t\t? i18n.t(\"history-utils.revert-create-view-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t\t: i18n.t(\"history-utils.revert-create-view-message-unnamed\"),\n\t\t\t\t\tType: nameStrBefore || nameStrAfter\n\t\t\t\t\t\t? i18n.t(\"history-utils.revert-create-type-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t\t: i18n.t(\"history-utils.revert-create-type-message-unnamed\"),\n\t\t\t\t}[entry.type],\n\t\t\t\tokLabel: i18n.t(\"history-utils.revert-create-button\")\n\t\t\t} : undefined\n\t\t) : exists ? {\n\t\t\tbutton: i18n.t(\"history-utils.revert-update\"),\n\t\t\ttitle: {\n\t\t\t\tMarker: i18n.t(\"history-utils.revert-update-marker-title\"),\n\t\t\t\tLine: i18n.t(\"history-utils.revert-update-line-title\"),\n\t\t\t\tView: i18n.t(\"history-utils.revert-update-view-title\"),\n\t\t\t\tType: i18n.t(\"history-utils.revert-update-type-title\")\n\t\t\t}[entry.type],\n\t\t\tmessage: {\n\t\t\t\tMarker: nameStrBefore || nameStrAfter\n\t\t\t\t\t? i18n.t(\"history-utils.revert-update-marker-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t: i18n.t(\"history-utils.revert-update-marker-message-unnamed\"),\n\t\t\t\tLine: nameStrBefore || nameStrAfter\n\t\t\t\t\t? i18n.t(\"history-utils.revert-update-line-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t: i18n.t(\"history-utils.revert-update-line-message-unnamed\"),\n\t\t\t\tView: nameStrBefore || nameStrAfter\n\t\t\t\t\t? i18n.t(\"history-utils.revert-update-view-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t: i18n.t(\"history-utils.revert-update-view-message-unnamed\"),\n\t\t\t\tType: nameStrBefore || nameStrAfter\n\t\t\t\t\t? i18n.t(\"history-utils.revert-update-type-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t: i18n.t(\"history-utils.revert-update-type-message-unnamed\"),\n\t\t\t}[entry.type],\n\t\t\tokLabel: i18n.t(\"history-utils.revert-update-button\")\n\t\t} : {\n\t\t\tbutton: i18n.t(\"history-utils.revert-delete\"),\n\t\t\ttitle: {\n\t\t\t\tMarker: i18n.t(\"history-utils.revert-delete-marker-title\"),\n\t\t\t\tLine: i18n.t(\"history-utils.revert-delete-line-title\"),\n\t\t\t\tView: i18n.t(\"history-utils.revert-delete-view-title\"),\n\t\t\t\tType: i18n.t(\"history-utils.revert-delete-type-title\")\n\t\t\t}[entry.type],\n\t\t\tmessage: {\n\t\t\t\tMarker: nameStrBefore || nameStrAfter\n\t\t\t\t\t? i18n.t(\"history-utils.revert-delete-marker-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t: i18n.t(\"history-utils.revert-delete-marker-message-unnamed\"),\n\t\t\t\tLine: nameStrBefore || nameStrAfter\n\t\t\t\t\t? i18n.t(\"history-utils.revert-delete-line-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t: i18n.t(\"history-utils.revert-delete-line-message-unnamed\"),\n\t\t\t\tView: nameStrBefore || nameStrAfter\n\t\t\t\t\t? i18n.t(\"history-utils.revert-delete-view-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t: i18n.t(\"history-utils.revert-delete-view-message-unnamed\"),\n\t\t\t\tType: nameStrBefore || nameStrAfter\n\t\t\t\t\t? i18n.t(\"history-utils.revert-delete-type-message-named\", { quotedName: nameStrBefore || nameStrAfter })\n\t\t\t\t\t: i18n.t(\"history-utils.revert-delete-type-message-unnamed\"),\n\t\t\t}[entry.type],\n\t\t\tokLabel: i18n.t(\"history-utils.revert-delete-button\")\n\t\t}\n\t);\n\n\treturn {\n\t\tdescription: {\n\t\t\tcreate: {\n\t\t\t\tMarker: i18n.t(\"history-utils.description-create-marker\", { id: entry.objectId, quotedName: descriptionName }),\n\t\t\t\tLine: i18n.t(\"history-utils.description-create-line\", { id: entry.objectId, quotedName: descriptionName }),\n\t\t\t\tView: i18n.t(\"history-utils.description-create-view\", { id: entry.objectId, quotedName: descriptionName }),\n\t\t\t\tType: i18n.t(\"history-utils.description-create-type\", { id: entry.objectId, quotedName: descriptionName })\n\t\t\t}[entry.type],\n\t\t\tupdate: {\n\t\t\t\tMarker: i18n.t(\"history-utils.description-update-marker\", { id: entry.objectId, quotedName: descriptionName }),\n\t\t\t\tLine: i18n.t(\"history-utils.description-update-line\", { id: entry.objectId, quotedName: descriptionName }),\n\t\t\t\tView: i18n.t(\"history-utils.description-update-view\", { id: entry.objectId, quotedName: descriptionName }),\n\t\t\t\tType: i18n.t(\"history-utils.description-update-type\", { id: entry.objectId, quotedName: descriptionName })\n\t\t\t}[entry.type],\n\t\t\tdelete: {\n\t\t\t\tMarker: i18n.t(\"history-utils.description-delete-marker\", { id: entry.objectId, quotedName: descriptionName }),\n\t\t\t\tLine: i18n.t(\"history-utils.description-delete-line\", { id: entry.objectId, quotedName: descriptionName }),\n\t\t\t\tView: i18n.t(\"history-utils.description-delete-view\", { id: entry.objectId, quotedName: descriptionName }),\n\t\t\t\tType: i18n.t(\"history-utils.description-delete-type\", { id: entry.objectId, quotedName: descriptionName })\n\t\t\t}[entry.type]\n\t\t}[entry.action],\n\t\trevert,\n\t\t...(diff ? { diff } : {})\n\t};\n}","<script setup lang=\"ts\">\n\timport { getLabelsForHistoryEntry, type HistoryEntryLabels } from \"./history-utils\";\n\timport type { HistoryEntry, ID } from \"facilmap-types\";\n\timport { orderBy } from \"lodash-es\";\n\timport Icon from \"../ui/icon.vue\";\n\timport { computed, onBeforeUnmount, onMounted, reactive, ref } from \"vue\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport { showConfirm } from \"../ui/alert.vue\";\n\timport { mapRef } from \"../../utils/vue\";\n\timport { getUniqueId } from \"../../utils/utils\";\n\timport Popover from \"../ui/popover.vue\";\n\timport ModalDialog from \"../ui/modal-dialog.vue\";\n\timport { injectContextRequired, requireClientContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\ttype HistoryEntryWithLabels = HistoryEntry & {\n\t\tlabels: HistoryEntryLabels;\n\t};\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst isLoading = ref(true);\n\tconst isReverting = ref<HistoryEntryWithLabels>();\n\tconst activeDiffPopoverId = ref<ID>();\n\n\tconst diffButtonRefs = reactive(new Map<ID, HTMLElement>());\n\n\tconst id = getUniqueId(\"fm-history-dialog\");\n\n\tonMounted(async () => {\n\t\ttry {\n\t\t\tawait client.value.listenToHistory();\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`${id}-listen-error`, () => i18n.t(\"history-dialog.loading-error\"), err);\n\t\t} finally {\n\t\t\tisLoading.value = false;\n\t\t}\n\t});\n\n\tonBeforeUnmount(async () => {\n\t\ttry {\n\t\t\tawait client.value.stopListeningToHistory();\n\t\t} catch (err) {\n\t\t\tconsole.error(\"Error stopping listening to history\", err);\n\t\t}\n\t});\n\n\tasync function revert(entry: HistoryEntryWithLabels): Promise<void> {\n\t\ttoasts.hideToast(`${id}-revert-error`);\n\n\t\tif (!await showConfirm({\n\t\t\ttitle: entry.labels.revert!.title,\n\t\t\tmessage: entry.labels.revert!.message,\n\t\t\tvariant: \"warning\",\n\t\t\tokLabel: entry.labels.revert!.okLabel\n\t\t}))\n\t\t\treturn;\n\n\t\tisReverting.value = entry;\n\n\t\ttry {\n\t\t\tawait client.value.revertHistoryEntry({ id: entry.id });\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`${id}-revert-error`, () => i18n.t(\"history-dialog.revert-error\"), err);\n\t\t} finally {\n\t\t\tisReverting.value = undefined;\n\t\t}\n\t}\n\n\tconst history = computed((): HistoryEntryWithLabels[] => {\n\t\treturn orderBy(\n\t\t\tObject.values(client.value.history).map((entry) => ({\n\t\t\t\t...entry,\n\t\t\t\ttime: entry.time.replace(/\\.\\d+/, \"\"),\n\t\t\t\tlabels: getLabelsForHistoryEntry(client.value, entry)\n\t\t\t})),\n\t\t\t[\"time\"],\n\t\t\t[\"desc\"]\n\t\t);\n\t});\n\n\tfunction toggleDiffPopover(entryId: ID, force?: boolean): void {\n\t\tconst isShown = activeDiffPopoverId.value === entryId;\n\t\tconst show = force ?? (activeDiffPopoverId.value !== entryId);\n\t\tif (isShown !== show) {\n\t\t\tactiveDiffPopoverId.value = show ? entryId : undefined;\n\t\t}\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('history-dialog.title')\"\n\t\tsize=\"xl\"\n\t\tclass=\"fm-history\"\n\t\t@hidden=\"emit('hidden')\"\n\t\t:isBusy=\"!!isReverting\"\n\t>\n\t\t<p><em>{{i18n.t(\"history-dialog.introduction\")}}</em></p>\n\t\t<div v-if=\"isLoading\" class=\"d-flex justify-content-center\">\n\t\t\t<div class=\"spinner-border\"></div>\n\t\t</div>\n\t\t<table v-else class=\"table table-striped table-hover history-entries\">\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th style=\"min-width: 12rem\">{{i18n.t(\"history-dialog.date\")}}</th>\n\t\t\t\t\t<th style=\"min-width: 15rem\">{{i18n.t(\"history-dialog.action\")}}</th>\n\t\t\t\t\t<th></th>\n\t\t\t\t\t<th>{{i18n.t(\"history-dialog.restore\")}}</th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t<tr v-for=\"entry in history\" :key=\"entry.id\">\n\t\t\t\t\t<td class=\"align-middle\">{{entry.time}}</td>\n\t\t\t\t\t<td class=\"align-middle text-break\">\n\t\t\t\t\t\t{{entry.labels.description}}\n\t\t\t\t\t</td>\n\t\t\t\t\t<td class=\"td-buttons\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tv-if=\"entry.labels.diff\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t\t\t@click=\"toggleDiffPopover(entry.id)\"\n\t\t\t\t\t\t\t:ref=\"mapRef(diffButtonRefs, entry.id)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon icon=\"info-sign\"></Icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<Popover\n\t\t\t\t\t\t\t:element=\"diffButtonRefs.get(entry.id)\"\n\t\t\t\t\t\t\tplacement=\"bottom\"\n\t\t\t\t\t\t\tclass=\"fm-history-popover\"\n\t\t\t\t\t\t\t:show=\"activeDiffPopoverId === entry.id\"\n\t\t\t\t\t\t\t@update:show=\"toggleDiffPopover(entry.id, $event)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<table class=\"table table-hover table-sm\">\n\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<th>{{i18n.t(\"history-dialog.diff-field\")}}</th>\n\t\t\t\t\t\t\t\t\t\t<th>{{i18n.t(\"history-dialog.diff-before\")}}</th>\n\t\t\t\t\t\t\t\t\t\t<th>{{i18n.t(\"history-dialog.diff-after\")}}</th>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t\t<tr v-for=\"diffItem in entry.labels.diff\" :key=\"diffItem.index\">\n\t\t\t\t\t\t\t\t\t\t<td class=\"text-break\"><code>{{diffItem.index}}</code></td>\n\t\t\t\t\t\t\t\t\t\t<td class=\"text-break\">{{diffItem.before}}</td>\n\t\t\t\t\t\t\t\t\t\t<td class=\"text-break\">{{diffItem.after}}</td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t</Popover>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td class=\"td-buttons\">\n\t\t\t\t\t\t<div class=\"d-grid\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tv-if=\"entry.labels.revert\"\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t\t\t\t:disabled=\"!!isReverting\"\n\t\t\t\t\t\t\t\t@click=\"revert(entry)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div v-if=\"isReverting === entry\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t\t{{entry.labels.revert.button}}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</tbody>\n\t\t</table>\n\t</ModalDialog>\n</template>\n\n<style lang=\"scss\">\n\t.fm-history-popover.fm-history-popover {\n\t\tmax-width: 500px;\n\n\t\t.popover-body {\n\t\t\tmax-height: 70vh;\n\t\t\toverflow: auto;\n\t\t}\n\t}\n\n\t.fm-history {\n\t\t.history-entries > tbody > tr {\n\t\t\t// Make sure that lines without button have the same height as lines with button\n\t\t\theight: calc(/* button line-height */ 1.5rem + /* button padding */ 2 * 0.375rem + /* button border */ 2 * 1px + /* td padding */ 2 * 0.5rem + /* td border-bottom */ 1px);\n\t\t}\n\t}\n</style>","import { Control, DomEvent, DomUtil, Map, type ControlOptions } from \"leaflet\";\n\nexport interface AttributionControlOptions extends ControlOptions {\n\tprefix?: string;\n}\n\n// Like the attribution control from Leaflet, but has a simple update() method that can be called in reaction to language changes\nexport class AttributionControl extends Control {\n\tdeclare options: AttributionControlOptions;\n\tprotected _map?: Map;\n\n\tconstructor(options?: AttributionControlOptions) {\n\t\tsuper({\n\t\t\tposition: 'bottomright',\n\t\t\tprefix: `<a href=\"https://leafletjs.com\" target=\"_blank\">Leaflet</a>`,\n\t\t\t...options\n\t\t});\n\t}\n\n\tonAdd(map: Map): HTMLElement {\n\t\tthis._container = DomUtil.create('div', 'leaflet-control-attribution');\n\t\tDomEvent.disableClickPropagation(this._container);\n\n\t\tthis.update();\n\n\t\tmap.on(\"layeradd\", this.update, this);\n\t\tmap.on(\"layerremove\", this.update, this);\n\n\t\treturn this._container;\n\t}\n\n\tonRemove(map: Map): void {\n\t\tmap.off(\"layeradd\", this.update, this);\n\t\tmap.off(\"layerremove\", this.update, this);\n\t\tdelete this._map;\n\t}\n\n\tupdate(): void {\n\t\tif (this._map) {\n\t\t\tthis._container.innerHTML = [\n\t\t\t\t...(this.options.prefix ? [this.options.prefix] : []),\n\t\t\t\t...Object.values(this._map._layers).flatMap((layer) => {\n\t\t\t\t\tconst attr = layer.getAttribution?.();\n\t\t\t\t\treturn attr ? [attr] : [];\n\t\t\t\t})\n\t\t\t].join(\" <span aria-hidden=\\\"true\\\">|</span> \");\n\t\t}\n\t}\n}","import { type Ref, ref, watch, markRaw, reactive, watchEffect, shallowRef, shallowReadonly, type Raw, nextTick } from \"vue\";\nimport { type Control, latLng, latLngBounds, type Map, map as leafletMap, DomUtil, control } from \"leaflet\";\nimport \"leaflet/dist/leaflet.css\";\nimport { BboxHandler, getSymbolHtml, getVisibleLayers, HashHandler, LinesLayer, MarkersLayer, SearchResultsLayer, OverpassLayer, OverpassLoadStatus, displayView, getInitialView, coreSymbolList } from \"facilmap-leaflet\";\nimport \"leaflet.locatecontrol\";\nimport \"leaflet.locatecontrol/dist/L.Control.Locate.css\";\nimport \"leaflet-graphicscale\";\nimport \"leaflet-graphicscale/dist/Leaflet.GraphicScale.min.css\";\nimport \"leaflet-mouse-position\";\nimport \"leaflet-mouse-position/src/L.Control.MousePosition.css\";\nimport SelectionHandler from \"../../utils/selection\";\nimport { getHashQuery, openSpecialQuery } from \"../../utils/zoom\";\nimport mitt from \"mitt\";\nimport type { MapComponents, MapContextData, MapContextEvents, WritableMapContext } from \"../facil-map-context-provider/map-context\";\nimport type { ClientContext } from \"../facil-map-context-provider/client-context\";\nimport type { FacilMapContext } from \"../facil-map-context-provider/facil-map-context\";\nimport { requireClientContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\nimport { type Optional } from \"facilmap-utils\";\nimport { getI18n, i18nResourceChangeCounter } from \"../../utils/i18n\";\nimport { AttributionControl } from \"./attribution\";\nimport { fixOnCleanup } from \"../../utils/vue\";\n\ntype MapContextWithoutComponents = Optional<WritableMapContext, 'components'>;\ntype OnCleanup = (cleanupFn: () => void) => void;\n\nfunction useMap(element: Ref<HTMLElement>, mapContext: MapContextWithoutComponents): Ref<Raw<Map>> {\n\tconst mapRef = shallowRef(undefined as any as Map);\n\tconst interaction = ref(0);\n\n\twatchEffect((onCleanup) => {\n\t\tconst map = mapRef.value = markRaw(leafletMap(element.value, { boxZoom: false, attributionControl: false }));\n\n\t\tmap._controlCorners.bottomcenter = DomUtil.create(\"div\", \"leaflet-bottom fm-leaflet-center\", map._controlContainer);\n\n\t\tmap.on(\"moveend\", () => {\n\t\t\tmapContext.center = map.getCenter();\n\t\t\tmapContext.zoom = map.getZoom();\n\t\t\tmapContext.bounds = map.getBounds();\n\t\t});\n\n\t\tmap.on(\"fmFilter\", () => {\n\t\t\tmapContext.filter = map.fmFilter;\n\t\t\tmapContext.filterFunc = map.fmFilterFunc;\n\t\t});\n\n\t\tmap.on(\"layeradd layerremove\", () => {\n\t\t\tmapContext.layers = getVisibleLayers(map);\n\t\t});\n\n\t\tmap.on(\"fmInteractionStart\", () => {\n\t\t\tinteraction.value++;\n\t\t});\n\n\t\tmap.on(\"fmInteractionEnd\", () => {\n\t\t\tinteraction.value--;\n\t\t});\n\n\t\tmap.on(\"locationfound\", (data) => {\n\t\t\tmapContext.location = { lat: data.latlng.lat, lon: data.latlng.lng };\n\t\t});\n\n\t\tconst stopLocate = map.stopLocate;\n\t\tmap.stopLocate = function() {\n\t\t\tmapContext.location = undefined;\n\t\t\treturn stopLocate.call(this);\n\t\t};\n\n\t\tonCleanup(() => {\n\t\t\tmap.remove();\n\t\t});\n\t});\n\n\twatch(() => interaction.value, () => {\n\t\tmapContext.interaction = interaction.value > 0;\n\t}, { immediate: true });\n\n\treturn mapRef;\n}\n\nfunction useMapComponent<T>(\n\tmap: Ref<Map>,\n\tconstruct: () => T,\n\tactivate: (component: T, onCleanup: OnCleanup) => void\n): Ref<T> {\n\tconst componentRef = shallowRef(undefined as any as T);\n\twatchEffect(() => {\n\t\tcomponentRef.value = construct();\n\t});\n\n\twatch([\n\t\tcomponentRef,\n\t\tmap\n\t], ([component], prev, onCleanup_) => {\n\t\tconst onCleanup = fixOnCleanup(onCleanup_);\n\t\tactivate(component as T, onCleanup);\n\t}, { immediate: true });\n\n\treturn componentRef;\n}\n\nfunction useAttribution(map: Ref<Map>): Ref<Raw<AttributionControl>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => markRaw(new AttributionControl()),\n\t\t(attribution, onCleanup) => {\n\t\t\tmap.value.addControl(attribution);\n\n\t\t\tconst i18nWatcher = watch(i18nResourceChangeCounter, () => {\n\t\t\t\tattribution.update();\n\t\t\t});\n\t\t\tonCleanup(() => {\n\t\t\t\ti18nWatcher();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useBboxHandler(map: Ref<Map>, client: Ref<ClientContext>): Ref<Raw<BboxHandler>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => markRaw(new BboxHandler(map.value, client.value)),\n\t\t(bboxHandler, onCleanup) => {\n\t\t\tbboxHandler.enable();\n\t\t\tonCleanup(() => {\n\t\t\t\tbboxHandler.disable();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useGraphicScale(map: Ref<Map>): Ref<Raw<any>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => markRaw(control.graphicScale({ fill: \"hollow\", position: \"bottomcenter\" })),\n\t\t(graphicScale, onCleanup) => {\n\t\t\tgraphicScale.addTo(map.value);\n\t\t\tonCleanup(() => {\n\t\t\t\tgraphicScale.remove();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useLinesLayer(map: Ref<Map>, client: Ref<ClientContext>): Ref<Raw<LinesLayer>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => markRaw(new LinesLayer(client.value)),\n\t\t(linesLayer, onCleanup) => {\n\t\t\tlinesLayer.addTo(map.value);\n\t\t\tonCleanup(() => {\n\t\t\t\tlinesLayer.remove();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useLocateControl(map: Ref<Map>, context: FacilMapContext): Ref<Raw<Control.Locate> | undefined> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => {\n\t\t\tif (context.settings.locate) {\n\t\t\t\treturn markRaw(control.locate({\n\t\t\t\t\tflyTo: true,\n\t\t\t\t\ticon: \"a\",\n\t\t\t\t\ticonLoading: \"a\",\n\t\t\t\t\tmarkerStyle: { pane: \"fm-raised-marker\", zIndexOffset: 10000 },\n\t\t\t\t\tlocateOptions: {\n\t\t\t\t\t\tenableHighAccuracy: true\n\t\t\t\t\t},\n\t\t\t\t\tclickBehavior: {\n\t\t\t\t\t\tinView: \"stop\",\n\t\t\t\t\t\toutOfView: \"setView\",\n\t\t\t\t\t\tinViewNotFollowing: \"outOfView\"\n\t\t\t\t\t}\n\t\t\t\t}));\n\t\t\t}\n\t\t},\n\t\t(locateControl, onCleanup) => {\n\t\t\tif (locateControl) {\n\t\t\t\tlocateControl.addTo(map.value);\n\n\t\t\t\tif (!coreSymbolList.includes(\"screenshot\")) {\n\t\t\t\t\tconsole.warn(`Icon \"screenshot\" is not in core icons.`);\n\t\t\t\t}\n\n\t\t\t\tgetSymbolHtml(\"currentColor\", \"1.5em\", \"screenshot\").then((html) => {\n\t\t\t\t\tlocateControl._container.querySelector(\"a\")?.insertAdjacentHTML(\"beforeend\", html);\n\t\t\t\t}).catch((err) => {\n\t\t\t\t\tconsole.error(\"Error loading locate control icon\", err);\n\t\t\t\t});\n\n\t\t\t\tonCleanup(() => {\n\t\t\t\t\tlocateControl.remove();\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t);\n}\n\nfunction useMarkersLayer(map: Ref<Map>, client: Ref<ClientContext>): Ref<Raw<MarkersLayer>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => markRaw(new MarkersLayer(client.value)),\n\t\t(markersLayer, onCleanup) => {\n\t\t\tmarkersLayer.addTo(map.value);\n\t\t\tonCleanup(() => {\n\t\t\t\tmarkersLayer.remove();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useMousePosition(map: Ref<Map>): Ref<Raw<Control.MousePosition>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => markRaw(control.mousePosition({ emptyString: \"0, 0\", separator: \", \", position: \"bottomright\" })),\n\t\t(mousePosition, onCleanup) => {\n\t\t\tmousePosition.addTo(map.value);\n\t\t\tonCleanup(() => {\n\t\t\t\tmousePosition.remove();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useOverpassLayer(map: Ref<Map>, mapContext: MapContextWithoutComponents): Ref<Raw<OverpassLayer>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => markRaw(new OverpassLayer([], { markerShape: \"rectangle-marker\" }))\n\t\t\t.on(\"setQuery\", ({ query }: any) => {\n\t\t\t\tmapContext.overpassIsCustom = typeof query == \"string\";\n\t\t\t\tif (mapContext.overpassIsCustom)\n\t\t\t\t\tmapContext.overpassCustom = query && typeof query == \"string\" ? query : \"\";\n\t\t\t\telse\n\t\t\t\t\tmapContext.overpassPresets = Array.isArray(query) ? query : [];\n\t\t\t})\n\t\t\t.on(\"loadstart\", () => {\n\t\t\t\tmapContext.loading++;\n\t\t\t})\n\t\t\t.on(\"loadend\", ({ status, error }: any) => {\n\t\t\t\tmapContext.loading--;\n\n\t\t\t\tif (status == OverpassLoadStatus.COMPLETE)\n\t\t\t\t\tmapContext.overpassMessage = undefined;\n\t\t\t\telse if (status == OverpassLoadStatus.INCOMPLETE)\n\t\t\t\t\tmapContext.overpassMessage = getI18n().t(\"leaflet-map-components.pois-too-many-results\");\n\t\t\t\telse if (status == OverpassLoadStatus.TIMEOUT)\n\t\t\t\t\tmapContext.overpassMessage = getI18n().t(\"leaflet-map-components.pois-zoom-in\");\n\t\t\t\telse if (status == OverpassLoadStatus.ERROR)\n\t\t\t\t\tmapContext.overpassMessage = getI18n().t(\"leaflet-map-components.pois-error\", { message: error.message });\n\t\t\t})\n\t\t\t.on(\"clear\", () => {\n\t\t\t\tmapContext.overpassMessage = undefined;\n\t\t\t}),\n\t\t(overpassLayer, onCleanup) => {\n\t\t\toverpassLayer.addTo(map.value)\n\t\t\tonCleanup(() => {\n\t\t\t\toverpassLayer.remove();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useSearchResultsLayer(map: Ref<Map>): Ref<Raw<SearchResultsLayer>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => markRaw(new SearchResultsLayer(undefined, { pathOptions: { weight: 7 } })),\n\t\t(searchResultsLayer, onCleanup) => {\n\t\t\tsearchResultsLayer.addTo(map.value);\n\t\t\tonCleanup(() => {\n\t\t\t\tsearchResultsLayer.remove();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useSelectionHandler(map: Ref<Map>, context: FacilMapContext, mapContext: MapContextWithoutComponents, markersLayer: Ref<MarkersLayer>, linesLayer: Ref<LinesLayer>, searchResultsLayer: Ref<SearchResultsLayer>, overpassLayer: Ref<OverpassLayer>): Ref<Raw<SelectionHandler>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => {\n\t\t\tconst selectionHandler = markRaw(new SelectionHandler(map.value, markersLayer.value, linesLayer.value, searchResultsLayer.value, overpassLayer.value));\n\n\t\t\tselectionHandler.on(\"fmChangeSelection\", (event: any) => {\n\t\t\t\tconst selection = selectionHandler.getSelection();\n\t\t\t\tmapContext.selection = selection;\n\n\t\t\t\tif (event.open) {\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tmapContext.emit(\"open-selection\", { selection });\n\t\t\t\t\t}, 0);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tselectionHandler.on(\"fmLongClick\", (event: any) => {\n\t\t\t\tvoid context.components.clickMarkerTab?.openClickMarker({ lat: event.latlng.lat, lon: event.latlng.lng });\n\t\t\t});\n\n\t\t\tselectionHandler.on(\"fmLongClickAbort\", () => {\n\t\t\t\tcontext.components.clickMarkerTab?.closeLastClickMarker();\n\t\t\t});\n\n\t\t\treturn selectionHandler;\n\t\t},\n\t\t(selectionHandler, onCleanup) => {\n\t\t\tselectionHandler.enable();\n\t\t\tonCleanup(() => {\n\t\t\t\tselectionHandler.disable();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useHashHandler(map: Ref<Map>, client: Ref<ClientContext>, context: FacilMapContext, mapContext: MapContextWithoutComponents, overpassLayer: Ref<OverpassLayer>): Ref<Raw<HashHandler & { _fmActivate: () => Promise<void> }>> {\n\treturn useMapComponent(\n\t\tmap,\n\t\t() => {\n\t\t\tlet queryChangePromise: Promise<void> | undefined;\n\t\t\tconst hashHandler = markRaw(new HashHandler(map.value, client.value, { overpassLayer: overpassLayer.value, simulate: !context.settings.updateHash }))\n\t\t\t\t.on(\"fmQueryChange\", async (e: any) => {\n\t\t\t\t\tlet smooth = true;\n\t\t\t\t\tlet autofocus = false;\n\n\t\t\t\t\tconst searchFormTab = context.components.searchFormTab;\n\t\t\t\t\tqueryChangePromise = (async () => {\n\t\t\t\t\t\tif (!e.query)\n\t\t\t\t\t\t\tawait searchFormTab?.setQuery(\"\", false, false);\n\t\t\t\t\t\telse if (!await openSpecialQuery(e.query, context, e.zoom, smooth))\n\t\t\t\t\t\t\tawait searchFormTab?.setQuery(e.query, e.zoom, smooth, autofocus);\n\t\t\t\t\t})();\n\t\t\t\t\tawait queryChangePromise;\n\t\t\t\t})\n\t\t\t\t.on(\"fmHash\", (e: any) => {\n\t\t\t\t\tmapContext.hash = e.hash;\n\t\t\t\t});\n\t\t\treturn Object.assign(hashHandler, {\n\t\t\t\t_fmActivate: async () => {\n\t\t\t\t\thashHandler.enable();\n\t\t\t\t\tawait queryChangePromise;\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t(hashHandler, onCleanup) => {\n\t\t\tonCleanup(() => {\n\t\t\t\thashHandler.disable();\n\t\t\t});\n\t\t}\n\t);\n}\n\nfunction useMapComponents(context: FacilMapContext, mapContext: MapContextWithoutComponents, mapRef: Ref<HTMLElement>, innerContainerRef: Ref<HTMLElement>): MapComponents {\n\tconst client = requireClientContext(context);\n\tconst map = useMap(mapRef, mapContext);\n\tconst attribution = useAttribution(map);\n\tconst bboxHandler = useBboxHandler(map, client);\n\tconst graphicScale = useGraphicScale(map);\n\tconst linesLayer = useLinesLayer(map, client);\n\tconst locateControl = useLocateControl(map, context);\n\tconst markersLayer = useMarkersLayer(map, client);\n\tconst mousePosition = useMousePosition(map);\n\tconst overpassLayer = useOverpassLayer(map, mapContext);\n\tconst searchResultsLayer = useSearchResultsLayer(map);\n\tconst selectionHandler = useSelectionHandler(map, context, mapContext, markersLayer, linesLayer, searchResultsLayer, overpassLayer);\n\tconst hashHandler = useHashHandler(map, client, context, mapContext, overpassLayer);\n\n\tconst components: MapComponents = reactive({\n\t\tmap,\n\t\tattribution,\n\t\tbboxHandler,\n\t\tgraphicScale,\n\t\tlinesLayer,\n\t\tlocateControl,\n\t\tmarkersLayer,\n\t\tmousePosition,\n\t\toverpassLayer,\n\t\tsearchResultsLayer,\n\t\tselectionHandler,\n\t\thashHandler,\n\t\tcontainer: innerContainerRef\n\t});\n\n\treturn shallowReadonly(components);\n}\n\nexport async function useMapContext(context: FacilMapContext, mapRef: Ref<HTMLElement>, innerContainerRef: Ref<HTMLElement>): Promise<WritableMapContext> {\n\tconst mapContextWithoutComponents: MapContextWithoutComponents = reactive(Object.assign(mitt<MapContextEvents>(), {\n\t\tcenter: latLng(0, 0),\n\t\tzoom: 1,\n\t\tbounds: latLngBounds([0, 0], [0, 0]),\n\t\tlayers: { baseLayer: \"\", overlays: [] },\n\t\tfilter: undefined,\n\t\tfilterFunc: () => true,\n\t\thash: location.hash.replace(/^#/, \"\"),\n\t\tshowToolbox: false,\n\t\tselection: [],\n\t\tactiveQuery: undefined,\n\t\tfallbackQuery: undefined,\n\t\tsetFallbackQuery: (query) => {\n\t\t\tmapContext.fallbackQuery = query;\n\t\t},\n\t\tinteraction: false,\n\t\tloading: 0,\n\t\toverpassIsCustom: false,\n\t\toverpassPresets: [],\n\t\toverpassCustom: \"\",\n\t\toverpassMessage: undefined,\n\t\tlocation: undefined,\n\t\tloaded: false,\n\t\tfatalError: undefined,\n\t\trunOperation: async (operation) => {\n\t\t\ttry {\n\t\t\t\tmapContextWithoutComponents.loading++;\n\t\t\t\treturn await operation();\n\t\t\t} finally {\n\t\t\t\tmapContextWithoutComponents.loading--;\n\t\t\t}\n\t\t}\n\t} satisfies Omit<MapContextData, 'components'>));\n\n\tconst mapContext: WritableMapContext = Object.assign(mapContextWithoutComponents, {\n\t\tcomponents: useMapComponents(context, mapContextWithoutComponents, mapRef, innerContainerRef)\n\t});\n\n\tconst map = mapContext.components.map;\n\tconst overpassLayer = mapContext.components.overpassLayer;\n\n\tconst client = requireClientContext(context);\n\n\t(async () => {\n\t\tawait nextTick(); // useMapContext() return promise is resolved, setting mapContext.value in <LeafletMap>\n\t\tawait nextTick(); // <LeafletMap> rerenders with its slot, search box tabs are now available and can receive the query from the hash handler\n\n\t\tawait mapContext.components.hashHandler._fmActivate();\n\n\t\tif (!map._loaded) {\n\t\t\ttry {\n\t\t\t\t// Initial view was not set by hash handler\n\t\t\t\tdisplayView(map, await getInitialView(client.value), { overpassLayer });\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(error);\n\t\t\t\tdisplayView(map, undefined, { overpassLayer });\n\t\t\t}\n\t\t}\n\n\t\twatch(() => mapContext.components.hashHandler, async (hashHandler) => {\n\t\t\tawait hashHandler._fmActivate();\n\t\t});\n\n\t\twatchEffect(() => {\n\t\t\tmapContext.activeQuery = getHashQuery(mapContext.components.map, client.value, mapContext.selection) || mapContext.fallbackQuery;\n\t\t\tmapContext.components.hashHandler.setQuery(mapContext.activeQuery);\n\t\t});\n\t})().catch(console.error);\n\n\treturn mapContext;\n}\n\n/* function createButton(symbol: string, onClick: () => void): Control {\n\treturn Object.assign(new Control(), {\n\t\tonAdd() {\n\t\t\tconst div = document.createElement('div');\n\t\t\tdiv.className = \"leaflet-bar\";\n\t\t\tconst a = document.createElement('a');\n\t\t\ta.href = \"javascript:\";\n\t\t\ta.innerHTML = createSymbolHtml(\"currentColor\", \"1.5em\", symbol);\n\t\t\ta.addEventListener(\"click\", (e) => {\n\t\t\t\te.preventDefault();\n\t\t\t\tonClick();\n\t\t\t});\n\t\t\tdiv.appendChild(a);\n\t\t\treturn div;\n\t\t}\n\t});\n} */","export default \"data:image/png;base64,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\"","<script setup lang=\"ts\">\n\timport { type Ref, computed, onMounted, ref } from \"vue\";\n\timport { useMapContext } from \"./leaflet-map-components\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport type { WritableMapContext } from \"../facil-map-context-provider/map-context\";\n\timport { injectContextRequired, requireClientContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst i18n = useI18n();\n\n\tconst innerContainerRef = ref<HTMLElement>();\n\tconst mapRef = ref<HTMLElement>();\n\n\tconst loaded = ref(false);\n\tconst fatalError = ref<string>();\n\n\tconst selfUrl = computed(() => {\n\t\treturn `${location.origin}${location.pathname}${mapContext.value?.hash ? `#${mapContext.value.hash}` : ''}`;\n\t});\n\n\tconst mapContext = ref<WritableMapContext>();\n\n\tonMounted(async () => {\n\t\ttry {\n\t\t\tmapContext.value = await useMapContext(context, mapRef as Ref<HTMLElement>, innerContainerRef as Ref<HTMLElement>);\n\t\t\tloaded.value = true;\n\t\t} catch (err: any) {\n\t\t\tconsole.error(err);\n\t\t\tfatalError.value = err.message;\n\t\t}\n\t});\n\n\tcontext.provideComponent(\"map\", mapContext);\n</script>\n\n<template>\n\t<div class=\"fm-leaflet-map-container\" :class=\"{ isNarrow: context.isNarrow }\">\n\t\t<slot v-if=\"mapContext\" name=\"before\"></slot>\n\n\t\t<div class=\"fm-leaflet-map-wrapper\">\n\t\t\t<div class=\"fm-leaflet-map-inner-container\" ref=\"innerContainerRef\">\n\t\t\t\t<div class=\"fm-leaflet-map\" ref=\"mapRef\"></div>\n\n\t\t\t\t<div v-if=\"mapContext && mapContext.overpassMessage\" class=\"alert alert-warning fm-overpass-message\">\n\t\t\t\t\t{{mapContext.overpassMessage}}\n\t\t\t\t</div>\n\n\t\t\t\t<a\n\t\t\t\t\tv-if=\"context.settings.linkLogo\"\n\t\t\t\t\t:href=\"selfUrl\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\tclass=\"fm-open-external\"\n\t\t\t\t\tv-tooltip.right=\"i18n.t('leaflet-map.open-full-size', { appName: context.appName })\"\n\t\t\t\t></a>\n\t\t\t\t<div class=\"fm-logo\">\n\t\t\t\t\t<img src=\"./logo.png\"/>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"spinner-border fm-leaflet-map-spinner\" v-show=\"client.loading > 0 || (mapContext && mapContext.loading > 0)\"></div>\n\n\t\t\t\t<slot v-if=\"mapContext\"></slot>\n\t\t\t</div>\n\t\t\t<slot v-if=\"mapContext\" name=\"after\"></slot>\n\t\t</div>\n\n\t\t<div class=\"fm-leaflet-map-disabled-cover\" v-show=\"client.padId && (client.disconnected || (client.serverError && !client.isCreatePad) || client.deleted)\"></div>\n\t\t<div class=\"fm-leaflet-map-loading\" v-show=\"!loaded && !client.serverError && !client.isCreatePad\" :class=\"{ 'fatal-error': !!fatalError }\">\n\t\t\t{{fatalError || i18n.t(\"leaflet-map.loading\")}}\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-leaflet-map-container {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tflex-grow: 1;\n\t\tposition: relative;\n\n\t\t.fm-leaflet-map-wrapper {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tflex-grow: 1;\n\t\t\tposition: relative;\n\t\t}\n\n\t\t.fm-leaflet-map-inner-container {\n\t\t\tposition: relative;\n\t\t\tflex-grow: 1;\n\t\t}\n\n\t\t.fm-leaflet-map {\n\t\t\tposition: absolute;\n\t\t\ttop: 0;\n\t\t\tright: 0;\n\t\t\tleft: 0;\n\t\t\tbottom: 0;\n\t\t\tz-index: 0;\n\t\t\tuser-select: none;\n\t\t\t-webkit-user-select: none;\n\n\t\t\t.fm-leaflet-center {\n\t\t\t\tleft: 50%;\n\t\t\t\ttransform: translateX(-50%);\n\t\t\t\ttext-align: center;\n\n\t\t\t\t.leaflet-control {\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\tfloat: none;\n\t\t\t\t\tclear: none;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.leaflet-control.leaflet-control-mouseposition {\n\t\t\t\tfloat: left;\n\t\t\t\tpointer-events: none;\n\t\t\t\tpadding-right: 0;\n\n\t\t\t\t&:after {\n\t\t\t\t\tcontent: \" |\";\n\t\t\t\t}\n\n\t\t\t\t& + * {\n\t\t\t\t\tclear: none;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.leaflet-control.leaflet-control-graphicscale {\n\t\t\t\tmargin-bottom: 0;\n\t\t\t\tpointer-events: none;\n\n\t\t\t\t.label {\n\t\t\t\t\tcolor: #000;\n\t\t\t\t\ttext-shadow: 0 0 3px #fff, 0 0 5px #fff, 0 0 10px #fff;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.leaflet-control-locate.leaflet-control-locate {\n\t\t\t\ta {\n\t\t\t\t\tfont-size: inherit;\n\t\t\t\t\tdisplay: inline-flex;\n\t\t\t\t\talign-items: center;\n\t\t\t\t\tjustify-content: center;\n\t\t\t\t}\n\n\t\t\t\t&.active a {\n\t\t\t\t\tcolor: rgb(32, 116, 182);\n\t\t\t\t}\n\n\t\t\t\t&.following a {\n\t\t\t\t\tcolor: rgb(252, 132, 40);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpath.leaflet-interactive {\n\t\t\t\t// Do not show focus ring\n\t\t\t\toutline: none;\n\t\t\t}\n\n\t\t}\n\n\t\t&.isNarrow {\n\t\t\t.leaflet-control-graphicscale,.leaflet-control-mouseposition {\n\t\t\t\tdisplay: none !important;\n\t\t\t}\n\t\t}\n\n\t\t.fm-leaflet-map-disabled-cover {\n\t\t\tbackground-color: #888;\n\t\t\topacity: 0.7;\n\t\t\tposition: absolute;\n\t\t\ttop: 0;\n\t\t\tleft: 0;\n\t\t\twidth: 100%;\n\t\t\theight: 100%;\n\t\t\tz-index: 10001;\n\t\t}\n\n\t\t.fm-leaflet-map-loading {\n\t\t\tposition:absolute;\n\t\t\ttop:0;\n\t\t\tleft:0;\n\t\t\tright:0;\n\t\t\tbottom:0;\n\t\t\tpadding:10px;\n\t\t\tbackground: #fff;\n\t\t\tz-index:100000;\n\t\t\tfont-size:1.5em;\n\t\t\tfont-weight:bold;\n\n\t\t\t&.fatal-error {\n\t\t\t\tcolor: #d00;\n\t\t\t}\n\t\t}\n\n\t\t.fm-overpass-message {\n\t\t\tposition: absolute;\n\t\t\ttop: 10px;\n\t\t\tright: 50%;\n\t\t\ttransform: translateX(50%);\n\t\t\tmax-width: calc(100vw - 1050px);\n\t\t}\n\n\t\t&.isNarrow .fm-overpass-message {\n\t\t\tmax-width: none;\n\t\t}\n\n\t\t@media(max-width: 1250px) {\n\t\t\t&:not(.isNarrow) .fm-overpass-message {\n\t\t\t\ttop: 69px;\n\t\t\t\tright: 10px;\n\t\t\t\ttransform: none;\n\t\t\t\tmax-width: 400px;\n\t\t\t}\n\t\t}\n\n\t\t.fm-leaflet-map-spinner {\n\t\t\tposition:absolute;\n\t\t\tbottom: 20px;\n\t\t\tleft: 115px;\n\t\t\tcolor: #00272a;\n\t\t}\n\n\t\t.fm-logo {\n\t\t\tposition: absolute;\n\t\t\tbottom: 0;\n\t\t\tleft: -25px;\n\t\t\tpointer-events: none;\n\t\t\toverflow: hidden;\n\t\t\tuser-select: none;\n\t\t\t-webkit-user-select: none;\n\n\t\t\timg {\n\t\t\t\tmargin-bottom: -24px;\n\t\t\t}\n\t\t}\n\n\t\t.fm-open-external {\n\t\t\tposition: absolute;\n\t\t\tbottom: 15px;\n\t\t\tleft: 15px;\n\t\t\twidth: 90px;\n\t\t\theight: 50px;\n\t\t}\n\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { getMarkerHtml, getSymbolHtml } from \"facilmap-leaflet\";\n\timport { makeTypeFilter, markdownBlock } from \"facilmap-utils\";\n\timport type { LegendItem, LegendType } from \"./legend-utils\";\n\timport { createLinePlaceholderHtml } from \"../../utils/ui\";\n\timport Popover from \"../ui/popover.vue\";\n\timport { computed, reactive, ref } from \"vue\";\n\timport { mapRef, vHtmlAsync } from \"../../utils/vue\";\n\timport { injectContextRequired, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tlegend1?: string;\n\t\tlegend2?: string;\n\t\titems: LegendType[];\n\t\tnoPopover?: boolean;\n\t}>(), {\n\t\tnoPopover: false\n\t});\n\n\tconst activePopoverKey = ref<string>();\n\tconst itemIconRefs = reactive(new Map<string, HTMLElement>());\n\n\tconst legend1Html = computed(() => {\n\t\treturn props.legend1 ? markdownBlock(props.legend1, true) : \"\";\n\t});\n\n\tconst legend2Html = computed(() => {\n\t\treturn props.legend2 ? markdownBlock(props.legend2, true) : \"\";\n\t});\n\n\tfunction toggleFilter(typeInfo: LegendType, item?: LegendItem): void {\n\t\tlet filters: Parameters<typeof makeTypeFilter>[2] = { };\n\t\tif(!item || !item.field) // We are toggling the visibility of one whole type\n\t\t\tfilters = !typeInfo.filtered;\n\t\telse {\n\t\t\tfor (const it of typeInfo.items) {\n\t\t\t\tif(it.field) {\n\t\t\t\t\tif(!filters[it.field])\n\t\t\t\t\t\tfilters[it.field] = { };\n\n\t\t\t\t\tif(!typeInfo.filtered || it.field == item.field)\n\t\t\t\t\t\tfilters[it.field][it.value] = (it.filtered == (it != item));\n\t\t\t\t\telse // If the whole type is filtered, we have to enable the filters of the other fields, otherwise the type will still be completely filtered\n\t\t\t\t\t\tfilters[it.field][it.value] = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tmapContext.value.components.map.setFmFilter(makeTypeFilter(mapContext.value.components.map.fmFilter, typeInfo.typeId, filters));\n\t}\n\n\tasync function makeSymbol(typeInfo: LegendType, item: LegendItem, height = 15): Promise<string> {\n\t\tif(typeInfo.type == \"line\")\n\t\t\treturn createLinePlaceholderHtml(item.colour || \"rainbow\", item.width || 5, 50, item.stroke ?? \"\");\n\t\telse if (item.colour || item.shape != null)\n\t\t\treturn await getMarkerHtml(item.colour || \"rainbow\", height, item.symbol, item.shape);\n\t\telse\n\t\t\treturn await getSymbolHtml(\"#000000\", height, item.symbol);\n\t}\n\n\tfunction togglePopover(itemKey: string, show: boolean) {\n\t\tconst isShown = activePopoverKey.value === itemKey;\n\t\tif (isShown !== show) {\n\t\t\tactivePopoverKey.value = show ? itemKey : undefined;\n\t\t}\n\t}\n</script>\n\n<template>\n\t<div class=\"fm-legend-content\">\n\t\t<div v-if=\"legend1\" class=\"fm-legend1\">\n\t\t\t<div v-html=\"legend1Html\"></div>\n\t\t\t<hr v-if=\"items.length > 0 || legend2\" />\n\t\t</div>\n\n\t\t<template v-for=\"(type, idx) in items\" :key=\"type.key\">\n\t\t\t<hr v-if=\"idx > 0\">\n\t\t\t<h3 @click=\"toggleFilter(type)\" :class=\"{ filtered: type.filtered }\">{{type.name}}</h3>\n\t\t\t<dl>\n\t\t\t\t<template v-for=\"(item, idx) in type.items\" :key=\"item.key\">\n\t\t\t\t\t<dt\n\t\t\t\t\t\t:class=\"[ 'fm-legend-symbol', 'fm-' + type.type, { filtered: item.filtered, first: (item.first && idx !== 0), bright: item.bright } ]\"\n\t\t\t\t\t\t@click=\"toggleFilter(type, item)\"\n\t\t\t\t\t\tv-html-async=\"makeSymbol(type, item)\"\n\t\t\t\t\t\t@mouseenter=\"togglePopover(item.key, true)\"\n\t\t\t\t\t\t@mouseleave=\"togglePopover(item.key, false)\"\n\t\t\t\t\t\t:ref=\"mapRef(itemIconRefs, item.key)\"\n\t\t\t\t\t></dt>\n\t\t\t\t\t<dd\n\t\t\t\t\t\tclass=\"text-break\"\n\t\t\t\t\t\t:class=\"[ 'fm-' + type.type, { filtered: item.filtered, first: (item.first && idx !== 0), bright: item.bright } ]\"\n\t\t\t\t\t\t@click=\"toggleFilter(type, item)\"\n\t\t\t\t\t\t:style=\"item.strikethrough ? {'text-decoration': 'line-through'} : {}\"\n\t\t\t\t\t\t@mouseenter=\"togglePopover(item.key, true)\"\n\t\t\t\t\t\t@mouseleave=\"togglePopover(item.key, false)\"\n\t\t\t\t\t>{{item.label}}</dd>\n\t\t\t\t</template>\n\t\t\t</dl>\n\t\t\t<div v-if=\"!props.noPopover\" class=\"fm-legend-popover-wrapper\">\n\t\t\t\t<template v-for=\"item in type.items\" :key=\"item.key\">\n\t\t\t\t\t<Popover\n\t\t\t\t\t\t:element=\"itemIconRefs.get(item.key)\"\n\t\t\t\t\t\tplacement=\"left\"\n\t\t\t\t\t\tclass=\"fm-legend-popover\"\n\t\t\t\t\t\t:show=\"activePopoverKey === item.key\"\n\t\t\t\t\t\t@update:show=\"togglePopover(item.key, $event)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t:class=\"[\n\t\t\t\t\t\t\t\t'fm-legend-symbol',\n\t\t\t\t\t\t\t\t`fm-${type.type}`,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfiltered: item.filtered,\n\t\t\t\t\t\t\t\t\tbright: item.bright\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\"\n\t\t\t\t\t\t\tv-html-async=\"makeSymbol(type, item, 40)\"\n\t\t\t\t\t\t></div>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t<span class=\"text-break\" :style=\"item.strikethrough ? {'text-decoration': 'line-through'} : {}\">{{item.label}}</span>\n\t\t\t\t\t\t\t<br>\n\t\t\t\t\t\t\t<small><em>{{i18n.t(\"legend-content.click-explanation\")}}</em></small>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</Popover>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<div v-if=\"legend2\" class=\"fm-legend2\">\n\t\t\t<hr v-if=\"items.length > 0\" />\n\t\t\t<div v-html=\"legend2Html\"></div>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-legend-content {\n\t\tfont-size: 12px;\n\n\t\t:is(.fm-legend1,.fm-legend2) > div > *:first-child {\n\t\t\tmargin-top: 0;\n\n\t\t}\n\n\t\t:is(.fm-legend1,.fm-legend2) > div > *:last-child {\n\t\t\tmargin-bottom: 0;\n\t\t}\n\n\t\th3 {\n\t\t\tfont-size: 1.1em;\n\t\t\tmargin: 0 0 5px 0;\n\t\t\tpadding: 0;\n\t\t\tfont-weight: bold;\n\t\t\tcursor: pointer;\n\t\t}\n\n\t\thr {\n\t\t\tmargin: 10px -8px;\n\t\t}\n\n\t\tdl {\n\t\t\t// In narrow mode, SearchBox sets some styles for dl. We need to take care of overriding them here.\n\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: calc(11px + 1ex) calc(50px - 11px) 1fr;\n\t\t\tmargin: 0px;\n\t\t\talign-items: center;\n\n\t\t\t> * {\n\t\t\t\tmargin: 0;\n\t\t\t\tcursor: pointer;\n\t\t\t}\n\n\t\t\tdt.fm-marker {\n\t\t\t\tgrid-column: 1 / 2;\n\t\t\t}\n\n\t\t\tdd.fm-marker {\n\t\t\t\tgrid-column: 2 / 4;\n\t\t\t}\n\n\t\t\tdt.fm-line {\n\t\t\t\tgrid-column: 1 / 3;\n\t\t\t}\n\n\t\t\tdd.fm-line {\n\t\t\t\tgrid-column: 3 / 4;\n\t\t\t}\n\n\t\t\tdt:after,dl:after {\n\t\t\t\tcontent: none;\n\t\t\t}\n\n\t\t\t.first {\n\t\t\t\tmargin-top: 6px;\n\t\t\t}\n\t\t}\n\n\t\t.filtered {\n\t\t\topacity: 0.5;\n\t\t}\n\t}\n\n\t.fm-legend-popover {\n\t\tmax-width: none;\n\n\t\t.popover-body {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\twidth: max-content;\n\t\t\tmax-width: 100%;\n\n\t\t\tp {\n\t\t\t\tmargin: 0 0 0 0.5em;\n\t\t\t}\n\t\t}\n\t}\n</style>","import type { ID, Shape, Stroke, Symbol, Type } from \"facilmap-types\";\nimport { symbolList } from \"facilmap-leaflet\";\nimport { formatTypeName, getOrderedTypes, isBright } from \"facilmap-utils\";\nimport type { FacilMapContext } from \"../facil-map-context-provider/facil-map-context\";\nimport { requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\nexport interface LegendType {\n\tkey: string;\n\ttype: Type['type'];\n\ttypeId: ID;\n\tname: string;\n\titems: LegendItem[];\n\tfiltered: boolean;\n}\n\nexport interface LegendItem {\n\tkey: string;\n\tvalue: string;\n\tlabel?: string;\n\tfield?: string;\n\tfiltered?: boolean;\n\tfirst?: boolean;\n\tstrikethrough?: boolean;\n\tcolour?: string;\n\tsymbol?: Symbol;\n\tshape?: Shape;\n\twidth?: number;\n\tstroke?: Stroke;\n\tbright?: boolean;\n}\n\nexport function getLegendItems(context: FacilMapContext): LegendType[] {\n\tconst client = requireClientContext(context).value;\n\tconst mapContext = requireMapContext(context).value;\n\n\tconst legendItems: LegendType[] = [ ];\n\tfor (const type of getOrderedTypes(client.types)) {\n\t\tif(!type.showInLegend)\n\t\t\tcontinue;\n\n\t\tconst items: LegendItem[] = [ ];\n\t\tconst fields: Record<string, string[]> = Object.create(null);\n\n\t\tif (\n\t\t\ttype.colourFixed ||\n\t\t\t(type.type == \"marker\" && type.symbolFixed && type.defaultSymbol && (symbolList.includes(type.defaultSymbol) || type.defaultSymbol.length == 1)) ||\n\t\t\t(type.type == \"marker\" && type.shapeFixed) ||\n\t\t\t(type.type == \"line\" && type.widthFixed) ||\n\t\t\t(type.type === \"line\" && type.strokeFixed)\n\t\t) {\n\t\t\tconst item: LegendItem = {\n\t\t\t\tkey: `legend-item-${type.id}`,\n\t\t\t\tvalue: type.name,\n\t\t\t\tlabel: formatTypeName(type.name),\n\t\t\t\tfiltered: true\n\t\t\t};\n\n\t\t\tif (type.colourFixed) {\n\t\t\t\titem.colour = type.defaultColour ? `#${type.defaultColour}` : undefined;\n\t\t\t}\n\t\t\tif (type.type == \"marker\" && type.symbolFixed && type.defaultSymbol && (symbolList.includes(type.defaultSymbol) || type.defaultSymbol.length == 1)) {\n\t\t\t\titem.symbol = type.defaultSymbol;\n\t\t\t}\n\t\t\tif (type.type == \"marker\" && type.shapeFixed) {\n\t\t\t\titem.shape = type.defaultShape ?? \"\";\n\t\t\t}\n\t\t\tif (type.type == \"line\" && type.widthFixed) {\n\t\t\t\titem.width = type.defaultWidth ?? undefined;\n\t\t\t}\n\t\t\tif (type.type === \"line\" && type.strokeFixed) {\n\t\t\t\titem.stroke = type.defaultStroke;\n\t\t\t}\n\n\t\t\tif (item.colour)\n\t\t\t\titem.bright = isBright(item.colour);\n\n\t\t\titems.push(item);\n\t\t}\n\n\t\tfor (const field of type.fields) {\n\t\t\tif (\n\t\t\t\t(field.type != \"dropdown\" && field.type != \"checkbox\") ||\n\t\t\t\t(\n\t\t\t\t\t!field.controlColour &&\n\t\t\t\t\t!(type.type === \"marker\" && field.controlSymbol) &&\n\t\t\t\t\t!(type.type === \"marker\" && field.controlShape) &&\n\t\t\t\t\t!(type.type === \"line\" && field.controlWidth) &&\n\t\t\t\t\t!(type.type === \"line\" && field.controlStroke)\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tcontinue;\n\n\t\t\tfields[field.name] = [ ];\n\n\t\t\t(field.options || [ ]).forEach((option, idx) => {\n\t\t\t\tconst item: LegendItem = {\n\t\t\t\t\tkey: `legend-item-${type.id}-${field.name}-${option.value}`,\n\t\t\t\t\tvalue: option.value,\n\t\t\t\t\tlabel: option.value,\n\t\t\t\t\tfield: field.name,\n\t\t\t\t\tfiltered: true,\n\t\t\t\t\tfirst: idx == 0\n\t\t\t\t};\n\n\t\t\t\tif(field.type == \"checkbox\") {\n\t\t\t\t\titem.value = idx == 0 ? \"0\" : \"1\";\n\n\t\t\t\t\tif(!item.label || /* Legacy format */ item.label == '0' || item.label == '1') {\n\t\t\t\t\t\titem.label = field.name;\n\t\t\t\t\t\tif(idx == 0)\n\t\t\t\t\t\t\titem.strikethrough = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (field.controlColour) {\n\t\t\t\t\titem.colour = `#${option.colour ?? type.defaultColour}`;\n\t\t\t\t} else if (type.colourFixed) {\n\t\t\t\t\titem.colour = `#${type.defaultColour}`;\n\t\t\t\t}\n\n\t\t\t\tif (type.type == \"marker\") {\n\t\t\t\t\tif (field.controlSymbol) {\n\t\t\t\t\t\titem.symbol = option.symbol ?? type.defaultSymbol;\n\t\t\t\t\t} else if (type.symbolFixed) {\n\t\t\t\t\t\titem.symbol = type.defaultSymbol;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (field.controlShape) {\n\t\t\t\t\t\titem.shape = option.shape ?? type.defaultShape;\n\t\t\t\t\t} else if (type.shapeFixed) {\n\t\t\t\t\t\titem.shape = type.defaultShape;\n\t\t\t\t\t}\n\t\t\t\t} else if (type.type == \"line\") {\n\t\t\t\t\tif (field.controlWidth) {\n\t\t\t\t\t\titem.width = option.width ?? type.defaultWidth;\n\t\t\t\t\t} else if (type.widthFixed) {\n\t\t\t\t\t\titem.width = type.defaultWidth;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (field.controlStroke) {\n\t\t\t\t\t\titem.stroke = option.stroke ?? type.defaultStroke;\n\t\t\t\t\t} else if (type.strokeFixed) {\n\t\t\t\t\t\titem.stroke = type.defaultStroke;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (item.colour) {\n\t\t\t\t\titem.bright = isBright(item.colour);\n\t\t\t\t}\n\n\t\t\t\titems.push(item);\n\t\t\t\tfields[field.name].push(item.value);\n\t\t\t});\n\t\t}\n\n\t\tif(items.length == 0) {\n\t\t\tconst item: LegendItem = {\n\t\t\t\tkey: `legend-item-${type.id}`,\n\t\t\t\tvalue: type.name,\n\t\t\t\tlabel: formatTypeName(type.name),\n\t\t\t\tfiltered: true\n\t\t\t};\n\n\t\t\tif(type.type == \"marker\")\n\t\t\t\titem.shape = \"drop\";\n\n\t\t\titems.push(item);\n\t\t}\n\n\t\tconst legendType: LegendType = {\n\t\t\tkey: `legend-type-${type.id}`,\n\t\t\ttype: type.type,\n\t\t\ttypeId: type.id,\n\t\t\tname: formatTypeName(type.name),\n\t\t\titems,\n\t\t\tfiltered: true,\n\t\t};\n\n\t\t// Check which fields are filtered\n\t\tallCombinations(fields, (data) => {\n\t\t\tif(mapContext.filterFunc({ typeId: legendType.typeId, data } as any, type)) {\n\t\t\t\tlegendType.filtered = false;\n\n\t\t\t\tfor (const item of items) {\n\t\t\t\t\tif (!item.field)\n\t\t\t\t\t\titem.filtered = false;\n\t\t\t\t}\n\n\t\t\t\tfor(const i in data) {\n\t\t\t\t\titems.forEach(function(it) {\n\t\t\t\t\t\tif(it.field == i && it.value == data[i])\n\t\t\t\t\t\t\tit.filtered = false;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tlegendItems.push(legendType);\n\t}\n\n\treturn legendItems;\n}\n\nfunction allCombinations(fields: Record<string, string[]>, callback: (data: Record<string, string>) => void): void {\n\tconst fieldKeys = Object.keys(fields);\n\n\tfunction rec(i: number, vals: Record<string, string>) {\n\t\tif(i == fieldKeys.length)\n\t\t\treturn callback(vals);\n\n\t\tfor (const f of fields[fieldKeys[i]]) {\n\t\t\tvals[fieldKeys[i]] = f;\n\t\t\trec(i+1, vals);\n\t\t}\n\t}\n\n\trec(0, Object.create(null));\n}","<script setup lang=\"ts\">\n\timport { computed, watch } from \"vue\";\n\timport type { HashQuery } from \"facilmap-leaflet\";\n\timport { injectContextRequired, requireSearchBoxContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport type { SearchBoxTab } from \"../facil-map-context-provider/search-box-context\";\n\n\tconst props = defineProps<{\n\t\tid: string;\n\t\ttitle: string;\n\t\tisCloseable?: boolean;\n\t\thashQuery?: HashQuery;\n\t\tclass?: string;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\tclose: [];\n\t}>();\n\n\tconst context = injectContextRequired();\n\tconst searchBoxContext = requireSearchBoxContext(context);\n\n\tconst slots = defineSlots<{\n\t\tdefault(props: { isActive: boolean }): any;\n\t}>();\n\n\tconst tab = computed((): SearchBoxTab => ({\n\t\ttitle: props.title,\n\t\tcontent: slots.default,\n\t\thashQuery: props.hashQuery,\n\t\tclass: props.class,\n\t\tonClose: props.isCloseable ? () => {\n\t\t\temit(\"close\");\n\t\t} : undefined\n\t}));\n\n\twatch(searchBoxContext, () => {\n\t\tsearchBoxContext.value.provideTab(props.id, tab);\n\t}, { immediate: true });\n</script>\n\n<!-- eslint-disable-next-line vue/valid-template-root -->\n<template>\n</template>","<script setup lang=\"ts\">\n\timport { round } from \"facilmap-utils\";\n\timport LegendContent from \"./legend-content.vue\";\n\timport { getLegendItems } from \"./legend-utils\";\n\timport SearchBoxTab from \"../search-box/search-box-tab.vue\";\n\timport { computed, ref } from \"vue\";\n\timport { useDomEventListener } from \"../../utils/utils\";\n\timport { useResizeObserver } from \"../../utils/vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst absoluteContainerRef = ref<HTMLElement>();\n\n\tconst scale = ref(1);\n\n\tuseDomEventListener(window, \"resize\", updateMaxScale);\n\tuseResizeObserver(absoluteContainerRef, updateMaxScale);\n\tupdateMaxScale();\n\n\tfunction updateMaxScale(): void {\n\t\tif (absoluteContainerRef.value) {\n\t\t\tconst mapContainer = mapContext.value.components.map.getContainer();\n\t\t\tconst maxHeight = mapContainer.offsetHeight - 94;\n\t\t\tconst maxWidth = mapContainer.offsetWidth - 20;\n\n\t\t\tconst currentHeight = absoluteContainerRef.value.offsetHeight;\n\t\t\tconst currentWidth = absoluteContainerRef.value.offsetWidth;\n\n\t\t\tconst newScale = round(Math.min(1, maxHeight / currentHeight, maxWidth / currentWidth), 4);\n\t\t\tif (isFinite(newScale) && newScale != scale.value)\n\t\t\t\tscale.value = newScale;\n\t\t}\n\t}\n\n\tconst legend1 = computed(() => {\n\t\treturn client.value.padData?.legend1?.trim() || \"\";\n\t});\n\n\tconst legend2 = computed(() => {\n\t\treturn client.value.padData?.legend2?.trim() || \"\";\n\t});\n\n\tconst legendItems = computed(() => {\n\t\treturn getLegendItems(context);\n\t});\n</script>\n\n<template>\n\t<div class=\"fm-legend\" v-if=\"legendItems.length > 0 || legend1 || legend2\">\n\t\t<template v-if=\"!context.isNarrow\">\n\t\t\t<div\n\t\t\t\tclass=\"fm-legend-absolute card\"\n\t\t\t\t:style=\"{ '--fm-scale-factor': scale }\"\n\t\t\t\tref=\"absoluteContainerRef\"\n\t\t\t>\n\t\t\t\t<div class=\"card-body\">\n\t\t\t\t\t<LegendContent :items=\"legendItems\" :legend1=\"legend1\" :legend2=\"legend2\"></LegendContent>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<SearchBoxTab :id=\"`fm${context.id}-legend-tab`\" :title=\"i18n.t('legend.tab-label')\">\n\t\t\t\t<LegendContent :items=\"legendItems\" :legend1=\"legend1\" :legend2=\"legend2\" no-popover></LegendContent>\n\t\t\t</SearchBoxTab>\n\t\t</template>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-legend-absolute.fm-legend-absolute {\n\t\tposition: absolute;\n\t\tright: 10px;\n\t\tbottom: 25px;\n\t\tmax-width: 20rem;\n\t\tz-index: 800;\n\t\ttransform-origin: bottom right;\n\t\topacity: .7;\n\t\ttransition: opacity .7s;\n\t\ttransform: scale(var(--fm-scale-factor));\n\n\t\t&:hover {\n\t\t\topacity: 1;\n\t\t}\n\n\t\t.fm-legend-popover-wrapper {\n\t\t\ttransform: scale(calc(1 / var(--fm-scale-factor)));\n\t\t\ttransform-origin: center right;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { lineValidator, type ID } from \"facilmap-types\";\n\timport { canControl, formatFieldName, formatTypeName, getOrderedTypes, mergeObject } from \"facilmap-utils\";\n\timport { getUniqueId, getZodValidator, validateRequired } from \"../utils/utils\";\n\timport { cloneDeep, isEqual, omit } from \"lodash-es\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport ColourPicker from \"./ui/colour-picker.vue\";\n\timport FieldInput from \"./ui/field-input.vue\";\n\timport RouteMode from \"./ui/route-mode.vue\";\n\timport WidthPicker from \"./ui/width-picker.vue\";\n\timport { computed, ref, toRef, watch } from \"vue\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport DropdownMenu from \"./ui/dropdown-menu.vue\";\n\timport { injectContextRequired, requireClientContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ValidatedField from \"./ui/validated-form/validated-field.vue\";\n\timport StrokePicker from \"./ui/stroke-picker.vue\";\n\timport { useI18n } from \"../utils/i18n\";\n\timport { useMaxBreakpoint } from \"../utils/bootstrap\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tlineId: ID;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst id = getUniqueId(\"fm-edit-line-dialog\");\n\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\n\tconst originalLine = toRef(() => client.value.lines[props.lineId]);\n\n\tconst line = ref(cloneDeep(originalLine.value));\n\n\tconst isModified = computed(() => !isEqual(line.value, originalLine.value));\n\n\tconst types = computed(() => getOrderedTypes(client.value.types).filter((type) => type.type === \"line\"));\n\n\tconst resolvedCanControl = computed(() => canControl(client.value.types[line.value.typeId]));\n\n\tconst isXs = useMaxBreakpoint(\"xs\");\n\n\twatch(originalLine, (newLine, oldLine) => {\n\t\tif (!newLine) {\n\t\t\tmodalRef.value?.modal.hide();\n\t\t\t// TODO: Show message\n\t\t} else {\n\t\t\tmergeObject(oldLine, newLine, line.value);\n\t\t}\n\t});\n\n\tasync function save(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-edit-line-error`);\n\n\t\ttry {\n\t\t\tawait client.value.editLine(omit(line.value, \"trackPoints\"));\n\t\t\tmodalRef.value?.modal.hide();\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-edit-line-error`, () => i18n.t(\"edit-line-dialog.save-error\"), err);\n\t\t}\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('edit-line-dialog.title')\"\n\t\tclass=\"fm-edit-line\"\n\t\t:isModified=\"isModified\"\n\t\t@submit=\"$event.waitUntil(save())\"\n\t\t@hidden=\"emit('hidden')\"\n\t\tref=\"modalRef\"\n\t>\n\t\t<template #default>\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-name-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-line-dialog.name\")}}</label>\n\t\t\t\t<ValidatedField\n\t\t\t\t\t:value=\"line.name\"\n\t\t\t\t\t:validators=\"[getZodValidator(lineValidator.update.shape.name)]\"\n\t\t\t\t\tclass=\"col-sm-9 position-relative\"\n\t\t\t\t>\n\t\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t\t<input class=\"form-control\" :id=\"`${id}-name-input`\" v-model=\"line.name\" :ref=\"slotProps.inputRef\" />\n\t\t\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</ValidatedField>\n\t\t\t</div>\n\n\t\t\t<div v-if=\"resolvedCanControl.includes('mode') && line.mode !== 'track' && context.settings.routing\" class=\"row mb-3\">\n\t\t\t\t<label class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-line-dialog.routing-mode\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<RouteMode v-model=\"line.mode\"></RouteMode>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('colour')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-colour-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-line-dialog.colour\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<ColourPicker\n\t\t\t\t\t\t\t:id=\"`${id}-colour-input`\"\n\t\t\t\t\t\t\tv-model=\"line.colour\"\n\t\t\t\t\t\t\t:validators=\"[validateRequired]\"\n\t\t\t\t\t\t></ColourPicker>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('width')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-width-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-line-dialog.width\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<WidthPicker\n\t\t\t\t\t\t\t:id=\"`${id}-width-input`\"\n\t\t\t\t\t\t\tv-model=\"line.width\"\n\t\t\t\t\t\t\tclass=\"fm-custom-range-with-label\"\n\t\t\t\t\t\t></WidthPicker>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('stroke')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-stroke-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-line-dialog.stroke\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<StrokePicker\n\t\t\t\t\t\t\t:id=\"`${id}-stroke-input`\"\n\t\t\t\t\t\t\tv-model=\"line.stroke\"\n\t\t\t\t\t\t></StrokePicker>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-for=\"(field, idx) in client.types[line.typeId].fields\" :key=\"field.name\">\n\t\t\t\t<template v-if=\"field.type !== 'checkbox' || !isXs\">\n\t\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t\t<label :for=\"`${id}-${idx}-input`\" class=\"col-sm-3 col-form-label text-break\">{{formatFieldName(field.name)}}</label>\n\t\t\t\t\t\t<div class=\"col-sm-9\" :class=\"{ 'fm-form-check-with-label': field.type === 'checkbox' }\">\n\t\t\t\t\t\t\t<FieldInput\n\t\t\t\t\t\t\t\t:id=\"`${id}-${idx}-input`\"\n\t\t\t\t\t\t\t\t:field=\"field\"\n\t\t\t\t\t\t\t\tv-model=\"line.data[field.name]\"\n\t\t\t\t\t\t\t></FieldInput>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t\t<template v-else>\n\t\t\t\t\t<FieldInput\n\t\t\t\t\t\t:id=\"`${id}-${idx}-input`\"\n\t\t\t\t\t\t:field=\"field\"\n\t\t\t\t\t\tv-model=\"line.data[field.name]\"\n\t\t\t\t\t\tshowCheckboxLabel\n\t\t\t\t\t></FieldInput>\n\t\t\t\t</template>\n\t\t\t</template>\n\t\t</template>\n\n\t\t<template #footer-left>\n\t\t\t<DropdownMenu v-if=\"types.length > 1\" class=\"dropup\" :label=\"i18n.t('edit-line-dialog.change-type')\">\n\t\t\t\t<template v-for=\"type in types\" :key=\"type.id\">\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t:class=\"{ active: type.id == line.typeId }\"\n\t\t\t\t\t\t\t@click=\"line.typeId = type.id\"\n\t\t\t\t\t\t>{{formatTypeName(type.name)}}</a>\n\t\t\t\t\t</li>\n\t\t\t\t</template>\n\t\t\t</DropdownMenu>\n\t\t</template>\n\t</ModalDialog>\n</template>","<script setup lang=\"ts\">\n\timport { sortBy } from \"lodash-es\";\n\timport type { LineWithTrackPoints, RouteWithTrackPoints } from \"facilmap-client\";\n\timport { createElevationStats } from \"../../utils/heightgraph\";\n\timport Icon from \"./icon.vue\";\n\timport { formatAscentDescent, formatDistance, numberKeys } from \"facilmap-utils\";\n\timport { computed, ref } from \"vue\";\n\timport Popover from \"./popover.vue\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\troute: LineWithTrackPoints | RouteWithTrackPoints;\n\t}>();\n\n\tconst statsButtonContainerRef = ref<HTMLElement>();\n\tconst showStatsPopover = ref(false);\n\n\tconst statsArr = computed(() => {\n\t\tconst stats = createElevationStats(props.route.extraInfo ?? {}, props.route.trackPoints)\n\t\treturn stats && sortBy([...numberKeys(stats)].map((i) => ({ i, distance: stats[i] })), 'i');\n\t});\n</script>\n\n<template>\n\t<span class=\"fm-elevation-stats\" v-if=\"route.ascent != null && route.descent != null\">\n\t\t<span>\n\t\t\t<Icon icon=\"triangle-top\" :alt=\"i18n.t('elevation-stats.ascent-alt')\"></Icon> {{formatAscentDescent(route.ascent)}} / <Icon icon=\"triangle-bottom\" :alt=\"i18n.t('elevation-status.descent-alt')\"></Icon> {{formatAscentDescent(route.descent)}}\n\t\t</span>\n\n\t\t<span ref=\"statsButtonContainerRef\">\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\tv-tooltip=\"i18n.t('elevation-stats.show-tooltip')\"\n\t\t\t\t@click=\"showStatsPopover = !showStatsPopover\"\n\t\t\t>\n\t\t\t\t<Icon icon=\"circle-info\" :alt=\"i18n.t('elevation-stats.show-alt')\"></Icon>\n\t\t\t</button>\n\t\t</span>\n\n\t\t<Popover\n\t\t\t:element=\"statsButtonContainerRef\"\n\t\t\tv-model:show=\"showStatsPopover\"\n\t\t\thideOnOutsideClick\n\t\t\tclass=\"fm-elevation-stats-popover\"\n\t\t>\n\t\t\t<dl class=\"row\">\n\t\t\t\t<dt class=\"col-6\">{{i18n.t(\"elevation-stats.total-ascent\")}}</dt>\n\t\t\t\t<dd class=\"col-6\">{{formatAscentDescent(route.ascent)}}</dd>\n\n\t\t\t\t<dt class=\"col-6\">{{i18n.t(\"elevation-stats.total-descent\")}}</dt>\n\t\t\t\t<dd class=\"col-6\">{{formatAscentDescent(route.descent)}}</dd>\n\n\t\t\t\t<template v-for=\"stat in statsArr\" :key=\"stat.i\">\n\t\t\t\t\t<dt class=\"col-6\">{{stat.i == 0 ? '0%' : stat.i < 0 ? \"≤ \"+stat.i+\"%\" : \"≥ \"+stat.i+\"%\"}}</dt>\n\t\t\t\t\t<dd class=\"col-6\">{{formatDistance(stat.distance)}}</dd>\n\t\t\t\t</template>\n\t\t\t</dl>\n\t\t</Popover>\n\t</span>\n</template>\n\n<style lang=\"scss\">\n\t.fm-elevation-stats {\n\t\t&, & > span {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t}\n\n\t\tbutton {\n\t\t\tmargin-left: 0.5rem;\n\t\t\tpadding: 0 0.25rem;\n\t\t\tline-height: 1;\n\t\t}\n\t}\n\n\t.fm-elevation-stats-popover {\n\t\tmax-width: none;\n\n\t\tdl {\n\t\t\tmargin: 0;\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: auto 1fr;\n\t\t\twhite-space: nowrap;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport FmHeightgraph from \"../../utils/heightgraph\";\n\timport type { LineWithTrackPoints, RouteWithTrackPoints } from \"facilmap-client\";\n\timport { computed, markRaw, ref, toRef, watch } from \"vue\";\n\timport { useDomEventListener, useEventListener } from \"../../utils/utils\";\n\timport { injectContextRequired, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { fixOnCleanup } from \"../../utils/vue\";\n\n\tconst props = defineProps<{\n\t\troute: RouteWithTrackPoints | LineWithTrackPoints;\n\t}>();\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst searchBoxContext = toRef(() => context.components.searchBox);\n\n\tuseEventListener(searchBoxContext, \"resizeend\", handleResize);\n\tuseEventListener(searchBoxContext, \"resizereset\", handleResize);\n\n\tuseDomEventListener(window, \"resize\", handleResize);\n\n\tconst containerRef = ref<HTMLElement>();\n\n\tconst elevationPlot = computed(() => {\n\t\tif (containerRef.value) {\n\t\t\t// Construct in computed value so that it is reconstructed on language change\n\t\t\treturn markRaw(new FmHeightgraph({ mapMarkerPane: \"lhl-raised\" }));\n\t\t}\n\t});\n\n\twatch(elevationPlot, (value, oldValue, onCleanup_) => {\n\t\tconst onCleanup = fixOnCleanup(onCleanup_);\n\n\t\tif (elevationPlot.value) {\n\t\t\televationPlot.value._map = mapContext.value.components.map;\n\t\t\thandleTrackPointsChange();\n\t\t\tcontainerRef.value!.append(elevationPlot.value.onAdd(mapContext.value.components.map));\n\t\t\thandleResize();\n\n\t\t\tonCleanup(() => {\n\t\t\t\tvalue!.onRemove(mapContext.value.components.map);\n\t\t\t\tcontainerRef.value!.replaceChildren();\n\t\t\t});\n\t\t}\n\t});\n\n\tfunction handleTrackPointsChange() {\n\t\tif (elevationPlot.value && props.route.trackPoints) {\n\t\t\televationPlot.value.addData(props.route.extraInfo ?? {}, props.route.trackPoints);\n\t\t}\n\t}\n\n\twatch(() => props.route.trackPoints, handleTrackPointsChange);\n\n\tfunction handleResize(): void {\n\t\tif (elevationPlot.value && containerRef.value) {\n\t\t\televationPlot.value.resize({ width: containerRef.value.offsetWidth, height: containerRef.value.offsetHeight });\n\t\t}\n\t}\n</script>\n\n<template>\n\t<div class=\"fm-elevation-plot\" ref=\"containerRef\"></div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-elevation-plot {\n\t\tflex-grow: 1;\n\t\tflex-basis: 12rem;\n\t\toverflow: hidden;\n\t\tmin-height: 6.5rem;\n\n\t\t.heightgraph-toggle, .heightgraph-close-icon {\n\t\t\tdisplay: none !important;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { computed } from \"vue\";\n\timport type { ButtonSize } from \"../../utils/bootstrap\";\n\timport { flyTo, type ZoomDestination } from \"../../utils/zoom\";\n\timport { injectContextRequired, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport Icon from \"./icon.vue\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tdestination: ZoomDestination;\n\t\tsize?: ButtonSize;\n\t\tlabel?: string;\n\t}>(), {\n\t\tlabel: \"object\"\n\t});\n\n\tconst tooltip = computed(() => props.label ?? i18n.t(\"zoom-to-object-button.fallback-label\"));\n\n\tfunction zoom(): void {\n\t\tflyTo(mapContext.value.components.map, props.destination);\n\t}\n</script>\n\n<template>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"btn btn-secondary btn-sm\"\n\t\tv-tooltip=\"tooltip\"\n\t\t@click=\"zoom()\"\n\t>\n\t\t<Icon icon=\"zoom-in\" :alt=\"tooltip\"></Icon>\n\t</button>\n</template>","<script setup lang=\"ts\">\n\timport type { Type } from 'facilmap-types';\n\timport { computed, ref, toRef, watch } from 'vue';\n\timport { injectContextRequired, requireClientContext } from '../facil-map-context-provider/facil-map-context-provider.vue';\n\timport { useToasts } from './toasts/toasts.vue';\n\timport type { SelectedItem } from '../../utils/selection';\n\timport { type LineWithTags, type MarkerWithTags, addToMap } from '../../utils/add';\n\timport type { ButtonSize } from '../../utils/bootstrap';\n\timport DropdownMenu from \"./dropdown-menu.vue\";\n\timport { formatTypeName, getOrderedTypes } from 'facilmap-utils';\n\timport { useI18n } from '../../utils/i18n';\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = toRef(() => context.components.map);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tmarkers?: MarkerWithTags[];\n\t\tlines?: LineWithTags[];\n\t\tlabel?: string;\n\t\tsize?: ButtonSize;\n\t\t/** If true, the markers/lines entries are assumed to refer to a single object, omitting the prefix \"Marker/line/polgon items as\" */\n\t\tisSingle?: boolean;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:isAdding\": [isAdding: boolean];\n\t}>();\n\n\tconst isAdding = ref(false);\n\n\twatch(isAdding, () => {\n\t\temit(\"update:isAdding\", isAdding.value);\n\t});\n\n\tconst markerTypes = computed(() => {\n\t\treturn getOrderedTypes(client.value.types).filter((type) => type.type == \"marker\");\n\t});\n\n\tconst lineTypes = computed(() => {\n\t\treturn getOrderedTypes(client.value.types).filter((type) => type.type == \"line\");\n\t});\n\n\tasync function add(callback: () => Promise<SelectedItem[]>): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-add-to-map-error`);\n\t\tisAdding.value = true;\n\n\t\ttry {\n\t\t\tconst selection = await callback();\n\n\t\t\tmapContext.value?.components.selectionHandler.setSelectedItems(selection, true);\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-add-to-map-error`, () => i18n.t(\"add-to-map-dropdown.add-error\"), err);\n\t\t} finally {\n\t\t\tisAdding.value = false;\n\t\t}\n\t}\n\n\tasync function addMarkers(type: Type): Promise<void> {\n\t\tawait add(async () => {\n\t\t\treturn await addToMap(context, (props.markers ?? []).map((marker) => ({ marker, type })));\n\t\t});\n\t}\n\n\tasync function addLines(type: Type): Promise<void> {\n\t\tawait add(async () => {\n\t\t\treturn await addToMap(context, (props.lines ?? []).map((line) => ({ line, type })));\n\t\t});\n\t}\n</script>\n\n<template>\n\t<DropdownMenu\n\t\tv-if=\"client.padData && !client.readonly && ((props.markers && markerTypes.length > 0) || (props.lines && lineTypes.length > 0))\"\n\t\t:label=\"props.label ?? i18n.t('add-to-map-dropdown.fallback-label')\"\n\t\t:isDisabled=\"(props.markers ?? []).length === 0 && (props.lines ?? []).length === 0\"\n\t\t:isBusy=\"isAdding\"\n\t\t:size=\"props.size\"\n\t>\n\t\t<template v-if=\"(props.markers ?? []).length > 0 && markerTypes.length > 0\">\n\t\t\t<template v-for=\"type in markerTypes\" :key=\"type.id\">\n\t\t\t\t<li>\n\t\t\t\t\t<a\n\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t@click=\"addMarkers(type)\"\n\t\t\t\t\t>{{!props.isSingle && props.lines ? i18n.t(\"add-to-map-dropdown.add-marker-items\", { typeName: formatTypeName(type.name) }) : formatTypeName(type.name)}}</a>\n\t\t\t\t</li>\n\t\t\t</template>\n\t\t</template>\n\t\t<template v-if=\"(props.lines ?? []).length > 0 && lineTypes.length > 0\">\n\t\t\t<template v-for=\"type in lineTypes\" :key=\"type.id\">\n\t\t\t\t<li>\n\t\t\t\t\t<a\n\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t@click=\"addLines(type)\"\n\t\t\t\t\t>{{!props.isSingle && props.markers ? i18n.t(\"add-to-map-dropdown.add-line-items\", { typeName: formatTypeName(type.name) }) : formatTypeName(type.name)}}</a>\n\t\t\t\t</li>\n\t\t\t</template>\n\t\t</template>\n\n\t\t<slot name=\"after\"></slot>\n\t</DropdownMenu>\n</template>","<script setup lang=\"ts\">\n\timport { ref } from \"vue\";\n\timport type { ButtonSize } from \"../../utils/bootstrap\";\n\timport { injectContextRequired } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport DropdownMenu from \"./dropdown-menu.vue\";\n\timport type { ExportFormat } from \"facilmap-types\";\n\timport { useToasts } from \"./toasts/toasts.vue\";\n\timport { saveAs } from \"file-saver\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport { getSafeFilename } from \"facilmap-utils\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tfilename: string;\n\t\tgetExport: (format: ExportFormat) => Promise<string>;\n\t\tisDisabled?: boolean;\n\t\tsize?: ButtonSize;\n\t}>();\n\n\tconst isExporting = ref(false);\n\n\tasync function exportRoute(format: ExportFormat): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-export-dropdown-error`);\n\t\tisExporting.value = true;\n\n\t\ttry {\n\t\t\tconst exported = await props.getExport(format);\n\t\t\tsaveAs(new Blob([exported], { type: \"application/gpx+xml\" }), `${getSafeFilename(props.filename)}.gpx`);\n\t\t} catch(err: any) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-export-dropdown-error`, () => i18n.t(\"export-dropdown.export-error\"), err);\n\t\t} finally {\n\t\t\tisExporting.value = false;\n\t\t}\n\t}\n</script>\n\n<template>\n\t<DropdownMenu\n\t\t:size=\"props.size\"\n\t\t:isDisabled=\"props.isDisabled\"\n\t\t:label=\"i18n.t('export-dropdown.button-label')\"\n\t\t:isBusy=\"isExporting\"\n\t>\n\t\t<li>\n\t\t\t<a\n\t\t\t\thref=\"javascript:\"\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t@click=\"exportRoute('gpx-trk')\"\n\t\t\t\tv-tooltip.right=\"i18n.t('export-dropdown.gpx-track-tooltip')\"\n\t\t\t>{{i18n.t(\"export-dropdown.gpx-track-label\")}}</a>\n\t\t</li>\n\t\t<li>\n\t\t\t<a\n\t\t\t\thref=\"javascript:\"\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t@click=\"exportRoute('gpx-rte')\"\n\t\t\t\tv-tooltip.right=\"i18n.t('export-dropdown.gpx-route-tooltip')\"\n\t\t\t>{{i18n.t(\"export-dropdown.gpx-route-label\")}}</a>\n\t\t</li>\n\t</DropdownMenu>\n</template>","<script setup lang=\"ts\">\n\timport { computed, markRaw, onBeforeUnmount, onMounted, ref, toRaw, watch, watchEffect } from \"vue\";\n\timport Icon from \"../ui/icon.vue\";\n\timport { decodeRouteQuery, encodeRouteQuery, formatCoordinates, formatDistance, formatRouteMode, formatRouteTime, formatTypeName, isSearchId, normalizeMarkerName } from \"facilmap-utils\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport type { ExportFormat, FindOnMapResult, SearchResult } from \"facilmap-types\";\n\timport { getMarkerIcon, type HashQuery, MarkerLayer, RouteLayer } from \"facilmap-leaflet\";\n\timport { getZoomDestinationForRoute, flyTo, normalizeZoomDestination } from \"../../utils/zoom\";\n\timport { latLng, type LatLng } from \"leaflet\";\n\timport Draggable from \"vuedraggable\";\n\timport RouteMode from \"../ui/route-mode.vue\";\n\timport DraggableLines from \"leaflet-draggable-lines\";\n\timport { cloneDeep, throttle } from \"lodash-es\";\n\timport ElevationStats from \"../ui/elevation-stats.vue\";\n\timport ElevationPlot from \"../ui/elevation-plot.vue\";\n\timport { isMapResult } from \"../../utils/search\";\n\timport type { LineWithTags } from \"../../utils/add\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\timport ZoomToObjectButton from \"../ui/zoom-to-object-button.vue\";\n\timport type { RouteDestination } from \"../facil-map-context-provider/route-form-tab-context\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport AddToMapDropdown from \"../ui/add-to-map-dropdown.vue\";\n\timport ExportDropdown from \"../ui/export-dropdown.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\ttype SearchSuggestion = SearchResult;\n\ttype MapSuggestion = FindOnMapResult & { kind: \"marker\" };\n\ttype Suggestion = SearchSuggestion | MapSuggestion;\n\n\tinterface Destination extends RouteDestination {\n\t\tquery: string;\n\t\tloadingQuery?: string;\n\t\tloadingPromise?: Promise<void>;\n\t\tloadedQuery?: string;\n\t\tsearchSuggestions?: SearchSuggestion[];\n\t\tmapSuggestions?: MapSuggestion[];\n\t\tselectedSuggestion?: Suggestion;\n\t}\n\n\tfunction makeCoordDestination(latlng: LatLng) {\n\t\tconst disp = formatCoordinates({ lat: latlng.lat, lon: latlng.lng });\n\t\tlet suggestion = {\n\t\t\tlat: latlng.lat,\n\t\t\tlon: latlng.lng,\n\t\t\tdisplay_name: disp,\n\t\t\tshort_name: disp,\n\t\t\ttype: \"coordinates\",\n\t\t\tid: disp\n\t\t};\n\t\treturn {\n\t\t\tquery: disp,\n\t\t\tloadingQuery: disp,\n\t\t\tloadedQuery: disp,\n\t\t\tselectedSuggestion: suggestion,\n\t\t\tsearchSuggestions: [ suggestion ]\n\t\t};\n\t}\n\n\tfunction makeDestination({ query, searchSuggestions, mapSuggestions, selectedSuggestion }: { query: string; searchSuggestions?: SearchResult[]; mapSuggestions?: FindOnMapResult[]; selectedSuggestion?: SearchResult | FindOnMapResult }): Destination {\n\t\treturn {\n\t\t\tquery,\n\t\t\tloadedQuery: searchSuggestions || mapSuggestions ? query : undefined,\n\t\t\tsearchSuggestions,\n\t\t\tmapSuggestions: mapSuggestions?.filter((result) => result.kind == \"marker\") as MapSuggestion[],\n\t\t\tselectedSuggestion: selectedSuggestion as MapSuggestion\n\t\t};\n\t}\n\n\tconst startMarkerColour = \"00ff00\";\n\tconst dragMarkerColour = \"ffd700\";\n\tconst endMarkerColour = \"ff0000\";\n\n\tfunction getIcon(i: number, length: number, highlight = false) {\n\t\treturn getMarkerIcon(i == 0 ? `#${startMarkerColour}` : i == length - 1 ? `#${endMarkerColour}` : `#${dragMarkerColour}`, 35, undefined, undefined, highlight);\n\t}\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst submitButton = ref<HTMLButtonElement>();\n\n\tconst props = withDefaults(defineProps<{\n\t\t/** If false, the route layer will be opaque and not draggable. */\n\t\tactive?: boolean;\n\t\trouteId?: string;\n\t\tshowToolbar?: boolean;\n\t\tnoClear?: boolean;\n\t}>(), {\n\t\tactive: true,\n\t\tshowToolbar: true\n\t});\n\n\tconst emit = defineEmits<{\n\t\tactivate: [];\n\t\t\"hash-query-change\": [hashQuery: HashQuery | undefined];\n\t}>();\n\n\tconst routeObj = computed(() => props.routeId ? client.value.routes[props.routeId] : client.value.route);\n\tconst hasRoute = computed(() => !!routeObj.value);\n\n\tconst routeMode = ref(routeObj.value?.mode ?? \"car\");\n\tconst destinations = ref<Destination[]>(routeObj.value ? (\n\t\trouteObj.value.routePoints.map((point) => makeCoordDestination(latLng(point.lat, point.lon)))\n\t) : (\n\t\t[{ query: \"\" }, { query: \"\" }]\n\t));\n\tconst submittedQuery = ref<{ destinations: Destination[]; mode: string }>();\n\tconst routeError = ref<string>();\n\tconst hoverDestinationIdx = ref<number>();\n\tconst hoverInsertIdx = ref<number>();\n\tconst suggestionMarker = ref<MarkerLayer>();\n\n\t// TODO: Handle client.value change\n\tconst routeLayer = new RouteLayer(client.value, props.routeId, { weight: 7, opacity: 1, raised: true });\n\trouteLayer.on(\"click\", (e) => {\n\t\tif (!props.active && !(e.originalEvent as any).ctrlKey) {\n\t\t\temit(\"activate\");\n\t\t}\n\t});\n\n\tconst draggable = new DraggableLines(mapContext.value.components.map, {\n\t\tenableForLayer: false,\n\t\ttempMarkerOptions: () => ({\n\t\t\ticon: getMarkerIcon(`#${dragMarkerColour}`, 35),\n\t\t\tpane: \"fm-raised-marker\"\n\t\t}),\n\t\tplusTempMarkerOptions: () => ({\n\t\t\ticon: getMarkerIcon(`#${dragMarkerColour}`, 35),\n\t\t\tpane: \"fm-raised-marker\"\n\t\t}),\n\t\tdragMarkerOptions: (layer, i, length) => ({\n\t\t\ticon: getIcon(i, length),\n\t\t\tpane: \"fm-raised-marker\"\n\t\t})\n\t});\n\tdraggable.on({\n\t\tinsert: (e: any) => {\n\t\t\tdestinations.value.splice(e.idx, 0, makeCoordDestination(e.latlng));\n\t\t\tvoid reroute(false);\n\t\t},\n\t\tdragstart: (e: any) => {\n\t\t\thoverDestinationIdx.value = e.idx;\n\t\t\thoverInsertIdx.value = undefined;\n\t\t\tif (e.isNew)\n\t\t\t\tdestinations.value.splice(e.idx, 0, makeCoordDestination(e.to));\n\t\t},\n\t\tdrag: throttle((e: any) => {\n\t\t\tdestinations.value[e.idx] = makeCoordDestination(e.to);\n\t\t}, 300),\n\t\tdragend: (e: any) => {\n\t\t\tdestinations.value[e.idx] = makeCoordDestination(e.to);\n\t\t\tvoid reroute(false);\n\t\t},\n\t\tremove: (e: any) => {\n\t\t\thoverDestinationIdx.value = undefined;\n\t\t\tdestinations.value.splice(e.idx, 1);\n\t\t\tvoid reroute(false);\n\t\t},\n\t\tdragmouseover: (e: any) => {\n\t\t\tdestinationMouseOver(e.idx);\n\t\t},\n\t\tdragmouseout: (e: any) => {\n\t\t\tdestinationMouseOut(e.idx);\n\t\t},\n\t\tplusmouseover: (e: any) => {\n\t\t\thoverInsertIdx.value = e.idx;\n\t\t},\n\t\tplusmouseout: (e: any) => {\n\t\t\thoverInsertIdx.value = undefined;\n\t\t},\n\t\ttempmouseover: (e: any) => {\n\t\t\thoverInsertIdx.value = e.idx;\n\t\t},\n\t\ttempmousemove: (e: any) => {\n\t\t\tif (e.idx != hoverInsertIdx.value)\n\t\t\t\thoverInsertIdx.value = e.idx;\n\t\t},\n\t\ttempmouseout: (e: any) => {\n\t\t\thoverInsertIdx.value = undefined;\n\t\t}\n\t} as any);\n\n\tonMounted(() => {\n\t\trouteLayer.addTo(mapContext.value.components.map);\n\t\tdraggable.enable();\n\t});\n\n\tonBeforeUnmount(() => {\n\t\tdraggable.disable();\n\t\trouteLayer.remove();\n\t});\n\n\tconst zoomDestination = computed(() => routeObj.value && getZoomDestinationForRoute(routeObj.value));\n\n\tconst hashQuery = computed(() => {\n\t\tif (submittedQuery.value) {\n\t\t\treturn {\n\t\t\t\tquery: encodeRouteQuery({\n\t\t\t\t\tqueries: submittedQuery.value.destinations.map((dest) => (getSelectedSuggestionId(dest) ?? dest.query)),\n\t\t\t\t\tmode: submittedQuery.value.mode\n\t\t\t\t}),\n\t\t\t\t...(zoomDestination.value ? normalizeZoomDestination(mapContext.value.components.map, zoomDestination.value) : {}),\n\t\t\t\tdescription: i18n.t(\"route-form.route-description-outer\", {\n\t\t\t\t\tinner: i18n.t(\"route-form.route-description-inner\", {\n\t\t\t\t\t\tdestinations: submittedQuery.value.destinations.map((dest) => (getSelectedSuggestionName(dest) ?? dest.query)).join(i18n.t(\"route-form.route-description-inner-joiner\")),\n\t\t\t\t\t\tmode: formatRouteMode(submittedQuery.value.mode)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t};\n\t\t} else\n\t\t\treturn undefined;\n\t});\n\n\tconst destinationsMeta = computed(() => destinations.value.map((destination) => ({\n\t\tisInvalid: getValidationState(destination) === false\n\t})));\n\n\twatchEffect(() => {\n\t\tif (hasRoute.value)\n\t\t\trouteLayer.setStyle({ opacity: props.active ? 1 : 0.35, raised: props.active });\n\n\t\t// Enable dragging after updating the style, since that might re-add the layer to the map\n\t\tif (props.active)\n\t\t\tdraggable.enableForLayer(routeLayer);\n\t\telse\n\t\t\tdraggable.disableForLayer(routeLayer);\n\t});\n\n\twatch(hashQuery, (hashQuery) => {\n\t\temit(\"hash-query-change\", hashQuery);\n\t});\n\n\twatch(routeMode, () => {\n\t\tvoid reroute(false);\n\t});\n\n\tfunction addDestination(): void {\n\t\tdestinations.value.push({\n\t\t\tquery: \"\"\n\t\t});\n\t}\n\n\tfunction removeDestination(idx: number): void {\n\t\tif (destinations.value.length > 2)\n\t\t\tdestinations.value.splice(idx, 1);\n\t}\n\n\tfunction getSelectedSuggestion(dest: Destination): Suggestion | undefined {\n\t\tif(dest.selectedSuggestion && [...(dest.searchSuggestions || []), ...(dest.mapSuggestions || [])].includes(dest.selectedSuggestion))\n\t\t\treturn dest.selectedSuggestion;\n\t\telse if(dest.mapSuggestions && dest.mapSuggestions.length > 0 && (dest.mapSuggestions[0].similarity == 1 || (dest.searchSuggestions || []).length == 0))\n\t\t\treturn dest.mapSuggestions[0];\n\t\telse if((dest.searchSuggestions || []).length > 0)\n\t\t\treturn dest.searchSuggestions![0];\n\t\telse\n\t\t\treturn undefined;\n\t}\n\n\tfunction getSelectedSuggestionId(dest: Destination): string | undefined {\n\t\tconst sugg = getSelectedSuggestion(dest);\n\t\tif (!sugg)\n\t\t\treturn undefined;\n\n\t\tif (isMapResult(sugg))\n\t\t\treturn (sugg.kind == \"marker\" ? \"m\" : \"l\") + sugg.id;\n\t\telse\n\t\t\treturn sugg.id;\n\t}\n\n\tfunction getSelectedSuggestionName(dest: Destination): string | undefined {\n\t\tconst sugg = getSelectedSuggestion(dest);\n\t\tif (!sugg)\n\t\t\treturn undefined;\n\n\t\tif (isMapResult(sugg))\n\t\t\treturn sugg.name;\n\t\telse\n\t\t\treturn sugg.short_name;\n\t}\n\n\tasync function loadSuggestions(dest: Destination): Promise<void> {\n\t\tif (dest.loadingQuery == dest.query.trim()) {\n\t\t\tawait dest.loadingPromise;\n\t\t\treturn;\n\t\t} else if (dest.loadedQuery == dest.query.trim())\n\t\t\treturn;\n\n\t\tconst idx = destinations.value.indexOf(dest);\n\t\ttoasts.hideToast(`fm${context.id}-route-form-suggestion-error-${idx}`);\n\t\tdest.searchSuggestions = undefined;\n\t\tdest.mapSuggestions = undefined;\n\t\tdest.selectedSuggestion = undefined;\n\t\tdest.loadingQuery = undefined;\n\t\tdest.loadingPromise = undefined;\n\t\tdest.loadedQuery = undefined;\n\n\t\tconst query = dest.query.trim();\n\n\t\tif(query != \"\") {\n\t\t\tdest.loadingQuery = query;\n\t\t\tlet resolveLoadingPromise = (): void => undefined;\n\t\t\tdest.loadingPromise = new Promise((resolve) => { resolveLoadingPromise = resolve; });\n\n\t\t\ttry {\n\t\t\t\tconst [searchResults, mapResults] = await Promise.all([\n\t\t\t\t\tclient.value.find({ query: query }),\n\t\t\t\t\t(async () => {\n\t\t\t\t\t\tif (client.value.padData) {\n\t\t\t\t\t\t\tconst m = query.match(/^m(\\d+)$/);\n\t\t\t\t\t\t\tif (m) {\n\t\t\t\t\t\t\t\tconst marker = await client.value.getMarker({ id: Number(m[1]) });\n\t\t\t\t\t\t\t\treturn marker ? [{ kind: \"marker\" as const, similarity: 1, ...marker }] : [];\n\t\t\t\t\t\t\t} else\n\t\t\t\t\t\t\t\treturn (await client.value.findOnMap({ query })).filter((res) => res.kind == \"marker\") as MapSuggestion[];\n\t\t\t\t\t\t}\n\t\t\t\t\t})()\n\t\t\t\t])\n\n\t\t\t\tif(query != dest.loadingQuery)\n\t\t\t\t\treturn; // The destination has changed in the meantime\n\n\t\t\t\tdest.loadingQuery = undefined;\n\t\t\t\tdest.loadedQuery = query;\n\t\t\t\tdest.searchSuggestions = searchResults;\n\t\t\t\tdest.mapSuggestions = mapResults;\n\n\t\t\t\tif(isSearchId(query) && searchResults.length > 0 && searchResults[0].display_name) {\n\t\t\t\t\tif (dest.query == query)\n\t\t\t\t\t\tdest.query = searchResults[0].display_name;\n\t\t\t\t\tdest.loadedQuery = searchResults[0].display_name;\n\t\t\t\t\tdest.selectedSuggestion = searchResults[0];\n\t\t\t\t}\n\n\t\t\t\tif(mapResults) {\n\t\t\t\t\tconst referencedMapResult = mapResults.find((res) => query == `m${res.id}`);\n\t\t\t\t\tif(referencedMapResult) {\n\t\t\t\t\t\tif (dest.query == query)\n\t\t\t\t\t\t\tdest.query = normalizeMarkerName(referencedMapResult.name);\n\t\t\t\t\t\tdest.loadedQuery = referencedMapResult.name;\n\t\t\t\t\t\tdest.selectedSuggestion = referencedMapResult;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(dest.selectedSuggestion == null)\n\t\t\t\t\tdest.selectedSuggestion = getSelectedSuggestion(dest);\n\t\t\t} catch (err: any) {\n\t\t\t\tif(query != dest.loadingQuery)\n\t\t\t\t\treturn; // The destination has changed in the meantime\n\n\t\t\t\tconsole.warn(err.stack || err);\n\t\t\t\ttoasts.showErrorToast(`fm${context.id}-route-form-suggestion-error-${idx}`, () => i18n.t(\"route-form.find-destination-error\", { query }), err);\n\t\t\t} finally {\n\t\t\t\tresolveLoadingPromise();\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction suggestionMouseOver(suggestion: Suggestion): void {\n\t\tsuggestionMarker.value = markRaw((new MarkerLayer([ suggestion.lat!, suggestion.lon! ], {\n\t\t\thighlight: true,\n\t\t\tmarker: {\n\t\t\t\tcolour: dragMarkerColour,\n\t\t\t\tsize: 35,\n\t\t\t\tsymbol: \"\",\n\t\t\t\tshape: \"drop\"\n\t\t\t}\n\t\t})).addTo(mapContext.value.components.map));\n\t}\n\n\tfunction suggestionMouseOut(): void {\n\t\tif(suggestionMarker.value) {\n\t\t\tsuggestionMarker.value.remove();\n\t\t\tsuggestionMarker.value = undefined;\n\t\t}\n\t}\n\n\tfunction suggestionZoom(suggestion: Suggestion): void {\n\t\tmapContext.value.components.map.flyTo([suggestion.lat!, suggestion.lon!]);\n\t}\n\n\tfunction destinationMouseOver(idx: number): void {\n\t\tconst marker = routeLayer._draggableLines?.dragMarkers[idx];\n\n\t\tif (marker) {\n\t\t\thoverDestinationIdx.value = idx;\n\t\t\tmarker.setIcon(getIcon(idx, routeLayer._draggableLines!.dragMarkers.length, true));\n\t\t}\n\t}\n\n\tfunction destinationMouseOut(idx: number): void {\n\t\thoverDestinationIdx.value = undefined;\n\n\t\tconst marker = routeLayer._draggableLines?.dragMarkers[idx];\n\t\tif (marker) {\n\t\t\tvoid Promise.resolve().then(() => {\n\t\t\t\t// If mouseout event is directly followed by a dragend event, the marker will be removed. Only update the icon if the marker is not removed.\n\t\t\t\tif (marker[\"_map\"])\n\t\t\t\t\tmarker.setIcon(getIcon(idx, routeLayer._draggableLines!.dragMarkers.length));\n\t\t\t});\n\t\t}\n\t}\n\n\tfunction getValidationState(destination: Destination): boolean | null {\n\t\tif (routeError.value && destination.query.trim() == '')\n\t\t\treturn false;\n\t\telse if (destination.loadedQuery && destination.query == destination.loadedQuery && getSelectedSuggestion(destination) == null)\n\t\t\treturn false;\n\t\telse\n\t\t\treturn null;\n\t}\n\n\tasync function route(zoom: boolean, smooth = true): Promise<void> {\n\t\treset();\n\n\t\ttry {\n\t\t\tconst mode = routeMode.value;\n\n\t\t\tsubmittedQuery.value = { destinations: cloneDeep(toRaw(destinations.value)), mode };\n\n\t\t\tawait Promise.all(destinations.value.map((dest) => loadSuggestions(dest)));\n\t\t\tconst points = destinations.value.map((dest) => getSelectedSuggestion(dest));\n\n\t\t\tsubmittedQuery.value = { destinations: cloneDeep(toRaw(destinations.value)), mode };\n\n\t\t\tif(points.some((point) => point == null)) {\n\t\t\t\trouteError.value = i18n.t(\"route-form.some-destinations-not-found\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst route = await client.value.setRoute({\n\t\t\t\troutePoints: points.map((point) => ({ lat: point!.lat!, lon: point!.lon! })),\n\t\t\t\tmode,\n\t\t\t\trouteId: props.routeId\n\t\t\t});\n\n\t\t\tif (route && zoom)\n\t\t\t\tflyTo(mapContext.value.components.map, getZoomDestinationForRoute(route), smooth);\n\t\t} catch (err: any) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-route-form-error`, () => i18n.t(\"route-form.route-calculation-error\"), err);\n\t\t}\n\t}\n\n\tasync function reroute(zoom: boolean, smooth = true): Promise<void> {\n\t\tif(hasRoute.value) {\n\t\t\tawait Promise.all(destinations.value.map((dest) => loadSuggestions(dest)));\n\t\t\tconst points = destinations.value.map((dest) => getSelectedSuggestion(dest));\n\n\t\t\tif(!points.some((point) => point == null))\n\t\t\t\tawait route(zoom, smooth);\n\t\t}\n\t}\n\n\tfunction reset(): void {\n\t\ttoasts.hideToast(`fm${context.id}-route-form-error`);\n\t\tsubmittedQuery.value = undefined;\n\t\trouteError.value = undefined;\n\n\t\tif(suggestionMarker.value) {\n\t\t\tsuggestionMarker.value.remove();\n\t\t\tsuggestionMarker.value = undefined;\n\t\t}\n\n\t\tclient.value.clearRoute({ routeId: props.routeId });\n\t}\n\n\tfunction clear(): void {\n\t\treset();\n\n\t\tdestinations.value = [\n\t\t\t{ query: \"\" },\n\t\t\t{ query: \"\" }\n\t\t];\n\t}\n\n\tfunction handleSubmit(event: Event): void {\n\t\tsubmitButton.value?.focus();\n\t\tvoid route(true);\n\t}\n\n\tconst linesWithTags = computed((): LineWithTags[] | undefined => routeObj.value && [{\n\t\troutePoints: routeObj.value.routePoints,\n\t\tmode: routeObj.value.mode\n\t}]);\n\n\tasync function getExport(format: ExportFormat): Promise<string> {\n\t\treturn await client.value.exportRoute({ format });\n\t}\n\n\tfunction setQuery(query: string, zoom = true, smooth = true): void {\n\t\tclear();\n\t\tconst split = decodeRouteQuery(query);\n\t\tdestinations.value = split.queries.map((query) => ({ query }));\n\t\twhile (destinations.value.length < 2)\n\t\t\tdestinations.value.push({ query: \"\" });\n\t\trouteMode.value = split.mode ?? \"car\";\n\t\tvoid route(zoom, smooth);\n\t}\n\n\tfunction setFrom(data: Parameters<typeof makeDestination>[0]): void {\n\t\tdestinations.value[0] = makeDestination(data);\n\t\tvoid reroute(true);\n\t}\n\n\tfunction addVia(data: Parameters<typeof makeDestination>[0]): void {\n\t\tdestinations.value.splice(destinations.value.length - 1, 0, makeDestination(data));\n\t\tvoid reroute(true);\n\t}\n\n\tfunction setTo(data: Parameters<typeof makeDestination>[0]): void {\n\t\tdestinations.value[destinations.value.length - 1] = makeDestination(data);\n\t\tvoid reroute(true);\n\t}\n\n\tdefineExpose({ setQuery, setFrom, addVia, setTo });\n</script>\n\n<template>\n\t<div class=\"fm-route-form\">\n\t\t<form action=\"javascript:\" @submit.prevent=\"handleSubmit\">\n\t\t\t<Draggable\n\t\t\t\tv-model=\"destinations\"\n\t\t\t\thandle=\".fm-drag-handle\"\n\t\t\t\t@end=\"reroute(true)\"\n\t\t\t\t:itemKey=\"(destination: any) => destinations.indexOf(destination)\"\n\t\t\t>\n\t\t\t\t<template #item=\"{ element: destination, index: idx }\">\n\t\t\t\t\t<div class=\"destination\" :class=\"{ active: hoverDestinationIdx == idx }\">\n\t\t\t\t\t\t<hr class=\"fm-route-form-hover-insert\" :class=\"{ active: hoverInsertIdx === idx }\"/>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"input-group\"\n\t\t\t\t\t\t\t@mouseenter=\"destinationMouseOver(idx)\"\n\t\t\t\t\t\t\t@mouseleave=\"destinationMouseOut(idx)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span class=\"input-group-text px-2\">\n\t\t\t\t\t\t\t\t<a href=\"javascript:\" class=\"fm-drag-handle\" @contextmenu.prevent>\n\t\t\t\t\t\t\t\t\t<Icon icon=\"resize-vertical\" :alt=\"i18n.t('route-form.reorder-alt')\"></Icon>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\t\t\tv-model=\"destination.query\"\n\t\t\t\t\t\t\t\t:placeholder=\"idx == 0 ? i18n.t('route-form.from-placeholder') : idx == destinations.length-1 ? i18n.t('route-form.to-placeholder') : i18n.t('route-form.via-placeholder')\"\n\t\t\t\t\t\t\t\t:tabindex=\"idx+1\"\n\t\t\t\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t\t\t\t'is-invalid': destinationsMeta[idx].isInvalid,\n\t\t\t\t\t\t\t\t\t'fm-autofocus': idx === 0\n\t\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t\t\t@blur=\"loadSuggestions(destination)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<template v-if=\"destination.query.trim() != ''\">\n\t\t\t\t\t\t\t\t<DropdownMenu\n\t\t\t\t\t\t\t\t\tmenuClass=\"fm-route-form-suggestions\"\n\t\t\t\t\t\t\t\t\tnoWrapper\n\t\t\t\t\t\t\t\t\t@update:isOpen=\"$event && loadSuggestions(destination)\"\n\t\t\t\t\t\t\t\t\t:isLoading=\"!destination.searchSuggestions && !destination.mapSuggestions\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<template v-for=\"suggestion in destination.mapSuggestions\" :key=\"suggestion.id\">\n\t\t\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\t\t\t@mouseenter=\"suggestionMouseOver(suggestion)\"\n\t\t\t\t\t\t\t\t\t\t\t@mouseleave=\"suggestionMouseOut()\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"dropdown-item fm-route-form-suggestions-zoom\"\n\t\t\t\t\t\t\t\t\t\t\t\t:class=\"{ active: suggestion === getSelectedSuggestion(destination) }\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click.capture.stop.prevent=\"suggestionZoom(suggestion)\"\n\t\t\t\t\t\t\t\t\t\t\t><Icon icon=\"zoom-in\" :alt=\"i18n.t('route-form.zoom-alt')\"></Icon></a>\n\n\t\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t\t\t\t\t\t:class=\"{ active: suggestion === getSelectedSuggestion(destination) }\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click=\"destination.selectedSuggestion = suggestion; reroute(true)\"\n\t\t\t\t\t\t\t\t\t\t\t>{{suggestion.name}} ({{formatTypeName(client.types[suggestion.typeId].name)}})</a>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t</template>\n\n\t\t\t\t\t\t\t\t\t<li v-if=\"(destination.searchSuggestions || []).length > 0 && (destination.mapSuggestions || []).length > 0\">\n\t\t\t\t\t\t\t\t\t\t<hr class=\"dropdown-divider fm-route-form-suggestions-divider\">\n\t\t\t\t\t\t\t\t\t</li>\n\n\t\t\t\t\t\t\t\t\t<template v-for=\"suggestion in destination.searchSuggestions\" :key=\"suggestion.id\">\n\t\t\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\t\t\t@mouseenter=\"suggestionMouseOver(suggestion)\"\n\t\t\t\t\t\t\t\t\t\t\t@mouseleave=\"suggestionMouseOut()\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"dropdown-item fm-route-form-suggestions-zoom\"\n\t\t\t\t\t\t\t\t\t\t\t\t:class=\"{ active: suggestion === getSelectedSuggestion(destination) }\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click.capture.stop.prevent=\"suggestionZoom(suggestion)\"\n\t\t\t\t\t\t\t\t\t\t\t><Icon icon=\"zoom-in\" :alt=\"i18n.t('route-form.zoom-alt')\"></Icon></a>\n\t\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t\t\t\t\t\t:class=\"{ active: suggestion === getSelectedSuggestion(destination) }\"\n\t\t\t\t\t\t\t\t\t\t\t\t@click=\"destination.selectedSuggestion = suggestion; reroute(true)\"\n\t\t\t\t\t\t\t\t\t\t\t>{{suggestion.display_name}}<span v-if=\"suggestion.type\"> ({{suggestion.type}})</span></a>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tv-if=\"destinations.length > 2\"\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t\t\t\t@click=\"removeDestination(idx); reroute(false)\"\n\t\t\t\t\t\t\t\tv-tooltip.right=\"i18n.t('route-form.remove-destination-tooltip')\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon icon=\"minus\" :alt=\"i18n.t('route-form.remove-destination-alt')\" size=\"1.0em\"></Icon>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t\t<template #footer>\n\t\t\t\t\t<hr class=\"fm-route-form-hover-insert\" :class=\"{ active: hoverInsertIdx === destinations.length }\"/>\n\t\t\t\t</template>\n\t\t\t</draggable>\n\n\t\t\t<div class=\"btn-toolbar\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t@click=\"addDestination()\"\n\t\t\t\t\tv-tooltip.bottom=\"i18n.t('route-form.add-destination-tooltip')\"\n\t\t\t\t\t:tabindex=\"destinations.length+1\"\n\t\t\t\t>\n\t\t\t\t\t<Icon icon=\"plus\" :alt=\"i18n.t('route-form.add-destination-alt')\"></Icon>\n\t\t\t\t</button>\n\n\t\t\t\t<RouteMode v-if=\"context.settings.routing\" v-model=\"routeMode\" :tabindex=\"destinations.length+2\" tooltip-placement=\"bottom\"></RouteMode>\n\n\t\t\t\t<button\n\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\tclass=\"btn btn-primary flex-grow-1\"\n\t\t\t\t\t:tabindex=\"destinations.length+7\"\n\t\t\t\t\tref=\"submitButton\"\n\t\t\t\t>{{i18n.t(\"route-form.submit\")}}</button>\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"hasRoute && !props.noClear\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t:tabindex=\"destinations.length+8\"\n\t\t\t\t\t@click=\"reset()\"\n\t\t\t\t\tv-tooltip.right=\"i18n.t('route-form.clear-route-tooltip')\"\n\t\t\t\t>\n\t\t\t\t\t<Icon icon=\"remove\" :alt=\"i18n.t('route-form.clear-route-alt')\"></Icon>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<template v-if=\"routeError\">\n\t\t\t\t<hr />\n\n\t\t\t\t<div class=\"alert alert-danger\">{{routeError}}</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"routeObj\">\n\t\t\t\t<hr />\n\n\t\t\t\t<dl class=\"fm-search-box-dl\">\n\t\t\t\t\t<dt>{{i18n.t(\"route-form.distance\")}}</dt>\n\t\t\t\t\t<dd>{{formatDistance(routeObj.distance)}} <span v-if=\"routeObj.time != null\">({{formatRouteTime(routeObj.time, routeObj.mode)}})</span></dd>\n\n\t\t\t\t\t<template v-if=\"routeObj.ascent != null\">\n\t\t\t\t\t\t<dt>{{i18n.t(\"route-form.ascent-descent\")}}</dt>\n\t\t\t\t\t\t<dd><ElevationStats :route=\"routeObj\"></ElevationStats></dd>\n\t\t\t\t\t</template>\n\t\t\t\t</dl>\n\n\t\t\t\t<ElevationPlot :route=\"routeObj\" v-if=\"routeObj.ascent != null\"></ElevationPlot>\n\n\t\t\t\t<div v-if=\"showToolbar && !client.readonly\" class=\"btn-toolbar\" role=\"group\">\n\t\t\t\t\t<ZoomToObjectButton\n\t\t\t\t\t\tv-if=\"zoomDestination\"\n\t\t\t\t\t\t:label=\"i18n.t('route-form.zoom-to-object-label')\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t:destination=\"zoomDestination\"\n\t\t\t\t\t></ZoomToObjectButton>\n\n\t\t\t\t\t<AddToMapDropdown\n\t\t\t\t\t\t:lines=\"linesWithTags\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tisSingle\n\t\t\t\t\t></AddToMapDropdown>\n\n\t\t\t\t\t<ExportDropdown\n\t\t\t\t\t\t:filename=\"i18n.t('route-form.export-filename')\"\n\t\t\t\t\t\t:getExport=\"getExport\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t></ExportDropdown>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t</form>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-route-form {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\t\tflex-grow: 1;\n\n\t\tform {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tflex-grow: 1;\n\t\t}\n\n\t\t.destination.active .input-group {\n\t\t\tbox-shadow: 0 0 3px;\n\t\t\tborder-radius: 0.25rem;\n\t\t}\n\n\t\t.destination:first-child {\n\t\t\tmargin-top: calc(-0.5rem + 2px); // Offset space of first fm-route-form-hover-insert\n\t\t}\n\n\t\t&#{&} hr.fm-route-form-hover-insert {\n\t\t\tmargin: 0.1rem -0.5rem;\n\t\t\twidth: auto;\n\t\t\tborder-width: 2px;\n\t\t\tborder-color: inherit;\n\t\t\tborder-top-style: dashed;\n\n\t\t\t&:not(.active) {\n\t\t\t\tborder-color: transparent;\n\t\t\t}\n\t\t}\n\n\t\t.fm-elevation-plot {\n\t\t\tmargin-bottom: 0.5rem;\n\t\t}\n\t}\n\n\t.dropdown-menu.fm-route-form-suggestions.show {\n\t\topacity: 0.6;\n\n\t\t> li {\n\t\t\tdisplay: flex;\n\n\t\t\t> :nth-child(2) {\n\t\t\t\tflex-grow: 1;\n\t\t\t}\n\t\t}\n\n\t\t.dropdown-item {\n\t\t\twidth: auto;\n\t\t\tpadding: 0.25rem 0.75rem 0.25rem 0.25rem;\n\n\t\t\t&.fm-route-form-suggestions-zoom {\n\t\t\t\tpadding: 0.25rem 0.25rem 0.25rem 0.75rem;\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport type { ExportFormat, ID } from \"facilmap-types\";\n\timport EditLineDialog from \"../edit-line-dialog.vue\";\n\timport ElevationStats from \"../ui/elevation-stats.vue\";\n\timport ElevationPlot from \"../ui/elevation-plot.vue\";\n\timport Icon from \"../ui/icon.vue\";\n\timport { getZoomDestinationForLine } from \"../../utils/zoom\";\n\timport RouteForm from \"../route-form/route-form.vue\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport { formatDistance, formatFieldName, formatFieldValue, formatRouteTime, formatTypeName, normalizeLineName } from \"facilmap-utils\";\n\timport { computed, reactive, ref, toRef } from \"vue\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport { showConfirm } from \"../ui/alert.vue\";\n\timport ZoomToObjectButton from \"../ui/zoom-to-object-button.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ExportDropdown from \"../ui/export-dropdown.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tlineId: ID;\n\t\tshowBackButton?: boolean;\n\t}>(), {\n\t\tshowBackButton: false\n\t});\n\n\tconst emit = defineEmits<{\n\t\tback: [];\n\t}>();\n\n\tconst routeForm = ref<InstanceType<typeof RouteForm>>();\n\n\tconst showEditDialog = ref(false);\n\tconst isDeleting = ref(false);\n\tconst showElevationPlot = ref(false);\n\tconst isMoving = ref(false);\n\n\tconst line = computed(() => client.value.lines[props.lineId]);\n\n\tconst typeName = computed(() => formatTypeName(client.value.types[line.value.typeId].name));\n\tconst showTypeName = computed(() => Object.values(client.value.types).filter((t) => t.type === 'line').length > 1);\n\n\tasync function deleteLine(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-line-info-delete`);\n\n\t\tif (!await showConfirm({\n\t\t\ttitle: i18n.t(\"line-info.delete-line-title\"),\n\t\t\tmessage: i18n.t(\"line-info.delete-line-message\", { name: normalizeLineName(line.value.name) }),\n\t\t\tvariant: \"danger\",\n\t\t\tokLabel: i18n.t(\"line-info.delete-line-ok\")\n\t\t}))\n\t\t\treturn;\n\n\t\tisDeleting.value = true;\n\n\t\ttry {\n\t\t\tawait client.value.deleteLine({ id: props.lineId });\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-line-info-delete`, () => i18n.t(\"line-info.delete-line-error\"), err);\n\t\t} finally {\n\t\t\tisDeleting.value = false;\n\t\t}\n\t}\n\n\tasync function getExport(format: ExportFormat): Promise<string> {\n\t\treturn await client.value.exportLine({ id: line.value.id, format });\n\t}\n\n\tasync function moveLine(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-line-info-move`);\n\n\t\tmapContext.value.components.map.fire('fmInteractionStart');\n\t\tconst routeId = `l${line.value.id}`;\n\n\t\ttry {\n\t\t\tawait client.value.lineToRoute({ id: line.value.id, routeId });\n\n\t\t\tmapContext.value.components.linesLayer.hideLine(line.value.id);\n\n\t\t\tconst isSaving = ref(false);\n\n\t\t\tconst done = async (save: boolean) => {\n\t\t\t\tconst route = client.value.routes[routeId];\n\t\t\t\tif (save && !route)\n\t\t\t\t\treturn;\n\n\t\t\t\ttry {\n\t\t\t\t\tif(save) {\n\t\t\t\t\t\tisSaving.value = true;\n\t\t\t\t\t\tawait client.value.editLine({ id: line.value.id, routePoints: route.routePoints, mode: route.mode });\n\t\t\t\t\t}\n\n\t\t\t\t\ttoasts.hideToast(`fm${context.id}-line-info-move`);\n\t\t\t\t} catch (err) {\n\t\t\t\t\ttoasts.showErrorToast(`fm${context.id}-line-info-move`, () => i18n.t(\"line-info.save-line-error\"), err);\n\t\t\t\t} finally {\n\t\t\t\t\tmapContext.value.components.map.fire('fmInteractionEnd');\n\t\t\t\t\tisMoving.value = false;\n\n\t\t\t\t\t// Clear route after editing line so that the server can take the trackPoints from the route\n\t\t\t\t\tclient.value.clearRoute({ routeId }).catch((err) => {\n\t\t\t\t\t\tconsole.error(\"Error clearing route\", err);\n\t\t\t\t\t});\n\n\t\t\t\t\tmapContext.value.components.linesLayer.unhideLine(line.value.id);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttoasts.showToast(`fm${context.id}-line-info-move`, () => i18n.t(\"line-info.move-line-title\"), () => i18n.t(\"line-info.move-line-message\"), reactive({\n\t\t\t\tnoCloseButton: true,\n\t\t\t\tactions: toRef(() => [\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: i18n.t(\"line-info.move-line-finish\"),\n\t\t\t\t\t\tvariant: \"primary\" as const,\n\t\t\t\t\t\tonClick: () => { void done(true); },\n\t\t\t\t\t\tisPending: isSaving.value,\n\t\t\t\t\t\tisDisabled: isSaving.value\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: i18n.t(\"line-info.move-line-cancel\"),\n\t\t\t\t\t\tonClick: () => { void done(false); },\n\t\t\t\t\t\tisDisabled: isSaving.value\n\t\t\t\t\t}\n\t\t\t\t])\n\t\t\t}));\n\n\t\t\tisMoving.value = true;\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-line-info-move-error`, () => i18n.t(\"line-info.save-line-error\"), err);\n\n\t\t\ttoasts.hideToast(`fm${context.id}-line-info-move`);\n\t\t\tmapContext.value.components.map.fire('fmInteractionEnd');\n\t\t\tisMoving.value = false;\n\t\t\tclient.value.clearRoute({ routeId }).catch((err) => {\n\t\t\t\tconsole.error(\"Error clearing route\", err);\n\t\t\t});\n\t\t\tmapContext.value.components.linesLayer.unhideLine(line.value.id);\n\t\t}\n\t}\n\n\tconst zoomDestination = computed(() => getZoomDestinationForLine(line.value));\n</script>\n\n<template>\n\t<div class=\"fm-line-info\" v-if=\"line\">\n\t\t<div class=\"d-flex align-items-center\">\n\t\t\t<h2 class=\"flex-grow-1 text-break\">\n\t\t\t\t<a v-if=\"showBackButton\" href=\"javascript:\" @click=\"emit('back')\"><Icon icon=\"arrow-left\"></Icon></a>\n\t\t\t\t<span>\n\t\t\t\t\t{{normalizeLineName(line.name)}}\n\t\t\t\t\t<template v-if=\"showTypeName\">\n\t\t\t\t\t\t<span class=\"type-name\">({{typeName}})</span>\n\t\t\t\t\t</template>\n\t\t\t\t</span>\n\t\t\t</h2>\n\t\t\t<div v-if=\"!isMoving\" class=\"btn-toolbar\">\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"line.ascent != null\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t:class=\"{ active: showElevationPlot }\"\n\t\t\t\t\t@click=\"showElevationPlot = !showElevationPlot\"\n\t\t\t\t\tv-tooltip.right=\"showElevationPlot ? i18n.t('line-info.hide-elevation-plot') : i18n.t('line-info.show-elevation-plot')\"\n\t\t\t\t>\n\t\t\t\t\t<Icon icon=\"chart-line\" :alt=\"showElevationPlot ? i18n.t('line-info.hide-elevation-plot') : i18n.t('line-info.show-elevation-plot')\"></Icon>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"fm-search-box-collapse-point\" v-if=\"!isMoving\">\n\t\t\t<dl class=\"fm-search-box-dl\">\n\t\t\t\t<dt class=\"distance\">{{i18n.t(\"line-info.distance\")}}</dt>\n\t\t\t\t<dd class=\"distance\">{{formatDistance(line.distance)}} <span v-if=\"line.time != null\">({{formatRouteTime(line.time, line.mode)}})</span></dd>\n\n\t\t\t\t<template v-if=\"line.ascent != null\">\n\t\t\t\t\t<dt class=\"elevation\">{{i18n.t(\"line-info.ascent-descent\")}}</dt>\n\t\t\t\t\t<dd class=\"elevation\"><ElevationStats :route=\"line\"></ElevationStats></dd>\n\t\t\t\t</template>\n\n\t\t\t\t<template v-if=\"line.ascent == null || !showElevationPlot\">\n\t\t\t\t\t<template v-for=\"field in client.types[line.typeId].fields\" :key=\"field.name\">\n\t\t\t\t\t\t<dt>{{formatFieldName(field.name)}}</dt>\n\t\t\t\t\t\t<dd v-html=\"formatFieldValue(field, line.data[field.name], true)\"></dd>\n\t\t\t\t\t</template>\n\t\t\t\t</template>\n\t\t\t</dl>\n\n\t\t\t<ElevationPlot :route=\"line\" v-if=\"line.ascent != null && showElevationPlot\"></ElevationPlot>\n\t\t</div>\n\n\t\t<div v-if=\"!isMoving\" class=\"btn-toolbar\">\n\t\t\t<ZoomToObjectButton\n\t\t\t\tv-if=\"zoomDestination\"\n\t\t\t\t:label=\"i18n.t('line-info.zoom-to-object-label')\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\t:destination=\"zoomDestination\"\n\t\t\t></ZoomToObjectButton>\n\n\t\t\t<ExportDropdown\n\t\t\t\t:filename=\"normalizeLineName(line.name)\"\n\t\t\t\t:getExport=\"getExport\"\n\t\t\t\tsize=\"sm\"\n\t\t\t></ExportDropdown>\n\n\t\t\t<button\n\t\t\t\tv-if=\"!client.readonly\"\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"btn btn-secondary btn-sm\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\t@click=\"showEditDialog = true\"\n\t\t\t\t:disabled=\"isDeleting || mapContext.interaction\"\n\t\t\t>{{i18n.t(\"line-info.edit-data\")}}</button>\n\n\t\t\t<DropdownMenu\n\t\t\t\tv-if=\"!client.readonly\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\t:label=\"i18n.t('line-info.actions')\"\n\t\t\t\t:isBusy=\"isDeleting\"\n\t\t\t\t:isDisabled=\"mapContext.interaction\"\n\t\t\t>\n\t\t\t\t<li>\n\t\t\t\t\t<a\n\t\t\t\t\t\tv-if=\"line.mode != 'track'\"\n\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t@click=\"moveLine()\"\n\t\t\t\t\t>{{i18n.t(\"line-info.edit-waypoints\")}}</a>\n\t\t\t\t</li>\n\n\t\t\t\t<li>\n\t\t\t\t\t<a\n\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t@click=\"deleteLine()\"\n\t\t\t\t\t>{{i18n.t(\"line-info.delete\")}}</a>\n\t\t\t\t</li>\n\t\t\t</DropdownMenu>\n\t\t</div>\n\n\t\t<RouteForm\n\t\t\tv-if=\"isMoving\"\n\t\t\tactive\n\t\t\tref=\"routeForm\"\n\t\t\t:routeId=\"`l${line.id}`\"\n\t\t\t:showToolbar=\"false\"\n\t\t\tnoClear\n\t\t></RouteForm>\n\n\t\t<EditLineDialog\n\t\t\tv-if=\"showEditDialog\"\n\t\t\t:lineId=\"lineId\"\n\t\t\t@hidden=\"showEditDialog = false\"\n\t\t></EditLineDialog>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-line-info {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\t\tflex-grow: 1;\n\n\t\t.fm-search-box-collapse-point {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tmin-height: 1.5em;\n\t\t\tflex-grow: 1;\n\t\t}\n\n\t\t.type-name {\n\t\t\tcolor: #888;\n\t\t\tfont-size: 0.7em;\n\t\t}\n\n\t\t.fm-elevation-plot {\n\t\t\tmargin-bottom: 0.5rem;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { computed, watch } from \"vue\";\n\timport LineInfo from \"./line-info.vue\";\n\timport SearchBoxTab from \"../search-box/search-box-tab.vue\";\n\timport { useEventListener } from \"../../utils/utils\";\n\timport { injectContextRequired, requireClientContext, requireMapContext, requireSearchBoxContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { normalizeLineName } from \"facilmap-utils\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst searchBoxContext = requireSearchBoxContext(context);\n\n\tuseEventListener(mapContext, \"open-selection\", handleOpenSelection);\n\n\tconst lineId = computed(() => {\n\t\tif (mapContext.value.selection.length == 1 && mapContext.value.selection[0].type == \"line\")\n\t\t\treturn mapContext.value.selection[0].id;\n\t\telse\n\t\t\treturn undefined;\n\t});\n\n\tconst line = computed(() => {\n\t\treturn lineId.value != null ? client.value.lines[lineId.value] : undefined;\n\t});\n\n\twatch(line, () => {\n\t\tif (!line.value && lineId.value != null) {\n\t\t\tclose();\n\t\t}\n\t});\n\n\tconst title = computed(() => {\n\t\tif (line.value != null)\n\t\t\treturn normalizeLineName(line.value.name);\n\t\telse\n\t\t\treturn undefined;\n\t});\n\n\tfunction handleOpenSelection(): void {\n\t\tif (line.value)\n\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-line-info-tab`, { expand: true })\n\t}\n\n\tfunction close(): void {\n\t\tmapContext.value.components.selectionHandler.setSelectedItems([]);\n\t}\n</script>\n\n<template>\n\t<template v-if=\"lineId\">\n\t\t<SearchBoxTab\n\t\t\t:id=\"`fm${context.id}-line-info-tab`\"\n\t\t\t:title=\"title ?? ''\"\n\t\t\tisCloseable\n\t\t\t@close=\"close()\"\n\t\t>\n\t\t\t<LineInfo :lineId=\"lineId\"></LineInfo>\n\t\t</SearchBoxTab>\n\t</template>\n</template>","<script setup lang=\"ts\">\n\timport { markerValidator, type ID } from \"facilmap-types\";\n\timport { canControl, formatFieldName, formatTypeName, getOrderedTypes, mergeObject } from \"facilmap-utils\";\n\timport { getUniqueId, getZodValidator, validateRequired } from \"../utils/utils\";\n\timport { cloneDeep, isEqual } from \"lodash-es\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport ColourPicker from \"./ui/colour-picker.vue\";\n\timport SymbolPicker from \"./ui/symbol-picker.vue\";\n\timport ShapePicker from \"./ui/shape-picker.vue\";\n\timport FieldInput from \"./ui/field-input.vue\";\n\timport SizePicker from \"./ui/size-picker.vue\";\n\timport { computed, ref, toRef, watch } from \"vue\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport DropdownMenu from \"./ui/dropdown-menu.vue\";\n\timport { injectContextRequired, requireClientContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ValidatedField from \"./ui/validated-form/validated-field.vue\";\n\timport { useI18n } from \"../utils/i18n\";\n\timport { useMaxBreakpoint } from \"../utils/bootstrap\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tmarkerId: ID;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst id = getUniqueId(\"edit-marker-dialog\");\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\n\tconst originalMarker = toRef(() => client.value.markers[props.markerId]);\n\n\tconst marker = ref(cloneDeep(originalMarker.value));\n\n\tconst isModified = computed(() => !isEqual(marker.value, client.value.markers[props.markerId]));\n\n\tconst types = computed(() => getOrderedTypes(client.value.types).filter((type) => type.type === \"marker\"));\n\n\tconst resolvedCanControl = computed(() => canControl(client.value.types[marker.value.typeId]));\n\n\tconst isXs = useMaxBreakpoint(\"xs\");\n\n\twatch(originalMarker, (newMarker, oldMarker) => {\n\t\tif (!newMarker) {\n\t\t\tmodalRef.value?.modal.hide();\n\t\t\t// TODO: Show message\n\t\t} else {\n\t\t\tmergeObject(oldMarker, newMarker, marker.value);\n\t\t}\n\t});\n\n\tasync function save(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-edit-marker-error`);\n\n\t\ttry {\n\t\t\tawait client.value.editMarker(marker.value);\n\t\t\tmodalRef.value?.modal.hide();\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-edit-marker-error`, () => i18n.t(\"edit-marker-dialog.save-error\"), err);\n\t\t}\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('edit-marker-dialog.title')\"\n\t\tclass=\"fm-edit-marker\"\n\t\t:isModified=\"isModified\"\n\t\tref=\"modalRef\"\n\t\t@submit=\"$event.waitUntil(save())\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<template #default>\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-name-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-marker-dialog.name\")}}</label>\n\t\t\t\t<ValidatedField\n\t\t\t\t\t:value=\"marker.name\"\n\t\t\t\t\t:validators=\"[getZodValidator(markerValidator.update.shape.name)]\"\n\t\t\t\t\tclass=\"col-sm-9 position-relative\"\n\t\t\t\t>\n\t\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t\t<input class=\"form-control\" :id=\"`${id}-name-input`\" v-model=\"marker.name\" :ref=\"slotProps.inputRef\" />\n\t\t\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</ValidatedField>\n\t\t\t</div>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('colour')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-colour-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-marker-dialog.colour\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<ColourPicker\n\t\t\t\t\t\t\t:id=\"`${id}-colour-input`\"\n\t\t\t\t\t\t\tv-model=\"marker.colour\"\n\t\t\t\t\t\t\t:validators=\"[validateRequired]\"\n\t\t\t\t\t\t></ColourPicker>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('size')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-size-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-marker-dialog.size\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<SizePicker\n\t\t\t\t\t\t\t:id=\"`${id}-size-input`\"\n\t\t\t\t\t\t\tv-model=\"marker.size\"\n\t\t\t\t\t\t\tclass=\"fm-custom-range-with-label\"\n\t\t\t\t\t\t></SizePicker>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('symbol')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-symbol-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-marker-dialog.icon\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<SymbolPicker :id=\"`${id}-symbol-input`\" v-model=\"marker.symbol\"></SymbolPicker>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"resolvedCanControl.includes('shape')\">\n\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t<label :for=\"`${id}-shape-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"edit-marker-dialog.shape\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t\t<ShapePicker :id=\"`${id}-shape-input`\" v-model=\"marker.shape\"></ShapePicker>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-for=\"(field, idx) in client.types[marker.typeId].fields\" :key=\"field.name\">\n\t\t\t\t<template v-if=\"field.type !== 'checkbox' || !isXs\">\n\t\t\t\t\t<div class=\"row mb-3\">\n\t\t\t\t\t\t<label :for=\"`${id}-${idx}-input`\" class=\"col-sm-3 col-form-label text-break\">{{formatFieldName(field.name)}}</label>\n\t\t\t\t\t\t<div class=\"col-sm-9\" :class=\"{ 'fm-form-check-with-label': field.type === 'checkbox' }\">\n\t\t\t\t\t\t\t<FieldInput\n\t\t\t\t\t\t\t\t:id=\"`${id}-${idx}-input`\"\n\t\t\t\t\t\t\t\t:field=\"field\"\n\t\t\t\t\t\t\t\tv-model=\"marker.data[field.name]\"\n\t\t\t\t\t\t\t></FieldInput>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t\t<template v-else>\n\t\t\t\t\t<FieldInput\n\t\t\t\t\t\t:id=\"`${id}-${idx}-input`\"\n\t\t\t\t\t\t:field=\"field\"\n\t\t\t\t\t\tv-model=\"marker.data[field.name]\"\n\t\t\t\t\t\tshowCheckboxLabel\n\t\t\t\t\t></FieldInput>\n\t\t\t\t</template>\n\t\t\t</template>\n\t\t</template>\n\n\t\t<template #footer-left>\n\t\t\t<DropdownMenu v-if=\"types.length > 1\" class=\"dropup\" :label=\"i18n.t('edit-marker-dialog.change-type')\">\n\t\t\t\t<template v-for=\"type in types\" :key=\"type.id\">\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t:class=\"{ active: type.id == marker.typeId }\"\n\t\t\t\t\t\t\t@click=\"marker.typeId = type.id\"\n\t\t\t\t\t\t>{{formatTypeName(type.name)}}</a>\n\t\t\t\t\t</li>\n\t\t\t\t</template>\n\t\t\t</DropdownMenu>\n\t\t</template>\n\t</ModalDialog>\n</template>","<script setup lang=\"ts\">\n\timport type { Point } from \"facilmap-types\";\n\timport copyToClipboard from \"copy-to-clipboard\";\n\timport { formatCoordinates, formatElevation } from \"facilmap-utils\";\n\timport Icon from \"./icon.vue\";\n\timport { computed } from \"vue\";\n\timport { useToasts } from \"./toasts/toasts.vue\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tpoint: Point;\n\t\tele?: number | null;\n\t}>();\n\n\tconst formattedCoordinates = computed(() => formatCoordinates(props.point));\n\n\tfunction copy(): void {\n\t\tcopyToClipboard(formattedCoordinates.value);\n\t\ttoasts.showToast(undefined, () => i18n.t(\"coordinates.copied-title\"), () => i18n.t(\"coordinates.copied-message\"), { variant: \"success\", autoHide: true });\n\t}\n</script>\n\n<template>\n\t<span class=\"fm-coordinates\">\n\t\t<span>{{formattedCoordinates}}</span>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"btn btn-secondary\"\n\t\t\t@click=\"copy()\"\n\t\t\tv-tooltip=\"i18n.t('coordinates.copy-to-clipboard')\"\n\t\t>\n\t\t\t<Icon icon=\"copy\" :alt=\"i18n.t('coordinates.copy-to-clipboard')\"></Icon>\n\t\t</button>\n\t\t<span v-if=\"props.ele != null\" v-tooltip=\"i18n.t('coordinates.elevation')\">\n\t\t\t({{formatElevation(props.ele)}})\n\t\t</span>\n\t</span>\n</template>\n\n<style lang=\"scss\">\n\t.fm-coordinates {\n\t\tdisplay: inline-flex;\n\t\talign-items: center;\n\n\t\tbutton, button + * {\n\t\t\tmargin-left: 0.5rem;\n\t\t}\n\n\t\tbutton {\n\t\t\tpadding: 0 0.25rem;\n\t\t\tline-height: 1;\n\t\t\tfont-size: 0.85em;\n\t\t\tvertical-align: top;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { toRef } from \"vue\";\n\timport type { ButtonSize } from \"../../utils/bootstrap\";\n\timport { injectContextRequired } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport type { RouteDestination } from \"../facil-map-context-provider/route-form-tab-context\";\n\timport DropdownMenu from \"./dropdown-menu.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst searchBoxContext = toRef(() => context.components.searchBox);\n\tconst routeFormContext = toRef(() => context.components.routeFormTab);\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tdestination: RouteDestination;\n\t\tisDisabled?: boolean;\n\t\tsize?: ButtonSize;\n\t}>();\n\n\tfunction useAs(type: \"from\" | \"via\" | \"to\"): void {\n\t\tif (type === \"from\") {\n\t\t\trouteFormContext.value!.setFrom(props.destination);\n\t\t} else if (type === \"via\") {\n\t\t\trouteFormContext.value!.addVia(props.destination);\n\t\t} else if (type === \"to\") {\n\t\t\trouteFormContext.value!.setTo(props.destination);\n\t\t}\n\n\t\tsearchBoxContext.value!.activateTab(`fm${context.id}-route-form-tab`, { autofocus: true });\n\t}\n</script>\n\n<template>\n\t<DropdownMenu\n\t\tv-if=\"searchBoxContext && routeFormContext && context.settings.search\"\n\t\t:size=\"props.size\"\n\t\t:isDisabled=\"props.isDisabled\"\n\t\t:label=\"i18n.t('use-as-dropdown.label')\"\n\t>\n\t\t<li>\n\t\t\t<a\n\t\t\t\thref=\"javascript:\"\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t@click=\"useAs('from')\"\n\t\t\t>{{i18n.t(\"use-as-dropdown.from\")}}</a>\n\t\t</li>\n\n\t\t<li>\n\t\t\t<a\n\t\t\t\thref=\"javascript:\"\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t@click=\"useAs('via')\"\n\t\t\t>{{i18n.t(\"use-as-dropdown.via\")}}</a>\n\t\t</li>\n\n\t\t<li>\n\t\t\t<a\n\t\t\t\thref=\"javascript:\"\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t@click=\"useAs('to')\"\n\t\t\t>{{i18n.t(\"use-as-dropdown.to\")}}</a>\n\t\t</li>\n\t</DropdownMenu>\n</template>","<script setup lang=\"ts\">\n\timport type { FindOnMapResult, ID } from \"facilmap-types\";\n\timport { moveMarker } from \"../../utils/draw\";\n\timport EditMarkerDialog from \"../edit-marker-dialog.vue\";\n\timport { getZoomDestinationForMarker } from \"../../utils/zoom\";\n\timport Icon from \"../ui/icon.vue\";\n\timport Coordinates from \"../ui/coordinates.vue\";\n\timport { formatFieldName, formatFieldValue, formatTypeName, normalizeMarkerName } from \"facilmap-utils\";\n\timport { computed, ref } from \"vue\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport { showConfirm } from \"../ui/alert.vue\";\n\timport UseAsDropdown from \"../ui/use-as-dropdown.vue\";\n\timport ZoomToObjectButton from \"../ui/zoom-to-object-button.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport type { RouteDestination } from \"../facil-map-context-provider/route-form-tab-context\";\n\timport { useI18n } from \"../../utils/i18n\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tmarkerId: ID;\n\t\tshowBackButton?: boolean;\n\t}>(), {\n\t\tshowBackButton: false\n\t});\n\n\tconst emit = defineEmits<{\n\t\tback: [];\n\t}>();\n\n\tconst isBusy = ref(false);\n\tconst showEditDialog = ref(false);\n\n\tconst marker = computed(() => client.value.markers[props.markerId]);\n\n\tconst typeName = computed(() => formatTypeName(client.value.types[marker.value.typeId].name));\n\tconst showTypeName = computed(() => Object.values(client.value.types).filter((t) => t.type === 'marker').length > 1);\n\n\tfunction move(): void {\n\t\tmoveMarker(props.markerId, context, toasts);\n\t}\n\n\tasync function deleteMarker(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-marker-info-delete`);\n\n\t\tif (!await showConfirm({\n\t\t\ttitle: i18n.t(\"marker-info.delete-marker-title\"),\n\t\t\tmessage: i18n.t(\"marker-info.delete-marker-message\", { name: normalizeMarkerName(marker.value.name) }),\n\t\t\tvariant: \"danger\",\n\t\t\tokLabel: i18n.t(\"marker-info.delete-marker-ok\")\n\t\t}))\n\t\t\treturn;\n\n\t\tisBusy.value = true;\n\n\t\ttry {\n\t\t\tawait client.value.deleteMarker({ id: props.markerId });\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-marker-info-delete`, () => i18n.t(\"marker-info.delete-marker-error\"), err);\n\t\t} finally {\n\t\t\tisBusy.value = false;\n\t\t}\n\t}\n\n\tconst zoomDestination = computed(() => getZoomDestinationForMarker(marker.value));\n\n\tconst routeDestination = computed<RouteDestination>(() => {\n\t\tconst markerSuggestion: FindOnMapResult = { ...marker.value, kind: \"marker\", similarity: 1 };\n\t\treturn {\n\t\t\tquery: normalizeMarkerName(marker.value.name),\n\t\t\tmapSuggestions: [markerSuggestion],\n\t\t\tselectedSuggestion: markerSuggestion\n\t\t};\n\t});\n</script>\n\n<template>\n\t<div class=\"fm-marker-info\" v-if=\"marker\">\n\t\t<h2 class=\"text-break\">\n\t\t\t<a v-if=\"showBackButton\" href=\"javascript:\" @click=\"emit('back')\"><Icon icon=\"arrow-left\"></Icon></a>\n\t\t\t<span>\n\t\t\t\t{{normalizeMarkerName(marker.name)}}\n\t\t\t\t<template v-if=\"showTypeName\">\n\t\t\t\t\t<span class=\"type-name\">({{typeName}})</span>\n\t\t\t\t</template>\n\t\t\t</span>\n\t\t</h2>\n\t\t<dl class=\"fm-search-box-collapse-point fm-search-box-dl\">\n\t\t\t<dt class=\"pos\">{{i18n.t(\"marker-info.coordinates\")}}</dt>\n\t\t\t<dd class=\"pos\"><Coordinates :point=\"marker\" :ele=\"marker.ele\"></Coordinates></dd>\n\n\t\t\t<template v-for=\"field in client.types[marker.typeId].fields\" :key=\"field.name\">\n\t\t\t\t<dt>{{formatFieldName(field.name)}}</dt>\n\t\t\t\t<dd v-html=\"formatFieldValue(field, marker.data[field.name], true)\"></dd>\n\t\t\t</template>\n\t\t</dl>\n\n\t\t<div class=\"btn-toolbar\">\n\t\t\t<ZoomToObjectButton\n\t\t\t\tv-if=\"zoomDestination\"\n\t\t\t\t:label=\"i18n.t('marker-info.zoom-to-object-label')\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\t:destination=\"zoomDestination\"\n\t\t\t></ZoomToObjectButton>\n\n\t\t\t<UseAsDropdown\n\t\t\t\tsize=\"sm\"\n\t\t\t\t:destination=\"routeDestination\"\n\t\t\t></UseAsDropdown>\n\n\t\t\t<button\n\t\t\t\tv-if=\"!client.readonly\"\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"btn btn-secondary btn-sm\"\n\t\t\t\t@click=\"showEditDialog = true\"\n\t\t\t\t:disabled=\"isBusy || mapContext.interaction\"\n\t\t\t>{{i18n.t(\"marker-info.edit-data\")}}</button>\n\n\t\t\t<DropdownMenu\n\t\t\t\tv-if=\"!client.readonly\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\t:label=\"i18n.t('marker-info.actions')\"\n\t\t\t\t:isBusy=\"isBusy\"\n\t\t\t\t:isDisabled=\"mapContext.interaction\"\n\t\t\t>\n\t\t\t\t<li>\n\t\t\t\t\t<a\n\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t@click=\"move()\"\n\t\t\t\t\t>{{i18n.t(\"marker-info.move\")}}</a>\n\t\t\t\t</li>\n\n\t\t\t\t<li>\n\t\t\t\t\t<a\n\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t@click=\"deleteMarker()\"\n\t\t\t\t\t>{{i18n.t(\"marker-info.delete\")}}</a>\n\t\t\t\t</li>\n\t\t\t</DropdownMenu>\n\t\t</div>\n\n\t\t<EditMarkerDialog\n\t\t\tv-if=\"showEditDialog\"\n\t\t\t:markerId=\"markerId\"\n\t\t\t@hidden=\"showEditDialog = false\"\n\t\t></EditMarkerDialog>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-marker-info {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\n\t\t.fm-search-box-collapse-point {\n\t\t\tmin-height: 1.5em;\n\t\t}\n\n\t\t.type-name {\n\t\t\tcolor: #888;\n\t\t\tfont-size: 0.7em;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { computed, watch } from \"vue\";\n\timport MarkerInfo from \"./marker-info.vue\";\n\timport SearchBoxTab from \"../search-box/search-box-tab.vue\"\n\timport { useEventListener } from \"../../utils/utils\";\n\timport { injectContextRequired, requireClientContext, requireMapContext, requireSearchBoxContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { normalizeMarkerName } from \"facilmap-utils\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst searchBoxContext = requireSearchBoxContext(context);\n\n\tuseEventListener(mapContext, \"open-selection\", handleOpenSelection);\n\n\tconst markerId = computed(() => {\n\t\tif (mapContext.value.selection.length == 1 && mapContext.value.selection[0].type == \"marker\")\n\t\t\treturn mapContext.value.selection[0].id;\n\t\telse\n\t\t\treturn undefined;\n\t});\n\n\tconst marker = computed(() => markerId.value != null ? client.value.markers[markerId.value] : undefined);\n\n\twatch(marker, () => {\n\t\tif (!marker.value && markerId.value != null)\n\t\t\tclose();\n\t});\n\n\tfunction handleOpenSelection(): void {\n\t\tif (marker.value)\n\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-marker-info-tab`, { expand: true });\n\t}\n\n\tfunction close(): void {\n\t\tmapContext.value.components.selectionHandler.setSelectedItems([]);\n\t}\n</script>\n\n<template>\n\t<template v-if=\"markerId\">\n\t\t<SearchBoxTab\n\t\t\t:id=\"`fm${context.id}-marker-info-tab`\"\n\t\t\t:title=\"marker ? normalizeMarkerName(marker.name) : ''\"\n\t\t\tisCloseable\n\t\t\t@close=\"close()\"\n\t\t>\n\t\t\t<MarkerInfo :markerId=\"markerId\"></MarkerInfo>\n\t\t</SearchBoxTab>\n\t</template>\n</template>","<script setup lang=\"ts\">\n\timport type { ID, Line, Marker } from \"facilmap-types\";\n\timport { combineZoomDestinations, flyTo, getZoomDestinationForLine, getZoomDestinationForMarker } from \"../../utils/zoom\";\n\timport Icon from \"../ui/icon.vue\";\n\timport MarkerInfo from \"../marker-info/marker-info.vue\";\n\timport LineInfo from \"../line-info/line-info.vue\";\n\timport { computed, ref, watch } from \"vue\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport { showConfirm } from \"../ui/alert.vue\";\n\timport { useCarousel } from \"../../utils/carousel\";\n\timport ZoomToObjectButton from \"../ui/zoom-to-object-button.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport { formatTypeName, isLine, isMarker, normalizeLineName, normalizeMarkerName } from \"facilmap-utils\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tobjects: Array<Marker | Line>;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"click-object\": [object: Marker | Line, event: MouseEvent];\n\t}>();\n\n\tconst isDeleting = ref(false);\n\tconst openedObjectId = ref<ID>();\n\tconst openedObjectType = ref<\"marker\" | \"line\">();\n\n\tconst carouselRef = ref<HTMLElement>();\n\tconst carousel = useCarousel(carouselRef);\n\n\tfunction zoomToObject(object: Marker | Line): void {\n\t\tconst zoomDestination = isMarker(object) ? getZoomDestinationForMarker(object) : isLine(object) ? getZoomDestinationForLine(object) : undefined;\n\t\tif (zoomDestination)\n\t\t\tflyTo(mapContext.value.components.map, zoomDestination);\n\t}\n\n\tfunction openObject(object: Marker | Line): void {\n\t\topenedObjectId.value = object.id;\n\t\topenedObjectType.value = isMarker(object) ? \"marker\" : isLine(object) ? \"line\" : undefined;\n\t\tcarousel.setTab(1);\n\t}\n\n\tconst openedObject = computed(() => {\n\t\tlet openedObject: Marker | Line | undefined = undefined;\n\t\tif (openedObjectId.value != null) {\n\t\t\tif (openedObjectType.value == \"marker\")\n\t\t\t\topenedObject = client.value.markers[openedObjectId.value];\n\t\t\telse if (openedObjectType.value == \"line\")\n\t\t\t\topenedObject = client.value.lines[openedObjectId.value];\n\t\t}\n\n\t\treturn openedObject && props.objects.includes(openedObject) ? openedObject : undefined;\n\t});\n\n\twatch(openedObject, () => {\n\t\tif (!openedObject.value)\n\t\t\tcarousel.setTab(0);\n\t});\n\n\tasync function deleteObjects(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-multiple-info-delete`);\n\n\t\tif (!props.objects || !await showConfirm({\n\t\t\ttitle: i18n.t(\"multiple-info.delete-objects-title\", { count: props.objects.length }),\n\t\t\tmessage: i18n.t(\"multiple-info.delete-objects-message\", { count: props.objects.length }),\n\t\t\tvariant: \"danger\",\n\t\t\tokLabel: i18n.t(\"multiple-info.delete-objects-ok\")\n\t\t}))\n\t\t\treturn;\n\n\t\tisDeleting.value = true;\n\n\t\ttry {\n\t\t\tfor (const object of props.objects) {\n\t\t\t\tif (isMarker(object))\n\t\t\t\t\tawait client.value.deleteMarker({ id: object.id });\n\t\t\t\telse if (isLine(object))\n\t\t\t\t\tawait client.value.deleteLine({ id: object.id });\n\t\t\t}\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-multiple-info-delete`, () => i18n.t(\"multiple-info.delete-objects-error\"), err);\n\t\t} finally {\n\t\t\tisDeleting.value = false;\n\t\t}\n\t}\n\n\tconst zoomDestination = computed(() => {\n\t\treturn combineZoomDestinations(props.objects.map((object) => {\n\t\t\tif (isMarker(object))\n\t\t\t\treturn getZoomDestinationForMarker(object);\n\t\t\telse if (isLine(object))\n\t\t\t\treturn getZoomDestinationForLine(object);\n\t\t\telse\n\t\t\t\treturn undefined;\n\t\t}));\n\t});\n</script>\n\n<template>\n\t<div class=\"fm-multiple-info\">\n\t\t<div class=\"carousel slide fm-flex-carousel\" ref=\"carouselRef\">\n\t\t\t<div class=\"carousel-item\" :class=\"{ active: carousel.tab === 0 }\">\n\t\t\t\t<ul class=\"list-group fm-search-box-collapse-point\">\n\t\t\t\t\t<li v-for=\"object in props.objects\" :key=\"`${isMarker(object) ? 'm' : 'l'}-${object.id}`\" class=\"list-group-item active\">\n\t\t\t\t\t\t<span class=\"text-break\">\n\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"emit('click-object', object, $event)\">{{isMarker(object) ? normalizeMarkerName(object.name) : normalizeLineName(object.name)}}</a>\n\t\t\t\t\t\t\t{{\" \"}}\n\t\t\t\t\t\t\t<span class=\"result-type\" v-if=\"client.types[object.typeId]\">({{formatTypeName(client.types[object.typeId].name)}})</span>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<a href=\"javascript:\" @click=\"zoomToObject(object)\" v-tooltip.left=\"i18n.t('multiple-info.zoom-to-object')\"><Icon icon=\"zoom-in\" :alt=\"i18n.t('multiple-info.zoom')\"></Icon></a>\n\t\t\t\t\t\t<a href=\"javascript:\" @click=\"openObject(object)\" v-tooltip.right=\"i18n.t('multiple-info.show-details')\"><Icon icon=\"arrow-right\" :alt=\"i18n.t('multiple-info.details')\"></Icon></a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<div class=\"btn-toolbar mt-2\">\n\t\t\t\t\t<ZoomToObjectButton\n\t\t\t\t\t\tv-if=\"zoomDestination\"\n\t\t\t\t\t\t:label=\"i18n.t('multiple-info.zoom-to-object-label')\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t:destination=\"zoomDestination\"\n\t\t\t\t\t></ZoomToObjectButton>\n\n\t\t\t\t\t<button\n\t\t\t\t\t\tv-if=\"!client.readonly\"\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"btn btn-secondary btn-sm\"\n\t\t\t\t\t\t@click=\"deleteObjects()\"\n\t\t\t\t\t\t:disabled=\"isDeleting || mapContext.interaction\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div v-if=\"isDeleting\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t{{i18n.t(\"multiple-info.delete\")}}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"carousel-item\" :class=\"{ active: carousel.tab === 1 }\">\n\t\t\t\t<MarkerInfo\n\t\t\t\t\tv-if=\"openedObject && isMarker(openedObject)\"\n\t\t\t\t\t:markerId=\"openedObject.id\"\n\t\t\t\t\tshow-back-button\n\t\t\t\t\t@back=\"carousel.setTab(0)\"\n\t\t\t\t></MarkerInfo>\n\t\t\t\t<LineInfo\n\t\t\t\t\tv-else-if=\"openedObject && isLine(openedObject)\"\n\t\t\t\t\t:lineId=\"openedObject.id\"\n\t\t\t\t\tshow-back-button\n\t\t\t\t\t@back=\"carousel.setTab(0)\"\n\t\t\t\t></LineInfo>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-multiple-info {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\n\t\t.list-group-item {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\n\t\t\t> :first-child {\n\t\t\t\tflex-grow: 1;\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport MultipleInfo from \"./multiple-info.vue\";\n\timport type { Line, Marker } from \"facilmap-types\";\n\timport { useEventListener } from \"../../utils/utils\";\n\timport { isLine, isMarker } from \"facilmap-utils\";\n\timport SearchBoxTab from \"../search-box/search-box-tab.vue\";\n\timport { computed } from \"vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext, requireSearchBoxContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst searchBoxContext = requireSearchBoxContext(context);\n\n\tuseEventListener(mapContext, \"open-selection\", handleOpenSelection);\n\n\tconst objects = computed(() => {\n\t\tconst objects = mapContext.value.selection.flatMap((item): Array<Marker | Line> => {\n\t\t\tif (item.type == \"marker\" && client.value.markers[item.id])\n\t\t\t\treturn [client.value.markers[item.id]];\n\t\t\telse if (item.type == \"line\" && client.value.lines[item.id])\n\t\t\t\treturn [client.value.lines[item.id]];\n\t\t\telse\n\t\t\t\treturn [];\n\t\t});\n\t\treturn objects.length > 1 ? objects : undefined;\n\t});\n\n\tfunction handleOpenSelection(): void {\n\t\tif (objects.value)\n\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-multiple-info-tab`, { expand: true });\n\t}\n\n\tconst title = computed(() => objects.value ? `${objects.value.length} objects` : \"\");\n\n\tfunction handleObjectClick(object: Marker | Line, event: MouseEvent): void {\n\t\tconst item = mapContext.value.selection.find((it) => {\n\t\t\treturn (it.type == \"marker\" && isMarker(object) && it.id == object.id) || (it.type == \"line\" && isLine(object) && it.id == object.id);\n\t\t});\n\t\tif (item) {\n\t\t\tif (event.ctrlKey)\n\t\t\t\tmapContext.value.components.selectionHandler.setSelectedItems(mapContext.value.selection.filter((it) => it !== item), true);\n\t\t\telse\n\t\t\t\tmapContext.value.components.selectionHandler.setSelectedItems([item], true);\n\t\t}\n\t}\n\n\tfunction close(): void {\n\t\tmapContext.value.components.selectionHandler.setSelectedItems([]);\n\t}\n</script>\n\n<template>\n\t<template v-if=\"objects\">\n\t\t<SearchBoxTab\n\t\t\t:id=\"`fm${context.id}-multiple-info-tab`\"\n\t\t\t:title=\"title\"\n\t\t\tisCloseable\n\t\t\t@close=\"close()\"\n\t\t>\n\t\t\t<MultipleInfo :objects=\"objects\" @click-object=\"handleObjectClick\"></MultipleInfo>\n\t\t</SearchBoxTab>\n\t</template>\n</template>","<script setup lang=\"ts\">\n\timport { getAllOverpassPresets, getOverpassPreset, validateOverpassQuery } from \"facilmap-leaflet\";\n\timport { computed, ref, watch } from \"vue\";\n\timport { injectContextRequired, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ValidatedField from \"../ui/validated-form/validated-field.vue\";\n\timport { T, useI18n } from \"../../utils/i18n\";\nimport { sortBy } from \"lodash-es\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst activeTab = ref(0);\n\tconst searchTerm = ref(\"\");\n\tconst customQuery = ref(\"\");\n\n\tconst categories = computed(() => {\n\t\treturn getAllOverpassPresets().map((cat) => {\n\t\t\tconst presets = cat.presets.map((presets) => sortBy(presets.map((preset) => ({\n\t\t\t\t...preset,\n\t\t\t\tisChecked: mapContext.value.overpassPresets.some((p) => p.key === preset.key)\n\t\t\t})), (preset) => preset.label.toLowerCase()));\n\t\t\treturn {\n\t\t\t\t...cat,\n\t\t\t\tpresets,\n\t\t\t\tchecked: presets.flat().filter((preset) => preset.isChecked).length\n\t\t\t}\n\t\t});\n\t});\n\n\tconst filteredPresets = computed(() => {\n\t\tif (!searchTerm.value)\n\t\t\treturn [];\n\n\t\tconst lowerTerm = searchTerm.value.toLowerCase();\n\t\treturn categories.value.map((cat) => cat.presets).flat().flat().filter((preset) => preset.label.toLowerCase().includes(lowerTerm));\n\t});\n\n\twatch(() => mapContext.value.overpassCustom, () => {\n\t\tcustomQuery.value = mapContext.value.overpassCustom;\n\t}, { immediate: true });\n\n\tfunction togglePreset(key: string, enable: boolean): void {\n\t\tconst without = mapContext.value.overpassPresets.filter((p) => p.key != key);\n\t\tmapContext.value.components.overpassLayer.setQuery([\n\t\t\t...without,\n\t\t\t...(enable ? [getOverpassPreset(key)!] : [])\n\t\t]);\n\t}\n\n\tfunction toggleIsCustom(): void {\n\t\tif (mapContext.value.overpassIsCustom) {\n\t\t\tmapContext.value.components.overpassLayer.setQuery(mapContext.value.overpassPresets);\n\t\t} else {\n\t\t\tmapContext.value.components.overpassLayer.setQuery(mapContext.value.overpassCustom);\n\t\t}\n\t}\n\n\tasync function validateCustomQuery(query: string, signal: AbortSignal): Promise<string | undefined> {\n\t\tif (query) {\n\t\t\tconst result = await validateOverpassQuery(query, signal);\n\t\t\tif (result) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t\tif (!signal.aborted) {\n\t\t\tmapContext.value.components.overpassLayer.setQuery(query);\n\t\t}\n\t}\n</script>\n\n<template>\n\t<div class=\"fm-overpass-form\">\n\t\t<template v-if=\"!mapContext.overpassIsCustom\">\n\t\t\t<input\n\t\t\t\tclass=\"form-control fm-autofocus\"\n\t\t\t\ttype=\"search\"\n\t\t\t\tv-model=\"searchTerm\"\n\t\t\t\t:placeholder=\"i18n.t('overpass-form.filter')\"\n\t\t\t/>\n\t\t\t<hr />\n\n\t\t\t<template v-if=\"searchTerm\">\n\t\t\t\t<div class=\"checkbox-grid fm-search-box-collapse-point\">\n\t\t\t\t\t<template v-for=\"preset in filteredPresets\" :key=\"preset.key\">\n\t\t\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t\t:id=\"`fm${context.id}-overpass-form-preset-${preset.key}`\"\n\t\t\t\t\t\t\t\t:checked=\"preset.isChecked\"\n\t\t\t\t\t\t\t\t@change=\"togglePreset(preset.key, ($event.target as HTMLInputElement).checked)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<label :for=\"`fm${context.id}-overpass-form-preset-${preset.key}`\" class=\"form-check-label\">\n\t\t\t\t\t\t\t\t{{preset.label}}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</div>\n\t\t\t</template>\n\n\t\t\t<template v-else>\n\t\t\t\t<ul class=\"nav nav-pills\">\n\t\t\t\t\t<template v-for=\"(category, idx) in categories\" :key=\"idx\">\n\t\t\t\t\t\t<li class=\"nav-item\">\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\tclass=\"nav-link\"\n\t\t\t\t\t\t\t\t:class=\"{ active: activeTab === idx }\"\n\t\t\t\t\t\t\t\t@click=\"activeTab = idx\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{{category.label}}\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tv-if=\"category.checked > 0\"\n\t\t\t\t\t\t\t\t\tclass=\"badge\"\n\t\t\t\t\t\t\t\t\t:class=\"activeTab == idx ? 'text-bg-secondary' : 'text-bg-primary'\"\n\t\t\t\t\t\t\t\t>{{category.checked}}</span>\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</template>\n\t\t\t\t</ul>\n\n\t\t\t\t<hr />\n\n\t\t\t\t<div class=\"fm-search-box-collapse-point\">\n\t\t\t\t\t<template v-for=\"(presets, idx) in categories[activeTab].presets\" :key=\"idx\">\n\t\t\t\t\t\t<hr v-if=\"idx > 0\" />\n\t\t\t\t\t\t<div class=\"checkbox-grid\">\n\t\t\t\t\t\t\t<template v-for=\"preset in presets\" :key=\"preset.key\">\n\t\t\t\t\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t\t\t\t:id=\"`fm${context.id}-overpass-form-preset-${preset.key}`\"\n\t\t\t\t\t\t\t\t\t\t:checked=\"preset.isChecked\"\n\t\t\t\t\t\t\t\t\t\t@change=\"togglePreset(preset.key, ($event.target as HTMLInputElement).checked)\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<label :for=\"`fm${context.id}-overpass-form-preset-${preset.key}`\" class=\"form-check-label\">\n\t\t\t\t\t\t\t\t\t\t{{preset.label}}\n\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<ValidatedField\n\t\t\t\ttag=\"form\"\n\t\t\t\taction=\"javascript:\"\n\t\t\t\t:value=\"customQuery\"\n\t\t\t\t:validators=\"[validateCustomQuery]\"\n\t\t\t\t:reportValid=\"!!customQuery\"\n\t\t\t\timmediate\n\t\t\t\t:debounceMs=\"500\"\n\t\t\t>\n\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t<textarea\n\t\t\t\t\t\tv-model=\"customQuery\"\n\t\t\t\t\t\trows=\"5\"\n\t\t\t\t\t\tclass=\"form-control text-monospace\"\n\t\t\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\t\t></textarea>\n\t\t\t\t\t<div class=\"invalid-feedback\" v-if=\"slotProps.validationError\">\n\t\t\t\t\t\t<pre>{{slotProps.validationError}}</pre>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t</ValidatedField>\n\n\t\t\t<hr />\n\n\t\t\t<p>\n\t\t\t\t<T k=\"overpass-form.custom-explanation-1\">\n\t\t\t\t\t<template #statement>\n\t\t\t\t\t\t<a :href=\"i18n.t('overpass-form.custom-explanation-1-interpolation-statement-url')\" target=\"_blank\" rel=\"noopener\">\n\t\t\t\t\t\t\t{{i18n.t(\"overpass-form.custom-explanation-1-interpolation-statement\")}}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</template>\n\t\t\t\t\t<template #out>\n\t\t\t\t\t\t<code>out</code>\n\t\t\t\t\t</template>\n\t\t\t\t</T>\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\t<T k=\"overpass-form.custom-explanation-2\">\n\t\t\t\t\t<template #parking>\n\t\t\t\t\t\t<code>nwr[amenity=parking]</code>\n\t\t\t\t\t</template>\n\t\t\t\t\t<template #atm>\n\t\t\t\t\t\t<code>(nwr[amenity=atm];nwr[amenity=bank][atm][atm!=no];)</code>\n\t\t\t\t\t</template>\n\t\t\t\t</T>\n\t\t\t</p>\n\t\t</template>\n\n\t\t<hr />\n\n\t\t<div class=\"btn-toolbar\">\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t:class=\"{ active: mapContext.overpassIsCustom }\"\n\t\t\t\t@click=\"toggleIsCustom()\"\n\t\t\t>{{i18n.t(\"overpass-form.custom-query\")}}</button>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-overpass-form {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\n\t\t.checkbox-grid {\n\t\t\tcolumn-width: 160px;\n\t\t\tpadding: 0 .25rem;\n\t\t}\n\n\t\tpre {\n\t\t\tcolor: inherit;\n\t\t\tfont-size: inherit;\n\t\t}\n\n\t\tfieldset + hr, p + hr {\n\t\t\tmargin-top: 0;\n\t\t}\n\n\t\t.nav-link {\n\t\t\tdisplay: flex;\n\t\t\tgap: 5px;\n\t\t\talign-items: center;\n\t\t}\n\n\t\t.fm-search-box-collapse-point {\n\t\t\tmin-height: 1.5em;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport OverpassForm from \"./overpass-form.vue\";\n\timport SearchBoxTab from \"../search-box/search-box-tab.vue\";\n\timport { injectContextRequired } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst i18n = useI18n();\n</script>\n\n<template>\n\t<SearchBoxTab\n\t\t:title=\"i18n.t('overpass-form-tab.pois')\"\n\t\t:id=\"`fm${context.id}-overpass-form-tab`\"\n\t\tclass=\"fm-overpass-form-tab\"\n\t>\n\t\t<OverpassForm></OverpassForm>\n\t</SearchBoxTab>\n</template>\n\n<style lang=\"scss\">\n\t.fm-overpass-form-tab.fm-overpass-form-tab.fm-overpass-form-tab {\n\t\tpadding: 0.5rem;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t}\n</style>","<script setup lang=\"ts\">\n\timport copyToClipboard from \"copy-to-clipboard\";\n\timport { computed, ref } from \"vue\";\n\timport { useToasts } from \"./toasts/toasts.vue\";\n\timport QrcodeVue from \"qrcode.vue\";\n\timport Popover from \"./popover.vue\";\n\timport Icon from \"./icon.vue\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport type { Validator } from \"./validated-form/validated-field.vue\";\n\timport ValidatedField from \"./validated-form/validated-field.vue\";\n\timport type { ThemeColour } from \"../../utils/bootstrap\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tprefix?: string;\n\t\tnoQr?: boolean;\n\t\tsuccessTitle?: string;\n\t\tsuccessMessage?: string;\n\t\treadonly?: boolean;\n\t\trows?: number;\n\t\t/** If specified, will be used for the clipboard/QR code instead of `${prefix}${modelValue}` */\n\t\tfullUrl?: string;\n\t\tvalidators?: Array<Validator<string>>;\n\t\tvariant?: ThemeColour;\n\t}>();\n\n\tconst modelValue = defineModel<string>({ required: true });\n\n\tconst qrButtonRef = ref<HTMLButtonElement>();\n\tconst showQr = ref(false);\n\n\tconst fullUrl = computed(() => props.fullUrl ?? `${props.prefix ?? \"\"}${modelValue.value}`);\n\n\tfunction copy(): void {\n\t\tcopyToClipboard(fullUrl.value);\n\t\ttoasts.showToast(undefined, () => (props.successTitle ?? i18n.t(\"copy-to-clipboard-input.copied-fallback-title\")), () => (props.successMessage ?? i18n.t(\"copy-to-clipboard-input.copied-fallback-message\")), { variant: \"success\", autoHide: true });\n\t}\n</script>\n\n<template>\n\t<ValidatedField\n\t\t:value=\"modelValue\"\n\t\t:validators=\"props.validators\"\n\t\tv-bind=\"$attrs\"\n\t\tclass=\"fm-copy-to-clipboard-input\"\n\t>\n\t\t<template #default=\"slotProps\">\n\t\t\t<div class=\"input-group has-validation\">\n\t\t\t\t<span v-if=\"props.prefix\" class=\"input-group-text\">{{props.prefix}}</span>\n\t\t\t\t<template v-if=\"props.rows && props.rows > 1\">\n\t\t\t\t\t<textarea\n\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\tv-model=\"modelValue\"\n\t\t\t\t\t\t:readonly=\"props.readonly\"\n\t\t\t\t\t\t:rows=\"props.rows\"\n\t\t\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\t\t></textarea>\n\t\t\t\t</template>\n\t\t\t\t<template v-else>\n\t\t\t\t\t<input\n\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\tv-model=\"modelValue\"\n\t\t\t\t\t\t:readonly=\"props.readonly\"\n\t\t\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\t\t/>\n\t\t\t\t</template>\n\t\t\t\t<button type=\"button\" :class=\"`btn btn-${props.variant ?? 'secondary'}`\" @click=\"copy()\">{{i18n.t(\"copy-to-clipboard-input.copy\")}}</button>\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"!props.noQr\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"btn btn-secondary fm-copy-to-clipboard-input-qr-button\"\n\t\t\t\t\t:class=\"{ active: showQr }\"\n\t\t\t\t\tref=\"qrButtonRef\"\n\t\t\t\t\t@click=\"showQr = !showQr\"\n\t\t\t\t>\n\t\t\t\t\t<Icon icon=\"qrcode\" :alt=\"i18n.t('copy-to-clipboard-input.qr-code-alt')\"></Icon>\n\t\t\t\t\t<span v-if=\"!showQr\" class=\"fm-copy-to-clipboard-input-qr-tooltip\" v-tooltip=\"i18n.t('copy-to-clipboard-input.qr-code-tooltip')\"></span>\n\t\t\t\t</button>\n\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\t</ValidatedField>\n\n\t<Popover v-if=\"!props.noQr\" :element=\"qrButtonRef\" v-model:show=\"showQr\" placement=\"left\" hideOnOutsideClick>\n\t\t<QrcodeVue :value=\"fullUrl\" :size=\"150\" level=\"L\" render-as=\"svg\"></QrcodeVue>\n\t</Popover>\n</template>\n\n<style lang=\"scss\">\n\t.fm-copy-to-clipboard-input {\n\t\t.fm-copy-to-clipboard-input-qr-button {\n\t\t\tposition: relative;\n\t\t}\n\n\t\t.fm-copy-to-clipboard-input-qr-tooltip {\n\t\t\tposition: absolute;\n\t\t\tinset: 0 0 0 0;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { padIdValidator, type CRU, type PadData } from \"facilmap-types\";\n\timport { computed } from \"vue\";\n\timport { getUniqueId, getZodValidator, validateRequired } from \"../../utils/utils\";\n\timport { injectContextRequired } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport CopyToClipboardInput from \"../ui/copy-to-clipboard-input.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst idProps = [\"id\", \"writeId\", \"adminId\"] as const;\n\ttype IdProp = typeof idProps[number];\n\n\tconst context = injectContextRequired();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tpadData: PadData<CRU.CREATE>;\n\t\tidProp: IdProp;\n\t\tmodelValue: string;\n\t\tlabel: string;\n\t\tdescription: string;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [string];\n\t}>();\n\n\tconst id = getUniqueId(\"fm-pad-settings-pad-id-edit\");\n\n\tconst value = computed({\n\t\tget: () => props.modelValue,\n\t\tset: (val) => {\n\t\t\temit(\"update:modelValue\", val);\n\t\t}\n\t});\n\n\tfunction validateDistinctPadId(id: string) {\n\t\tif (idProps.some((p) => p !== props.idProp && props.padData[p] === id)) {\n\t\t\treturn i18n.t(\"pad-id-edit.unique-id-error\");\n\t\t}\n\t}\n</script>\n\n<template>\n\t<div class=\"row mb-3\">\n\t\t<label :for=\"`${id}-input`\" class=\"col-sm-3 col-form-label\">{{props.label}}</label>\n\t\t<div class=\"col-sm-9 position-relative\">\n\t\t\t<CopyToClipboardInput\n\t\t\t\tv-model=\"value\"\n\t\t\t\t:prefix=\"context.baseUrl\"\n\t\t\t\tsuccessTitle=\"Map link copied\"\n\t\t\t\tsuccessMessage=\"The map link was copied to the clipboard.\"\n\t\t\t\t:fullUrl=\"`${context.baseUrl}${encodeURIComponent(value)}`\"\n\t\t\t\t:validators=\"[validateRequired, getZodValidator(padIdValidator), validateDistinctPadId]\"\n\t\t\t></CopyToClipboardInput>\n\n\t\t\t<div class=\"form-text\">\n\t\t\t\t{{props.description}}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-pad-settings-pad-id-edit {\n\t\tinput {\n\t\t\tmin-width: 11rem;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { computed, ref, watch } from \"vue\";\n\timport { padDataValidator, type CRU, type PadData } from \"facilmap-types\";\n\timport { generateRandomPadId, mergeObject } from \"facilmap-utils\";\n\timport { getUniqueId, getZodValidator } from \"../../utils/utils\";\n\timport { cloneDeep, isEqual } from \"lodash-es\";\n\timport ModalDialog from \"../ui/modal-dialog.vue\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport { showConfirm } from \"../ui/alert.vue\";\n\timport PadIdEdit from \"./pad-id-edit.vue\";\n\timport { injectContextRequired, requireClientContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ValidatedField from \"../ui/validated-form/validated-field.vue\";\n\timport { T, useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tproposedAdminId?: string;\n\t\tnoCancel?: boolean;\n\t\tisCreate?: boolean;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\thide: [];\n\t\thidden: [];\n\t}>();\n\n\tconst id = getUniqueId(\"fm-pad-settings\");\n\tconst isDeleting = ref(false);\n\tconst deleteConfirmation = ref(\"\");\n\tconst expectedDeleteConfirmation = computed(() => i18n.t('pad-settings-dialog.delete-code'));\n\n\tconst initialPadData: PadData<CRU.CREATE> | undefined = props.isCreate ? {\n\t\tname: \"\",\n\t\tsearchEngines: false,\n\t\tdescription: \"\",\n\t\tclusterMarkers: false,\n\t\tadminId: (props.proposedAdminId || generateRandomPadId(16)),\n\t\twriteId: generateRandomPadId(14),\n\t\tid: generateRandomPadId(12),\n\t\tlegend1: \"\",\n\t\tlegend2: \"\",\n\t\tdefaultViewId: null\n\t} : undefined;\n\n\tconst originalPadData = computed(() => props.isCreate ? initialPadData! : client.value.padData as PadData<CRU.CREATE>);\n\n\tconst padData = ref(cloneDeep(originalPadData.value));\n\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\n\tconst isModified = computed(() => !isEqual(padData.value, originalPadData.value));\n\n\twatch(() => client.value.padData, (newPadData, oldPadData) => {\n\t\tif (!props.isCreate && padData.value && newPadData)\n\t\t\tmergeObject(oldPadData, newPadData, padData.value as PadData);\n\t}, { deep: true });\n\n\tasync function save(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-pad-settings-error`);\n\n\t\ttry {\n\t\t\tif(props.isCreate)\n\t\t\t\tawait client.value.createPad(padData.value as PadData<CRU.CREATE>);\n\t\t\telse\n\t\t\t\tawait client.value.editPad(padData.value);\n\t\t\tmodalRef.value?.modal.hide();\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-pad-settings-error`, () => (props.isCreate ? i18n.t(\"pad-settings-dialog.create-map-error\") : i18n.t(\"pad-settings-dialog.save-map-error\")), err);\n\t\t}\n\t};\n\n\tasync function deletePad(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-pad-settings-error`);\n\n\t\tif (!await showConfirm({\n\t\t\ttitle: i18n.t(\"pad-settings-dialog.delete-map-title\"),\n\t\t\tmessage: i18n.t(\"pad-settings-dialog.delete-map-message\", { name: padData.value.name }),\n\t\t\tvariant: \"danger\",\n\t\t\tokLabel: i18n.t(\"pad-settings-dialog.delete-map-ok\")\n\t\t})) {\n\t\t\treturn;\n\t\t}\n\n\t\tisDeleting.value = true;\n\n\t\ttry {\n\t\t\tawait client.value.deletePad();\n\t\t\tmodalRef.value?.modal.hide();\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-pad-settings-error`, () => i18n.t(\"pad-settings-dialog.delete-map-error\"), err);\n\t\t} finally {\n\t\t\tisDeleting.value = false;\n\t\t}\n\t};\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"props.isCreate ? i18n.t('pad-settings-dialog.title-create') : i18n.t('pad-settings-dialog.title-edit')\"\n\t\tclass=\"fm-pad-settings\"\n\t\t:noCancel=\"props.noCancel\"\n\t\t:isBusy=\"isDeleting\"\n\t\t:isCreate=\"props.isCreate\"\n\t\t:isModified=\"isModified\"\n\t\t:okLabel=\"props.isCreate ? i18n.t('pad-settings-dialog.create-button') : undefined\"\n\t\tref=\"modalRef\"\n\t\t@submit=\"$event.waitUntil(save())\"\n\t\t@hide=\"emit('hide')\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<template v-if=\"padData\">\n\t\t\t<PadIdEdit\n\t\t\t\t:padData=\"padData\"\n\t\t\t\tidProp=\"adminId\"\n\t\t\t\tv-model=\"padData.adminId\"\n\t\t\t\t:label=\"i18n.t('pad-settings-dialog.admin-link-label')\"\n\t\t\t\t:description=\"i18n.t('pad-settings-dialog.admin-link-description')\"\n\t\t\t></PadIdEdit>\n\n\t\t\t<PadIdEdit\n\t\t\t\t:padData=\"padData\"\n\t\t\t\tidProp=\"writeId\"\n\t\t\t\tv-model=\"padData.writeId\"\n\t\t\t\t:label=\"i18n.t('pad-settings-dialog.write-link-label')\"\n\t\t\t\t:description=\"i18n.t('pad-settings-dialog.write-link-description')\"\n\t\t\t></PadIdEdit>\n\n\t\t\t<PadIdEdit\n\t\t\t\t:padData=\"padData\"\n\t\t\t\tidProp=\"id\"\n\t\t\t\tv-model=\"padData.id\"\n\t\t\t\t:label=\"i18n.t('pad-settings-dialog.read-link-label')\"\n\t\t\t\t:description=\"i18n.t('pad-settings-dialog.read-link-description')\"\n\t\t\t></PadIdEdit>\n\n\t\t\t<ValidatedField\n\t\t\t\tclass=\"row mb-3\"\n\t\t\t\t:value=\"padData.name\"\n\t\t\t\t:validators=\"[getZodValidator(padDataValidator.update.shape.name)]\"\n\t\t\t>\n\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t<label :for=\"`${id}-pad-name-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"pad-settings-dialog.map-name\")}}</label>\n\t\t\t\t\t<div class=\"col-sm-9 position-relative\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t:id=\"`${id}-pad-name-input`\"\n\t\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tv-model=\"padData.name\"\n\t\t\t\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t</ValidatedField>\n\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-search-engines-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"pad-settings-dialog.search-engines\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t:id=\"`${id}-search-engines-input`\"\n\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\tv-model=\"padData.searchEngines\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<label :for=\"`${id}-search-engines-input`\" class=\"form-check-label\">\n\t\t\t\t\t\t\t{{i18n.t(\"pad-settings-dialog.search-engines-label\")}}\n\t\t\t\t\t\t</label>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"form-text\">\n\t\t\t\t\t\t{{i18n.t(\"pad-settings-dialog.search-engines-description\")}}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-description-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"pad-settings-dialog.map-description\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<input\n\t\t\t\t\t\t:id=\"`${id}-description-input`\"\n\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tv-model=\"padData.description\"\n\t\t\t\t\t/>\n\t\t\t\t\t<div class=\"form-text\">\n\t\t\t\t\t\t{{i18n.t(\"pad-settings-dialog.map-description-description\")}}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-cluster-markers-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"pad-settings-dialog.cluster-markers\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t:id=\"`${id}-cluster-markers-input`\"\n\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\tv-model=\"padData.clusterMarkers\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<label :for=\"`${id}-cluster-markers-input`\" class=\"form-check-label\">\n\t\t\t\t\t\t\t{{i18n.t(\"pad-settings-dialog.cluster-markers-label\")}}\n\t\t\t\t\t\t</label>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"form-text\">\n\t\t\t\t\t\t{{i18n.t(\"pad-settings-dialog.cluster-markers-description\")}}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-legend1-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"pad-settings-dialog.legend-text\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<textarea\n\t\t\t\t\t\t:id=\"`${id}-legend1-input`\"\n\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tv-model=\"padData.legend1\"\n\t\t\t\t\t></textarea>\n\t\t\t\t\t<textarea\n\t\t\t\t\t\t:id=\"`${id}-legend2-input`\"\n\t\t\t\t\t\tclass=\"form-control mt-1\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tv-model=\"padData.legend2\"\n\t\t\t\t\t></textarea>\n\t\t\t\t\t<div class=\"form-text\">\n\t\t\t\t\t\t<T k=\"pad-settings-dialog.legend-text-description\">\n\t\t\t\t\t\t\t<template #markdown>\n\t\t\t\t\t\t\t\t<a href=\"http://commonmark.org/help/\" target=\"_blank\">{{i18n.t(\"pad-settings-dialog.legend-text-description-interpolation-markdown\")}}</a>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<template v-if=\"padData && !props.isCreate\">\n\t\t\t<hr/>\n\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-delete-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"pad-settings-dialog.delete-map\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<div class=\"input-group\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t:form=\"`${id}-delete-form`\"\n\t\t\t\t\t\t\t:id=\"`${id}-delete-input`\"\n\t\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tv-model=\"deleteConfirmation\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t:form=\"`${id}-delete-form`\"\n\t\t\t\t\t\t\tclass=\"btn btn-danger\"\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\t:disabled=\"isDeleting || modalRef?.formData?.isSubmitting || deleteConfirmation != expectedDeleteConfirmation\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div v-if=\"isDeleting\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t{{i18n.t(\"pad-settings-dialog.delete-map-button\")}}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"form-text\">\n\t\t\t\t\t\t<T k=\"pad-settings-dialog.delete-description\">\n\t\t\t\t\t\t\t<template #code>\n\t\t\t\t\t\t\t\t<code>{{expectedDeleteConfirmation}}</code>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\t</ModalDialog>\n\n\t<form :id=\"`${id}-delete-form`\" @submit.prevent=\"deleteConfirmation == expectedDeleteConfirmation && deletePad()\">\n\t</form>\n</template>","<script setup lang=\"ts\">\n\timport RouteForm from \"./route-form.vue\";\n\timport type { HashQuery } from \"facilmap-leaflet\";\n\timport SearchBoxTab from \"../search-box/search-box-tab.vue\";\n\timport { readonly, ref, toRef } from \"vue\";\n\timport { injectContextRequired, requireSearchBoxContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport type { WritableRouteFormTabContext } from \"../facil-map-context-provider/route-form-tab-context\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst searchBoxContext = requireSearchBoxContext(context);\n\tconst i18n = useI18n();\n\n\tconst routeForm = ref<InstanceType<typeof RouteForm>>();\n\n\tconst hashQuery = ref<HashQuery>();\n\n\tconst routeFormTabContext = ref<WritableRouteFormTabContext>({\n\t\tsetQuery(query, zoom, smooth) {\n\t\t\trouteForm.value!.setQuery(query, zoom, smooth);\n\t\t},\n\n\t\tsetFrom(destination) {\n\t\t\trouteForm.value!.setFrom(destination);\n\t\t},\n\n\t\taddVia(destination) {\n\t\t\trouteForm.value!.addVia(destination);\n\t\t},\n\n\t\tsetTo(destination) {\n\t\t\trouteForm.value!.setTo(destination);\n\t\t}\n\t});\n\n\tcontext.provideComponent(\"routeFormTab\", toRef(readonly(routeFormTabContext)));\n\n\tfunction activate(): void {\n\t\tsearchBoxContext.value.activateTab(`fm${context.id}-route-form-tab`, { expand: true });\n\t}\n</script>\n\n<template>\n\t<SearchBoxTab\n\t\t:title=\"i18n.t('route-form-tab.tab-label')\"\n\t\t:id=\"`fm${context.id}-route-form-tab`\"\n\t\t:hashQuery=\"hashQuery\"\n\t\tclass=\"fm-route-form-tab\"\n\t>\n\t\t<template #default=\"slotProps\">\n\t\t\t<RouteForm :active=\"slotProps.isActive\" @activate=\"activate()\" ref=\"routeForm\" @hash-query-change=\"hashQuery = $event\"></RouteForm>\n\t\t</template>\n\t</SearchBoxTab>\n</template>\n\n<style lang=\"scss\">\n\t.fm-route-form-tab.fm-route-form-tab.fm-route-form-tab {\n\t\tpadding: 0.5rem;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tflex-grow: 1;\n\n\t\t.input-group {\n\t\t\tposition: static;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport Icon from \"../ui/icon.vue\";\n\timport hammer from \"hammerjs\";\n\timport { type Ref, defineComponent, nextTick, onMounted, onScopeDispose, reactive, readonly, ref, toRef, watch } from \"vue\";\n\timport vTooltip, { hideAllTooltips } from \"../../utils/tooltip\";\n\timport type { SearchBoxEventMap, SearchBoxTab, WritableSearchBoxContext } from \"../facil-map-context-provider/search-box-context\";\n\timport mitt from \"mitt\";\n\timport { injectContextRequired, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst tabs = reactive(new Map<string, SearchBoxTab>());\n\tconst activeTabId = ref<string | undefined>();\n\tconst tabHistory = ref<string[]>([]);\n\n\tfunction provideTab(id: string, tabRef: Ref<SearchBoxTab>) {\n\t\tif (tabs.has(id)) {\n\t\t\tthrow new Error(`Tab with ID ${id} already present.`);\n\t\t}\n\n\t\twatch(tabRef, (tab) => {\n\t\t\ttabs.set(id, tab);\n\t\t}, { immediate: true });\n\n\t\tif (activeTabId.value == null) {\n\t\t\tactivateTab(id, { autofocus: context.settings.autofocus });\n\t\t}\n\n\t\tonScopeDispose(() => {\n\t\t\ttabs.delete(id);\n\n\t\t\tconst isActive = activeTabId.value === id;\n\t\t\ttabHistory.value = tabHistory.value.filter((v) => v !== id);\n\t\t\tif (isActive) {\n\t\t\t\tactiveTabId.value = tabHistory.value[tabHistory.value.length - 1];\n\t\t\t\tif (restoreHeight.value && context.isNarrow && containerRef.value) {\n\t\t\t\t\tcontainerRef.value.style.flexBasis = `${restoreHeight.value}px`;\n\t\t\t\t}\n\t\t\t\trestoreHeight.value = undefined;\n\t\t\t}\n\t\t});\n\t}\n\n\tfunction activateTab(id: string, { expand = false, autofocus = false }: { expand?: boolean; autofocus?: boolean } = {}) {\n\t\tactiveTabId.value = id;\n\t\ttabHistory.value.push(id);\n\t\trestoreHeight.value = undefined;\n\n\t\tif (expand) {\n\t\t\tvoid nextTick(() => {\n\t\t\t\tdoExpand();\n\t\t\t});\n\t\t}\n\n\t\tif (autofocus && !context.isNarrow) {\n\t\t\tvoid nextTick(() => {\n\t\t\t\tcontainerRef.value?.querySelector<HTMLElement>(\":scope > .card-body.active [autofocus],:scope > .card-body.active .fm-autofocus\")?.focus();\n\t\t\t});\n\t\t}\n\t}\n\n\tconst searchBoxContext: WritableSearchBoxContext = reactive(Object.assign(mitt<SearchBoxEventMap>(), {\n\t\ttabs,\n\t\tactiveTabId: undefined,\n\t\tactiveTab: undefined,\n\t\tprovideTab,\n\t\tactivateTab\n\t}));\n\n\tcontext.provideComponent(\"searchBox\", toRef(readonly(searchBoxContext)));\n\n\twatch([\n\t\tactiveTabId,\n\t\t() => activeTabId.value != null ? tabs.get(activeTabId.value) : undefined\n\t], ([tabId, tab]) => {\n\t\tsearchBoxContext.activeTabId = tabId;\n\t\tsearchBoxContext.activeTab = tab ? readonly(tab) : undefined;\n\t});\n\n\tconst containerRef = ref<HTMLElement>();\n\tconst cardHeaderRef = ref<HTMLElement>();\n\tconst resizeHandleRef = ref<HTMLElement>();\n\n\tconst isPanning = ref<boolean>();\n\tconst panStartHeight = ref<number>();\n\tconst restoreHeight = ref<number>();\n\tconst resizeStartHeight = ref<number>();\n\tconst resizeStartWidth = ref<number>();\n\tconst hasFocus = ref(false);\n\tconst isResizing = ref(false);\n\n\tonMounted(() => {\n\t\tconst pan = new hammer.Manager(cardHeaderRef.value!);\n\t\tpan.add(new hammer.Pan({ direction: hammer.DIRECTION_VERTICAL }));\n\t\tpan.on(\"panstart\", handlePanStart);\n\t\tpan.on(\"pan\", handlePanMove);\n\t\tpan.on(\"panend\", handlePanEnd);\n\n\t\tconst resize = new hammer.Manager(resizeHandleRef.value!);\n\t\tresize.add(new hammer.Pan({ direction: hammer.DIRECTION_ALL }));\n\t\tresize.add(new hammer.Tap());\n\t\tresize.on(\"panstart\", handleResizeStart);\n\t\tresize.on(\"pan\", handleResizeMove);\n\t\tresize.on(\"panend\", handleResizeEnd);\n\t\tresize.on(\"tap\", handleResizeClick);\n\t});\n\n\tfunction handlePanStart(): void {\n\t\tisPanning.value = true;\n\t\trestoreHeight.value = undefined;\n\t\tpanStartHeight.value = parseInt(getComputedStyle(containerRef.value!).flexBasis);\n\t}\n\n\tfunction handlePanMove(event: any): void {\n\t\tif (context.isNarrow && panStartHeight.value != null && event.srcEvent.type != \"pointercancel\")\n\t\t\tcontainerRef.value!.style.flexBasis = `${getSanitizedHeight(panStartHeight.value - event.deltaY)}px`;\n\t}\n\n\tfunction handlePanEnd(): void {\n\t\tisPanning.value = false;\n\t\tmapContext.value.components.map.invalidateSize({ pan: false });\n\t}\n\n\tfunction getSanitizedHeight(height: number): number {\n\t\tconst maxHeight = (containerRef.value!.offsetParent as HTMLElement).offsetHeight - 5;\n\t\treturn Math.max(0, Math.min(maxHeight, height));\n\t}\n\n\tfunction doExpand(): void {\n\t\tif (context.isNarrow) {\n\t\t\tconst currentHeight = parseInt(getComputedStyle(containerRef.value!).flexBasis);\n\t\t\tif (currentHeight < 120) {\n\t\t\t\trestoreHeight.value = currentHeight;\n\t\t\t\tconst mapHeight = (containerRef.value!.offsetParent as HTMLElement).offsetHeight;\n\t\t\t\tconst defaultHeight = Math.min(Math.max(170, mapHeight / 2), 200);\n\t\t\t\tcontainerRef.value!.style.flexBasis = `${defaultHeight}px`;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction handleResizeStart(): void {\n\t\tisResizing.value = true;\n\t\tresizeStartWidth.value = containerRef.value!.offsetWidth;\n\t\tresizeStartHeight.value = containerRef.value!.offsetHeight;\n\t\thideAllTooltips();\n\t\tsearchBoxContext.emit(\"resizestart\");\n\t}\n\n\tfunction handleResizeMove(event: any): void {\n\t\tcontainerRef.value!.style.width = `${resizeStartWidth.value + event.deltaX}px`;\n\t\tcontainerRef.value!.style.height = `${resizeStartHeight.value + event.deltaY}px`;\n\t\tsearchBoxContext.emit(\"resize\");\n\t}\n\n\tfunction handleResizeEnd(): void {\n\t\tisResizing.value = false;\n\t\tsearchBoxContext.emit(\"resizeend\");\n\t}\n\n\tfunction handleResizeClick(): void {\n\t\tcontainerRef.value!.style.width = \"\";\n\t\tcontainerRef.value!.style.height = \"\";\n\t\thideAllTooltips();\n\t\tsearchBoxContext.emit(\"resizereset\");\n\t}\n\n\tfunction handleFocusIn(e: FocusEvent): void {\n\t\tif ((e.target as HTMLElement).closest(\"input,textarea\"))\n\t\t\thasFocus.value = true;\n\t}\n\n\tfunction handleFocusOut(e: FocusEvent): void {\n\t\thasFocus.value = false;\n\t}\n\n\tfunction handleTransitionEnd(): void {\n\t\tmapContext.value.components.map.invalidateSize({ pan: false });\n\t}\n\n\tconst TabContent = defineComponent({\n\t\tprops: {\n\t\t\tisActive: { type: Boolean, required: true },\n\t\t\ttabId: { type: String, required: true }\n\t\t},\n\t\tsetup(props) {\n\t\t\treturn () => searchBoxContext.tabs.get(props.tabId)?.content?.({ isActive: props.isActive });\n\t\t}\n\t});\n\n\twatch(() => searchBoxContext.activeTab?.hashQuery, (hashQuery) => {\n\t\tmapContext.value.setFallbackQuery(hashQuery);\n\t});\n</script>\n\n<template>\n\t<div\n\t\tclass=\"card fm-search-box\"\n\t\tv-show=\"searchBoxContext.tabs.size > 0\"\n\t\tref=\"containerRef\"\n\t\t:class=\"{ isNarrow: context.isNarrow, hasFocus, isPanning }\"\n\t\t@focusin=\"handleFocusIn\"\n\t\t@focusout=\"handleFocusOut\"\n\t\t@transitionend=\"handleTransitionEnd\"\n\t>\n\t\t<div\n\t\t\tclass=\"card-header\"\n\t\t\tref=\"cardHeaderRef\"\n\t\t\t@contextmenu=\"($event as PointerEvent).pointerType === 'touch' && context.isNarrow && $event.preventDefault()\"\n\t\t>\n\t\t\t<ul class=\"nav nav-tabs card-header-tabs\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"[tabId, tab] in searchBoxContext.tabs\"\n\t\t\t\t\t:key=\"tabId\"\n\t\t\t\t\tclass=\"nav-item nav-link\"\n\t\t\t\t\t:class=\"{ active: tabId === searchBoxContext.activeTabId }\"\n\t\t\t\t> <!-- nav-link class on the <li> rather than the <a> so that we can have multiple <a> children -->\n\t\t\t\t\t<a\n\t\t\t\t\t\t:aria-current=\"tabId === searchBoxContext.activeTabId ? 'true' : undefined\"\n\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t:class=\"{ active: tabId === searchBoxContext.activeTabId }\"\n\t\t\t\t\t\t@click=\"searchBoxContext.activateTab(tabId, { expand: true, autofocus: true })\"\n\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t>{{tab.title}}</a>\n\n\t\t\t\t\t<a\n\t\t\t\t\t\tv-if=\"tab.onClose\"\n\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t@click=\"tab.onClose()\"\n\t\t\t\t\t\tdraggable=\"false\"\n\t\t\t\t\t><Icon icon=\"remove\" :alt=\"i18n.t('search-box.close-alt')\"></Icon></a>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<template v-for=\"[tabId, tab] in searchBoxContext.tabs\" :key=\"tabId\">\n\t\t\t<div v-show=\"tabId === searchBoxContext.activeTabId\" class=\"card-body\" :class=\"[tab.class, { active: tabId === searchBoxContext.activeTabId }]\">\n\t\t\t\t<TabContent :tabId=\"tabId\" :isActive=\"tabId === searchBoxContext.activeTabId\"></TabContent>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<a\n\t\t\tv-show=\"!context.isNarrow\"\n\t\t\thref=\"javascript:\"\n\t\t\tclass=\"fm-search-box-resize\"\n\t\t\tv-tooltip.right=\"i18n.t('search-box.resize-tooltip')\"\n\t\t\tref=\"resizeHandleRef\"\n\t\t><Icon icon=\"resize-horizontal\"></Icon></a>\n\t</div>\n\n</template>\n\n<style lang=\"scss\">\n\t.fm-search-box.fm-search-box {\n\t\t&:not(.isNarrow) {\n\t\t\tposition: absolute;\n\t\t\ttop: 10px !important; /* Override drag position from narrow mode */\n\t\t\tleft: 52px;\n\t\t\tmax-height: calc(100% - 25px);\n\t\t\tmin-width: 19rem;\n\t\t\tmin-height: 6rem;\n\t\t\twidth: 29.5rem;\n\n\t\t\ttransition: opacity .7s,background-color .7s,border-color .7s;\n\t\t\topacity: .7;\n\n\t\t\t&:hover,&.hasFocus {\n\t\t\t\topacity: 1;\n\t\t\t}\n\n\t\t\t> .card-header .nav-tabs .nav-item {\n\t\t\t\tpadding: 0;\n\n\t\t\t\t> :nth-child(1) {\n\t\t\t\t\tpadding: 0.1rem 0.1rem 0.1rem 0.3rem;\n\t\t\t\t}\n\n\t\t\t\t> :nth-child(2) {\n\t\t\t\t\tpadding: 0.1rem 0.3rem 0.1rem 0.1rem;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t&.isNarrow {\n\t\t\tmin-height: 55px;\n\t\t\tflex-basis: 55px;\n\t\t\toverflow: hidden;\n\n\t\t\t&:not(.isPanning) {\n\t\t\t\ttransition: flex-basis 0.4s;\n\t\t\t}\n\n\t\t\theight: auto !important; /* Override resize height from non-narrow mode */\n\t\t\twidth: auto !important; /* Override resize width from non-narrow mode */\n\n\t\t\t> .card-header {\n\t\t\t\tpadding-top: 11px;\n\t\t\t\tposition: relative;\n\t\t\t\t-webkit-touch-callout: none;\n\t\t\t\tcursor: row-resize;\n\n\t\t\t\t&::before {\n\t\t\t\t\tcontent: \"\";\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tleft: 0;\n\t\t\t\t\tright: 0;\n\t\t\t\t\tmargin: 0 auto;\n\t\t\t\t\ttop: 4px;\n\t\t\t\t\tborder-top: 3px double #aaa;\n\t\t\t\t\twidth: 40px;\n\t\t\t\t}\n\n\t\t\t\t> .nav {\n\t\t\t\t\tcursor: default;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t&.isPanning > .card-header {\n\t\t\t\tcursor: row-resize;\n\n\t\t\t\t> * {\n\t\t\t\t\t// Prevent click event on drag end (see https://stackoverflow.com/a/59957886/242365)\n\t\t\t\t\tpointer-events: none;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t> .card-body {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tmin-height: 0;\n\t\t\toverflow: auto;\n\t\t}\n\n\t\t> .card-header {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tflex-shrink: 0;\n\t\t\tpadding: 0.3rem 0.3rem 0 0.3rem;\n\n\t\t\t.nav-tabs {\n\t\t\t\tdisplay: grid;\n\t\t\t\tgrid-auto-columns: 1fr;\n\t\t\t\tgrid-auto-flow: column;\n\t\t\t\ttext-align: center;\n\t\t\t\tgap: 5px;\n\t\t\t\tmargin: 0;\n\n\t\t\t\t.nav-item {\n\t\t\t\t\tmin-width: 0;\n\t\t\t\t\tdisplay: flex;\n\n\t\t\t\t\ta {\n\t\t\t\t\t\ttext-decoration: inherit; // Set to none in \".nav-link\" style, but apply that to the <li> rather than the <a>\n\t\t\t\t\t}\n\n\t\t\t\t\t> :nth-child(1) {\n\t\t\t\t\t\tflex-grow: 1;\n\t\t\t\t\t\ttext-overflow: ellipsis;\n\t\t\t\t\t\twhite-space: nowrap;\n\t\t\t\t\t\toverflow: hidden;\n\t\t\t\t\t}\n\n\t\t\t\t\t> :nth-child(2) {\n\t\t\t\t\t\t&, > .fm-icon {\n\t\t\t\t\t\t\tflex-shrink: 0;\n\t\t\t\t\t\t\tdisplay: inline-flex;\n\t\t\t\t\t\t\talign-items: center;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t.fm-search-box-collapse-point {\n\t\t\toverflow: auto;\n\t\t}\n\n\t\thr {\n\t\t\twidth: 100%;\n\t\t\tmargin: 0.5rem 0;\n\t\t}\n\n\t\t.list-group-item {\n\t\t\tpadding: 0.5rem;\n\t\t}\n\n\t\th2 {\n\t\t\tmargin-top: 0;\n\t\t\tfont-size: 1.6em;\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t}\n\n\t\th3 {\n\t\t\tfont-size: 1.2em;\n\t\t}\n\n\t\t* + h3 {\n\t\t\tmargin-top: 15px;\n\t\t}\n\n\t\tdl.fm-search-box-dl {\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: 150px auto;\n\t\t\tgap: 5px;\n\t\t\tmargin-bottom: 0.5rem;\n\n\t\t\t* {\n\t\t\t\tmin-width: 0;\n\t\t\t}\n\n\t\t\tdd {\n\t\t\t\tmargin-bottom: 0;\n\t\t\t}\n\t\t}\n\n\t\t.pos,.distance,.elevation {\n\t\t\tcolor: #888;\n\t\t}\n\t}\n\n\n\t.fm-search-box-resize {\n\t\tposition: absolute;\n\t\tbottom: 0;\n\t\tright: 0;\n\t\ttransform: translate(30%,30%) rotate(45deg);\n\n\t\tcursor: nwse-resize;\n\t\tborder: 1px solid #ddd;\n\t\tborder-radius: 1000px;\n\t\tbox-shadow: 0 1px 2px rgba(0, 0, 0, .075);\n\t\tbackground: #fff;\n\t\tcolor: #666;\n\t\tpadding: 2px;\n\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\n\t\t.fm-icon {\n\t\t\tdisplay: flex;\n\t\t}\n\n\t\tsvg {\n\t\t\twidth: 20px;\n\t\t\theight: 20px;\n\t\t}\n\n\t\topacity: 0.5;\n\t\ttransition: opacity .7s;\n\n\t\t/* .fm-search-box:not(:hover):not(.fm-hasResults):not(.fm-hasFocus) & {\n\t\t\topacity: 0;\n\t\t} */\n\n\t\t.fm-search-box:hover &,.fm-search-box.hasFocus & {\n\t\t\topacity: 1;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { formatCoordinates, renderOsmTag } from \"facilmap-utils\";\n\timport type { FindOnMapResult, Point, SearchResult, Type } from \"facilmap-types\";\n\timport Icon from \"./ui/icon.vue\";\n\timport type { FileResult } from \"../utils/files\";\n\timport { isFileResult, isMarkerResult } from \"../utils/search\";\n\timport { searchResultsToLinesWithTags, searchResultsToMarkersWithTags } from \"../utils/add\";\n\timport { getZoomDestinationForSearchResult } from \"../utils/zoom\";\n\timport Coordinates from \"./ui/coordinates.vue\";\n\timport { computed } from \"vue\";\n\timport UseAsDropdown from \"./ui/use-as-dropdown.vue\";\n\timport ZoomToObjectButton from \"./ui/zoom-to-object-button.vue\";\n\timport type { RouteDestination } from \"./facil-map-context-provider/route-form-tab-context\";\n\timport AddToMapDropdown from \"./ui/add-to-map-dropdown.vue\";\n\timport { useI18n } from \"../utils/i18n\";\n\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tresult: SearchResult | FileResult;\n\t\tshowBackButton?: boolean;\n\t\t/** If specified, will be passed to the route form as suggestions when using the \"Use as\" menu */\n\t\tsearchResults?: SearchResult[];\n\t\t/** If specified, will be passed to the route form as suggestions when using the \"Use as\" menu */\n\t\tmapResults?: FindOnMapResult[];\n\t\tisLoading?: boolean;\n\t}>(), {\n\t\tshowBackButton: false\n\t});\n\n\tconst emit = defineEmits<{\n\t\tback: [];\n\t\t\"add-to-map\": [type: Type];\n\t}>();\n\n\tconst isMarker = computed(() => isMarkerResult(props.result));\n\n\tconst zoomDestination = computed(() => getZoomDestinationForSearchResult(props.result));\n\n\tconst routeDestination = computed<RouteDestination | undefined>(() => {\n\t\tif (isFileResult(props.result)) {\n\t\t\tif (props.result.lat != null && props.result.lon != null) {\n\t\t\t\treturn { query: formatCoordinates({ lat: props.result.lat, lon: props.result.lon }) };\n\t\t\t} else if (props.result.geojson?.type === \"Point\") {\n\t\t\t\treturn { query: formatCoordinates({ lat: props.result.geojson.coordinates[1], lon: props.result.geojson.coordinates[0] }) };\n\t\t\t} else {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tquery: props.result.short_name,\n\t\t\t\tsearchSuggestions: (props.searchResults || props.mapResults) ? props.searchResults : [props.result],\n\t\t\t\tmapSuggestions: props.mapResults,\n\t\t\t\tselectedSuggestion: props.result\n\t\t\t};\n\t\t}\n\t});\n\n\tconst markersWithTags = computed(() => searchResultsToMarkersWithTags([props.result]));\n\tconst linesWithTags = computed(() => searchResultsToLinesWithTags([props.result]));\n</script>\n\n<template>\n\t<div class=\"fm-search-result-info\" v-if=\"result\">\n\t\t<h2 class=\"text-break\">\n\t\t\t<a v-if=\"showBackButton\" href=\"javascript:\" @click=\"emit('back')\"><Icon icon=\"arrow-left\"></Icon></a>\n\t\t\t{{result.short_name}}\n\t\t</h2>\n\t\t<dl class=\"fm-search-box-collapse-point fm-search-box-dl\">\n\t\t\t<template v-if=\"result.lat != null && result.lon != null\">\n\t\t\t\t<dt class=\"pos\">{{i18n.t(\"search-result-info.coordinates\")}}</dt>\n\t\t\t\t<dd class=\"pos\"><Coordinates :point=\"result as Point\" :ele=\"result.elevation\"></Coordinates></dd>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"result.type\">\n\t\t\t\t<dt>{{i18n.t(\"search-result-info.type\")}}</dt>\n\t\t\t\t<dd class=\"text-break\">{{result.type}}</dd>\n\t\t\t</template>\n\n\t\t\t<template v-if=\"result.address\">\n\t\t\t\t<dt>{{i18n.t(\"search-result-info.address\")}}</dt>\n\t\t\t\t<dd class=\"text-break\">{{result.address}}</dd>\n\t\t\t</template>\n\n\t\t\t<template v-for=\"(value, key) in result.extratags\" :key=\"key\">\n\t\t\t\t<dt>{{key}}</dt>\n\t\t\t\t<dd class=\"text-break\" v-html=\"renderOsmTag(key, value)\"></dd>\n\t\t\t</template>\n\t\t</dl>\n\n\t\t<template v-if=\"props.isLoading\">\n\t\t\t<div class=\"d-flex justify-content-center mb-3\">\n\t\t\t\t<div class=\"spinner-border\"></div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<div class=\"btn-toolbar\">\n\t\t\t<ZoomToObjectButton\n\t\t\t\tv-if=\"zoomDestination\"\n\t\t\t\t:label=\"i18n.t('search-result-info.zoom-to-result-label')\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\t:destination=\"zoomDestination\"\n\t\t\t></ZoomToObjectButton>\n\n\t\t\t<AddToMapDropdown\n\t\t\t\t:markers=\"markersWithTags\"\n\t\t\t\t:lines=\"linesWithTags\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\tisSingle\n\t\t\t></AddToMapDropdown>\n\n\t\t\t<UseAsDropdown\n\t\t\t\tv-if=\"isMarker && routeDestination\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\t:destination=\"routeDestination\"\n\t\t\t></UseAsDropdown>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-search-result-info {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\n\t\t.fm-search-box-collapse-point {\n\t\t\tmin-height: 1.5em;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport type { ID, Type } from \"facilmap-types\";\n\timport type { FileResult, FileResultObject } from \"../../utils/files\";\n\timport { isLineResult, isMarkerResult, typeExists } from \"../../utils/search\";\n\timport { mapValues, pickBy, uniq } from \"lodash-es\";\n\timport ModalDialog from \"../ui/modal-dialog.vue\";\n\timport { getUniqueId } from \"../../utils/utils\";\n\timport { computed, ref } from \"vue\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport { injectContextRequired, requireClientContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { type LineWithTags, type MarkerWithTags, addToMap, searchResultToLineWithTags, searchResultToMarkerWithTags } from \"../../utils/add\";\n\timport { formatTypeName, getOrderedTypes } from \"facilmap-utils\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tcustomTypes?: FileResultObject[\"types\"];\n\t\tresults: FileResult[];\n\t}>(), {\n\t\tcustomTypes: () => ({})\n\t});\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst id = getUniqueId(\"fm-custom-import-dialog\");\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\n\tconst activeFileResultsByType = computed(() => {\n\t\treturn mapValues(props.customTypes, (type, id) => props.results.filter((result) => result.fmTypeId != null && `${result.fmTypeId}` == `${id}`));\n\t});\n\n\ttype Option = { key: string; value: string | false; text: string; disabled?: boolean };\n\n\tconst orderedTypes = computed(() => getOrderedTypes(client.value.types));\n\n\tconst customMappingOptions = computed(() => {\n\t\treturn mapValues(pickBy(props.customTypes, (customType, customTypeId) => activeFileResultsByType.value[customTypeId as any].length > 0), (customType, customTypeId): Option[] => {\n\t\t\tconst recommendedOptions: Option[] = [];\n\n\t\t\tfor (const type of orderedTypes.value) {\n\t\t\t\tif (type.name == customType.name && type.type == customType.type)\n\t\t\t\t\trecommendedOptions.push({ key: `e${type.id}`, value: `e${type.id}`, text: i18n.t(\"custom-import-dialog.existing-type\", { name: formatTypeName(type.name) }) });\n\t\t\t}\n\n\t\t\tif (client.value.writable == 2 && !typeExists(client.value, customType))\n\t\t\t\trecommendedOptions.push({ key: `i${customTypeId}`, value: `i${customTypeId}`, text: i18n.t(\"custom-import-dialog.import-type\", { name: customType.name }) });\n\n\t\t\trecommendedOptions.push({ key: \"false1\", value: false, text: i18n.t(\"custom-import-dialog.no-import\") });\n\n\n\t\t\tconst otherOptions: Option[] = [];\n\n\t\t\tfor (const type of orderedTypes.value) {\n\t\t\t\tif (type.name != customType.name && type.type == customType.type)\n\t\t\t\t\totherOptions.push({ key: `e${type.id}`, value: `e${type.id}`, text: i18n.t(\"custom-import-dialog.existing-type\", { name: formatTypeName(type.name) }) });\n\t\t\t}\n\n\t\t\tfor (const [customTypeId2, customType2] of Object.entries(props.customTypes)) {\n\t\t\t\tif (client.value.writable == 2 && customType2.type == customType.type && customTypeId2 != customTypeId && !typeExists(client.value, customType2))\n\t\t\t\t\totherOptions.push({ key: `i${customTypeId2}`, value: `i${customTypeId2}`, text: i18n.t(\"custom-import-dialog.import-type\", { name: customType2.name }) });\n\t\t\t}\n\n\n\t\t\treturn [\n\t\t\t\t...recommendedOptions,\n\t\t\t\t...(recommendedOptions.length > 0 && otherOptions.length > 0 ? [\n\t\t\t\t\t{ key: \"false2\", value: false, text: \"──────────\", disabled: true } satisfies Option\n\t\t\t\t] : []),\n\t\t\t\t...otherOptions\n\t\t\t];\n\t\t});\n\t});\n\n\tconst customMapping = ref<Record<ID, false | string>>(mapValues(customMappingOptions.value, (options) => options[0].value));\n\tconst untypedMarkerMapping = ref<false | string>(false);\n\tconst untypedLineMapping = ref<false | string>(false);\n\n\tconst untypedMarkers = computed(() => {\n\t\treturn props.results.filter((result) => (result.fmTypeId == null || !props.customTypes[result.fmTypeId]) && isMarkerResult(result));\n\t});\n\n\tconst untypedLines = computed(() => {\n\t\treturn props.results.filter((result) => (result.fmTypeId == null || !props.customTypes[result.fmTypeId]) && isLineResult(result));\n\t});\n\n\tconst untypedMarkerMappingOptions = computed(() => {\n\t\tconst options: Array<{ key: string; value: string | false; text: string }> = [];\n\t\toptions.push({ key: \"false\", value: false, text: i18n.t(\"custom-import-dialog.no-import\") });\n\n\t\tfor (const customTypeId of Object.keys(props.customTypes)) {\n\t\t\tconst customType = props.customTypes[customTypeId as any];\n\t\t\tif (client.value.writable && customType.type == \"marker\" && !typeExists(client.value, customType))\n\t\t\t\toptions.push({ key: `i${customTypeId}`, value: `i${customTypeId}`, text: i18n.t(\"custom-import-dialog.import-type\", { name: customType.name }) });\n\t\t}\n\n\t\tfor (const type of orderedTypes.value) {\n\t\t\tif (type.type == \"marker\")\n\t\t\t\toptions.push({ key: `e${type.id}`, value: `e${type.id}`, text: i18n.t(\"custom-import-dialog.existing-type\", { name: formatTypeName(type.name) }) });\n\t\t}\n\n\t\treturn options;\n\t});\n\n\tconst untypedLineMappingOptions = computed(() => {\n\t\tconst options: Array<{ key: string; value: string | false; text: string }> = [];\n\t\toptions.push({ key: \"false\", value: false, text: i18n.t(\"custom-import-dialog.no-import\") });\n\n\t\tfor (const customTypeId of Object.keys(props.customTypes)) {\n\t\t\tconst customType = props.customTypes[customTypeId as any];\n\t\t\tif (client.value.writable && customType.type == \"line\")\n\t\t\t\toptions.push({ key: `i${customTypeId}`, value: `i${customTypeId}`, text: i18n.t(\"custom-import-dialog.import-type\", { name: customType.name }) });\n\t\t}\n\n\t\tfor (const type of orderedTypes.value) {\n\t\t\tif (type.type == \"line\")\n\t\t\t\toptions.push({ key: `e${type.id}`, value: `e${type.id}`, text: i18n.t(\"custom-import-dialog.existing-type\", { name: formatTypeName(type.name) }) });\n\t\t}\n\n\t\treturn options;\n\t});\n\n\tasync function save(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-search-result-info-add-error`);\n\n\t\ttry {\n\t\t\tconst resolvedMapping: Record<string, Type> = {};\n\t\t\tfor (const id of uniq([...Object.values(customMapping.value), untypedMarkerMapping.value, untypedLineMapping.value])) {\n\t\t\t\tif (id !== false) {\n\t\t\t\t\tconst m = id.match(/^([ei])(.*)$/);\n\t\t\t\t\tif (m && m[1] == \"e\")\n\t\t\t\t\t\tresolvedMapping[id] = client.value.types[m[2] as any];\n\t\t\t\t\telse if (m && m[1] == \"i\")\n\t\t\t\t\t\tresolvedMapping[id] = await client.value.addType(props.customTypes[m[2] as any]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst add = props.results.flatMap((result) => {\n\t\t\t\tconst id = (result.fmTypeId && customMapping.value[result.fmTypeId]) ? customMapping.value[result.fmTypeId] : isMarkerResult(result) ? untypedMarkerMapping.value : untypedLineMapping.value;\n\t\t\t\treturn id !== false && resolvedMapping[id] ? [{ result, type: resolvedMapping[id] }] : [];\n\t\t\t});\n\n\t\t\tawait addToMap(context, add.flatMap(({ result, type }): Array<({ marker: MarkerWithTags } | { line: LineWithTags }) & { type: Type }> => {\n\t\t\t\tif (type.type === 'marker') {\n\t\t\t\t\tconst marker = searchResultToMarkerWithTags(result);\n\t\t\t\t\treturn marker ? [{ marker, type }] : [];\n\t\t\t\t} else {\n\t\t\t\t\tconst line = searchResultToLineWithTags(result);\n\t\t\t\t\treturn line ? [{ line, type }] : [];\n\t\t\t\t};\n\t\t\t}));\n\n\t\t\tmodalRef.value?.modal.hide();\n\t\t} catch(err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-search-result-info-add-error`, () => i18n.t(\"custom-import-dialog.import-error\"), err);\n\t\t}\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('custom-import-dialog.dialog-title')\"\n\t\tclass=\"fm-search-results-custom-import\"\n\t\tisCreate\n\t\t:okLabel=\"i18n.t('custom-import-dialog.ok-label')\"\n\t\t@submit=\"$event.waitUntil(save())\"\n\t\tref=\"modalRef\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<table class=\"table table-striped table-hover\">\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th>{{i18n.t(\"custom-import-dialog.type\")}}</th>\n\t\t\t\t\t<th>{{i18n.t(\"custom-import-dialog.map-to\")}}</th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t<!-- eslint-disable-next-line vue/require-v-for-key -->\n\t\t\t\t<tr v-for=\"(options, importTypeId) in customMappingOptions\">\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<label :for=\"`${id}-map-type-${importTypeId}`\">\n\t\t\t\t\t\t\t{{customTypes[importTypeId as number].type == 'marker'\n\t\t\t\t\t\t\t\t? i18n.t(\"custom-import-dialog.markers\", {\n\t\t\t\t\t\t\t\t\ttypeName: customTypes[importTypeId as number].name,\n\t\t\t\t\t\t\t\t\tcount: activeFileResultsByType[importTypeId as number].length\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: i18n.t(\"custom-import-dialog.lines\", {\n\t\t\t\t\t\t\t\t\ttypeName: customTypes[importTypeId as number].name,\n\t\t\t\t\t\t\t\t\tcount: activeFileResultsByType[importTypeId as number].length\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t</label>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<select :id=\"`${id}-map-type-${importTypeId}`\" v-model=\"customMapping[importTypeId as number]\">\n\t\t\t\t\t\t\t<option v-for=\"option in options\" :key=\"option.key\" :value=\"option.value\">{{option.text}}</option>\n\t\t\t\t\t\t</select>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr v-if=\"untypedMarkers.length > 0\">\n\t\t\t\t\t<td><label :for=\"`${id}-map-untyped-markers`\">{{i18n.t(\"custom-import-dialog.untyped-markers\", { count: untypedMarkers.length })}}</label></td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<select :id=\"`${id}-map-untyped-markers`\" v-model=\"untypedMarkerMapping\">\n\t\t\t\t\t\t\t<option v-for=\"option in untypedMarkerMappingOptions\" :key=\"option.key\" :value=\"option.value\">{{option.text}}</option>\n\t\t\t\t\t\t</select>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr v-if=\"untypedLines.length > 0\">\n\t\t\t\t\t<td><label :for=\"`${id}-map-untyped-lines`\">{{i18n.t(\"custom-import-dialog.untyped-lines\", { count: untypedLines.length })}}</label></td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<select :id=\"`${id}-map-untyped-lines`\" v-model=\"untypedLineMapping\">\n\t\t\t\t\t\t\t<option v-for=\"option in untypedLineMappingOptions\" :key=\"option.key\" :value=\"option.value\">{{option.text}}</option>\n\t\t\t\t\t\t</select>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</tbody>\n\t\t</table>\n\t</ModalDialog>\n</template>","<script setup lang=\"ts\">\n\timport type { FindOnMapResult, SearchResult } from \"facilmap-types\";\n\timport Icon from \"../ui/icon.vue\";\n\timport SearchResultInfo from \"../search-result-info.vue\";\n\timport type { SelectedItem } from \"../../utils/selection\";\n\timport type { FileResult, FileResultObject } from \"../../utils/files\";\n\timport { isFileResult, isLineResult, isMapResult, isMarkerResult } from \"../../utils/search\";\n\timport { searchResultsToLinesWithTags, searchResultsToMarkersWithTags } from \"../../utils/add\";\n\timport { combineZoomDestinations, flyTo, getZoomDestinationForMapResult, getZoomDestinationForResults, getZoomDestinationForSearchResult } from \"../../utils/zoom\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport { vScrollIntoView } from \"../../utils/vue\";\n\timport { computed, ref, toRef, watch } from \"vue\";\n\timport CustomImportDialog from \"./custom-import-dialog.vue\";\n\timport { useCarousel } from \"../../utils/carousel\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport AddToMapDropdown from \"../ui/add-to-map-dropdown.vue\";\n\timport { formatTypeName, normalizeLineName, normalizeMarkerName } from \"facilmap-utils\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst searchBoxContext = toRef(() => context.components.searchBox);\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tsearchResults?: Array<SearchResult | FileResult>;\n\t\tmapResults?: FindOnMapResult[];\n\t\tlayerId: number;\n\t\t/** When clicking a search result, union zoom to it. Normal zoom is done when clicking the zoom button. */\n\t\tunionZoom?: boolean;\n\t\t/** When clicking or selecting a search result, zoom to it. */\n\t\tautoZoom?: boolean;\n\t\tcustomTypes?: FileResultObject[\"types\"];\n\t}>(), {\n\t\tunionZoom: false,\n\t\tautoZoom: false,\n\t\tcustomTypes: () => ({})\n\t});\n\n\tconst carouselRef = ref<HTMLElement>();\n\tconst carousel = useCarousel(carouselRef);\n\tconst customImport = ref(false);\n\n\tconst showZoom = computed(() => !props.autoZoom || props.unionZoom);\n\n\tconst openResult = computed(() => {\n\t\tif (activeResults.value.length == 1 && !isMapResult(activeResults.value[0]))\n\t\t\treturn activeResults.value[0];\n\t\telse\n\t\t\treturn undefined;\n\t});\n\n\tconst activeResults = computed(() => {\n\t\treturn [\n\t\t\t...(props.searchResults || []).filter((result) => mapContext.value.selection.some((item) => item.type == \"searchResult\" && item.result === result)),\n\t\t\t...(props.mapResults || []).filter((result) => {\n\t\t\t\tif (result.kind == \"marker\")\n\t\t\t\t\treturn mapContext.value.selection.some((item) => item.type == \"marker\" && item.id == result.id);\n\t\t\t\telse if (result.kind == \"line\")\n\t\t\t\t\treturn mapContext.value.selection.some((item) => item.type == \"line\" && item.id == result.id);\n\t\t\t\telse\n\t\t\t\t\treturn false;\n\t\t\t})\n\t\t];\n\t});\n\n\tconst isAllSelected = computed(() => {\n\t\treturn !props.searchResults?.some((result) => !activeResults.value.includes(result));\n\t});\n\n\tconst activeSearchResults = computed(() => {\n\t\treturn activeResults.value.filter((result) => !isMapResult(result)) as Array<SearchResult | FileResult>;\n\t});\n\n\tconst activeMarkerSearchResults = computed(() => {\n\t\treturn activeSearchResults.value.filter((result) => isMarkerResult(result)) as Array<SearchResult | FileResult>;\n\t});\n\n\tconst activeLineSearchResults = computed(() => {\n\t\treturn activeSearchResults.value.filter((result) => isLineResult(result)) as Array<SearchResult | FileResult>;\n\t});\n\n\tconst activeFileResults = computed(() => {\n\t\treturn activeResults.value.filter(isFileResult);\n\t});\n\n\tconst hasCustomTypes = computed(() => {\n\t\treturn Object.keys(props.customTypes).length > 0;\n\t});\n\n\tfunction closeResult(): void {\n\t\tcarousel.setTab(0);\n\t}\n\n\twatch(openResult, () => {\n\t\tif (!openResult.value && carousel.tab != 0)\n\t\t\tcarousel.setTab(0);\n\t});\n\n\tfunction handleClick(result: SearchResult | FileResult | FindOnMapResult, event: MouseEvent): void {\n\t\tconst toggle = event.ctrlKey;\n\t\tselectResult(result, toggle);\n\n\t\tif (props.autoZoom)\n\t\t\tzoomToSelectedResults(props.unionZoom || toggle);\n\t}\n\n\tfunction zoomToSelectedResults(unionZoom: boolean): void {\n\t\tlet dest = getZoomDestinationForResults(activeResults.value);\n\t\tif (dest && unionZoom)\n\t\t\tdest = combineZoomDestinations([dest, { bounds: mapContext.value.components.map.getBounds() }]);\n\t\tif (dest)\n\t\t\tflyTo(mapContext.value.components.map, dest);\n\t}\n\n\tfunction zoomToResult(result: SearchResult | FileResult | FindOnMapResult): void {\n\t\tconst dest = isMapResult(result) ? getZoomDestinationForMapResult(result) : getZoomDestinationForSearchResult(result);\n\t\tif (dest)\n\t\t\tflyTo(mapContext.value.components.map, dest);\n\t}\n\n\tfunction handleOpen(result: SearchResult | FileResult | FindOnMapResult, event: MouseEvent): void {\n\t\tselectResult(result, false);\n\n\t\tsetTimeout(async () => {\n\t\t\tif (isMapResult(result)) {\n\t\t\t\tif (result.kind == \"marker\" && !client.value.markers[result.id])\n\t\t\t\t\tawait client.value.getMarker({ id: result.id });\n\t\t\t\tsearchBoxContext.value?.activateTab(`fm${context.id}-${result.kind}-info-tab`);\n\t\t\t} else\n\t\t\t\tcarousel.setTab(1);\n\t\t}, 0);\n\t}\n\n\tfunction selectResult(result: SearchResult | FileResult | FindOnMapResult, toggle: boolean): void {\n\t\tconst item: SelectedItem = isMapResult(result) ? { type: result.kind, id: result.id } : { type: \"searchResult\", result, layerId: props.layerId };\n\t\tif (toggle)\n\t\t\tmapContext.value.components.selectionHandler.toggleItem(item);\n\t\telse\n\t\t\tmapContext.value.components.selectionHandler.setSelectedItems([item]);\n\t}\n\n\tfunction toggleSelectAll(): void {\n\t\tif (!props.searchResults)\n\t\t\treturn;\n\n\t\tif (isAllSelected.value)\n\t\t\tmapContext.value.components.selectionHandler.setSelectedItems([]);\n\t\telse {\n\t\t\tmapContext.value.components.selectionHandler.setSelectedItems(props.searchResults.map((result) => ({ type: \"searchResult\", result, layerId: props.layerId })));\n\n\t\t\tif (props.autoZoom)\n\t\t\t\tzoomToSelectedResults(true);\n\t\t}\n\t}\n\n\tconst activeMarkersWithTags = computed(() => searchResultsToMarkersWithTags(activeMarkerSearchResults.value));\n\tconst activeLinesWithTags = computed(() => searchResultsToLinesWithTags(activeLineSearchResults.value));\n</script>\n\n<template>\n\t<div class=\"fm-search-results\" :class=\"{ isNarrow: context.isNarrow }\">\n\t\t<div class=\"carousel slide fm-flex-carousel\" ref=\"carouselRef\">\n\t\t\t<div class=\"carousel-item\" :class=\"{ active: carousel.tab === 0 }\">\n\t\t\t\t<div class=\"fm-search-box-collapse-point\">\n\t\t\t\t\t<slot name=\"before\"></slot>\n\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-if=\"(!searchResults || searchResults.length == 0) && (!mapResults || mapResults.length == 0)\"\n\t\t\t\t\t\tclass=\"alert alert-danger\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{i18n.t(\"search-results.no-results\")}}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<ul v-if=\"mapResults && mapResults.length > 0\" class=\"list-group\">\n\t\t\t\t\t\t<!-- eslint-disable-next-line vue/require-v-for-key -->\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tv-for=\"result in mapResults\"\n\t\t\t\t\t\t\tclass=\"list-group-item\"\n\t\t\t\t\t\t\t:class=\"{ active: activeResults.includes(result) }\"\n\t\t\t\t\t\t\tv-scroll-into-view=\"activeResults.includes(result)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span class=\"text-break\">\n\t\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"handleClick(result, $event)\">{{isMarkerResult(result) ? normalizeMarkerName(result.name) : normalizeLineName(result.name)}}</a>\n\t\t\t\t\t\t\t\t{{\" \"}}\n\t\t\t\t\t\t\t\t<span class=\"result-type\">({{formatTypeName(client.types[result.typeId].name)}})</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<a v-if=\"showZoom\" href=\"javascript:\" @click=\"zoomToResult(result)\" v-tooltip.hover.left=\"i18n.t('search-results.zoom-to-result-tooltip')\"><Icon icon=\"zoom-in\" :alt=\"i18n.t('search-results.zoom-to-result-alt')\"></Icon></a>\n\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"handleOpen(result, $event)\" v-tooltip.left=\"i18n.t('search-results.show-details-tooltip')\"><Icon icon=\"arrow-right\" :alt=\"i18n.t('search-results.show-details-alt')\"></Icon></a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\n\t\t\t\t\t<hr v-if=\"mapResults && mapResults.length > 0 && searchResults && searchResults.length > 0\"/>\n\n\t\t\t\t\t<ul v-if=\"searchResults && searchResults.length > 0\" class=\"list-group\">\n\t\t\t\t\t\t<!-- eslint-disable-next-line vue/require-v-for-key -->\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tv-for=\"result in searchResults\"\n\t\t\t\t\t\t\tclass=\"list-group-item\"\n\t\t\t\t\t\t\t:class=\"{ active: activeResults.includes(result) }\"\n\t\t\t\t\t\t\tv-scroll-into-view=\"activeResults.includes(result)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span class=\"text-break\">\n\t\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"handleClick(result, $event)\">{{result.display_name}}</a>\n\t\t\t\t\t\t\t\t{{\" \"}}\n\t\t\t\t\t\t\t\t<span class=\"result-type\" v-if=\"result.type\">({{result.type}})</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<a v-if=\"showZoom\" href=\"javascript:\" @click=\"zoomToResult(result)\" v-tooltip.left=\"i18n.t('search-results.zoom-to-result-tooltip')\"><Icon icon=\"zoom-in\" :alt=\"i18n.t('search-results.zoom-to-result-alt')\"></Icon></a>\n\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"handleOpen(result, $event)\" v-tooltip.right=\"i18n.t('search-results.show-details-tooltip')\"><Icon icon=\"arrow-right\" :alt=\"i18n.t('search-results.show-details-alt')\"></Icon></a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\n\t\t\t\t\t<slot name=\"after\"></slot>\n\t\t\t\t</div>\n\n\t\t\t\t<div v-if=\"client.padData && !client.readonly && searchResults && searchResults.length > 0\" class=\"btn-toolbar mt-2\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"btn btn-secondary btn-sm\"\n\t\t\t\t\t\t:class=\"{ active: isAllSelected }\"\n\t\t\t\t\t\t@click=\"toggleSelectAll\"\n\t\t\t\t\t>{{i18n.t(\"search-results.select-all\")}}</button>\n\n\t\t\t\t\t<AddToMapDropdown\n\t\t\t\t\t\t:label=\"i18n.t('search-results.add-to-map-label', { count: activeSearchResults.length })\"\n\t\t\t\t\t\t:markers=\"activeMarkersWithTags\"\n\t\t\t\t\t\t:lines=\"activeLinesWithTags\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<template v-if=\"hasCustomTypes\" #after>\n\t\t\t\t\t\t\t<li><hr class=\"dropdown-divider\"></li>\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t\t\t@click=\"customImport = true\"\n\t\t\t\t\t\t\t\t>{{i18n.t(\"search-results.custom-type-mapping\")}}</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</AddToMapDropdown>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"carousel-item\" :class=\"{ active: carousel.tab === 1 }\">\n\t\t\t\t<SearchResultInfo\n\t\t\t\t\tv-if=\"openResult\"\n\t\t\t\t\t:result=\"openResult\"\n\t\t\t\t\tshowBackButton\n\t\t\t\t\t:searchSuggestions=\"props.searchResults\"\n\t\t\t\t\t:mapSuggestions=\"props.mapResults\"\n\t\t\t\t\t@back=\"closeResult()\"\n\t\t\t\t></SearchResultInfo>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<CustomImportDialog\n\t\t\tv-if=\"customImport\"\n\t\t\t:customTypes=\"props.customTypes\"\n\t\t\t:results=\"activeFileResults\"\n\t\t\t@hidden=\"customImport = false\"\n\t\t></CustomImportDialog>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-search-results.fm-search-results {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\n\t\t.list-group-item {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\n\t\t\t> :first-child {\n\t\t\t\tflex-grow: 1;\n\t\t\t}\n\n\t\t\t> a, > a > .fm-icon {\n\t\t\t\tdisplay: inline-flex;\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport type { FileResultObject } from \"../utils/files\";\n\timport Icon from \"./ui/icon.vue\";\n\timport SearchResults from \"./search-results/search-results.vue\";\n\timport { displayView } from \"facilmap-leaflet\";\n\timport { typeExists, viewExists } from \"../utils/search\";\n\timport vTooltip from \"../utils/tooltip\";\n\timport { computed, ref } from \"vue\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { useI18n } from \"../utils/i18n\";\n\n\ttype ViewImport = FileResultObject[\"views\"][0];\n\ttype TypeImport = FileResultObject[\"types\"][0];\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst client = requireClientContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\tlayerId: number;\n\t\tfile: FileResultObject;\n\t\t/** When clicking a search result, union zoom to it. Normal zoom is done when clicking the zoom button. */\n\t\tunionZoom?: boolean;\n\t\t/** When clicking or selecting a search result, zoom to it. */\n\t\tautoZoom?: boolean;\n\t}>(), {\n\t\tunionZoom: false,\n\t\tautoZoom: false\n\t});\n\n\tconst isAddingView = ref(new Set<ViewImport>());\n\tconst isAddingType = ref(new Set<TypeImport>());\n\n\tconst hasViews = computed(() => props.file.views.length > 0);\n\n\tconst hasTypes = computed(() => Object.keys(props.file.types).length > 0);\n\n\tconst existingViews = computed(() => {\n\t\treturn new Map(props.file.views.map((view) => [view, viewExists(client.value, view)]));\n\t});\n\n\tfunction showView(view: ViewImport): void {\n\t\tdisplayView(mapContext.value.components.map, view, { overpassLayer: mapContext.value.components.overpassLayer });\n\t}\n\n\tasync function addView(view: ViewImport): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-file-result-import-error`);\n\t\tisAddingView.value.add(view);\n\n\t\ttry {\n\t\t\tawait client.value.addView(view);\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-file-result-import-error`, () => i18n.t(\"file-results.import-view-error\"), err);\n\t\t} finally {\n\t\t\tisAddingView.value.delete(view);\n\t\t}\n\t};\n\n\tconst existingTypes = computed(() => {\n\t\treturn new Map(Object.values(props.file.types).map((type) => [type, typeExists(client.value, type)]));\n\t});\n\n\tasync function addType(type: TypeImport): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-file-result-import-error`);\n\t\tisAddingType.value.add(type);\n\n\t\ttry {\n\t\t\tawait client.value.addType(type);\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-file-result-import-error`, () => i18n.t(\"file-results.import-type-error\"), err);\n\t\t} finally {\n\t\t\tisAddingType.value.delete(type);\n\t\t}\n\t};\n</script>\n\n<template>\n\t<div class=\"fm-file-results\">\n\t\t<SearchResults\n\t\t\t:search-results=\"file.features\"\n\t\t\t:layer-id=\"layerId\"\n\t\t\t:auto-zoom=\"autoZoom\"\n\t\t\t:union-zoom=\"unionZoom\"\n\t\t\t:custom-types=\"file.types\"\n\t\t>\n\t\t\t<template #before>\n\t\t\t\t<template v-if=\"hasViews\">\n\t\t\t\t\t<h3>{{i18n.t(\"file-results.views\")}}</h3>\n\t\t\t\t\t<ul class=\"list-group\">\n\t\t\t\t\t\t<!-- eslint-disable-next-line vue/require-v-for-key -->\n\t\t\t\t\t\t<li v-for=\"view in file.views\" class=\"list-group-item\">\n\t\t\t\t\t\t\t<span class=\"text-break\">\n\t\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"showView(view)\">{{view.name}}</a>\n\t\t\t\t\t\t\t\t{{\" \"}}\n\t\t\t\t\t\t\t\t<span class=\"result-type\">({{i18n.t(\"file-results.view\")}})</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<template v-if=\"isAddingView.has(view)\">\n\t\t\t\t\t\t\t\t<div class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template v-else-if=\"client.padData && client.writable == 2 && !existingViews.get(view)\">\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\t@click=\"addView(view)\"\n\t\t\t\t\t\t\t\t\tv-tooltip.right=\"i18n.t('file-results.add-view-tooltip')\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon icon=\"plus\" :alt=\"i18n.t('file-results.add-view-alt')\"></Icon>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</template>\n\t\t\t\t<h3 v-if=\"hasViews || hasTypes\">{{i18n.t(\"file-results.markers-lines\")}}</h3>\n\t\t\t</template>\n\n\t\t\t<template #after>\n\t\t\t\t<template v-if=\"hasTypes\">\n\t\t\t\t\t<h3>{{i18n.t(\"file-results.types\")}}</h3>\n\t\t\t\t\t<ul class=\"list-group\">\n\t\t\t\t\t\t<!-- eslint-disable-next-line vue/require-v-for-key -->\n\t\t\t\t\t\t<li v-for=\"type in file.types\" class=\"list-group-item\">\n\t\t\t\t\t\t\t<span class=\"text-break\">\n\t\t\t\t\t\t\t\t{{type.name}}\n\t\t\t\t\t\t\t\t{{\" \"}}\n\t\t\t\t\t\t\t\t<span class=\"result-type\">({{i18n.t(\"file-results.type\")}})</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<template v-if=\"isAddingType.has(type)\">\n\t\t\t\t\t\t\t\t<div class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template v-else-if=\"client.padData && client.writable == 2 && !existingTypes.get(type)\">\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\t@click=\"addType(type)\"\n\t\t\t\t\t\t\t\t\tv-tooltip.right=\"i18n.t('file-results.add-type-tooltip')\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon icon=\"plus\" :alt=\"i18n.t('file-results.add-type-alt')\"></Icon>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</template>\n\t\t\t</template>\n\t\t</SearchResults>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-file-results {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\t}\n</style>","<script setup lang=\"ts\">\n\timport Icon from \"../ui/icon.vue\";\n\timport { find, getCurrentLanguage, getElevationForPoint, isSearchId, parseUrlQuery } from \"facilmap-utils\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport type { FindOnMapResult, SearchResult } from \"facilmap-types\";\n\timport SearchResults from \"../search-results/search-results.vue\";\n\timport { flyTo, getZoomDestinationForMapResult, getZoomDestinationForResults, getZoomDestinationForSearchResult, normalizeZoomDestination, openSpecialQuery } from \"../../utils/zoom\";\n\timport { Util } from \"leaflet\";\n\timport { isMapResult } from \"../../utils/search\";\n\timport storage from \"../../utils/storage\";\n\timport type { HashQuery } from \"facilmap-leaflet\";\n\timport { type FileResultObject, parseFiles } from \"../../utils/files\";\n\timport FileResults from \"../file-results.vue\";\n\timport { computed, reactive, ref, watch } from \"vue\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { isLanguageExplicit, useI18n } from \"../../utils/i18n\";\n\n\tconst emit = defineEmits<{\n\t\t\"hash-query-change\": [query: HashQuery | undefined];\n\t}>();\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst layerId = Util.stamp(mapContext.value.components.searchResultsLayer);\n\n\tconst searchInput = ref<HTMLInputElement>();\n\n\tconst searchString = ref(\"\");\n\tconst loadingSearchString = ref(\"\");\n\tconst loadedSearchString = ref(\"\");\n\tconst searchCounter = ref(0);\n\n\tconst searchResults = ref<SearchResult[]>();\n\tconst mapResults = ref<FindOnMapResult[]>();\n\tconst fileResult = ref<FileResultObject>();\n\n\tconst zoomDestination = computed(() => getZoomDestinationForResults([\n\t\t...(searchResults.value || []),\n\t\t...(mapResults.value || []),\n\t\t...(fileResult.value?.features || [])\n\t]));\n\n\tconst hashQuery = computed(() => {\n\t\tif (loadedSearchString.value) {\n\t\t\treturn {\n\t\t\t\tquery: loadedSearchString.value,\n\t\t\t\t...(zoomDestination.value && normalizeZoomDestination(mapContext.value.components.map, zoomDestination.value)),\n\t\t\t\tdescription: i18n.t(\"search-form.search-description\", { query: loadedSearchString.value })\n\t\t\t};\n\t\t} else if (loadingSearchString.value)\n\t\t\treturn { query: loadingSearchString.value, description: i18n.t(\"search-form.search-description\", { query: loadedSearchString.value }) };\n\t\telse\n\t\t\treturn undefined;\n\t});\n\n\twatch(hashQuery, (hashQuery: HashQuery | undefined) => {\n\t\temit(\"hash-query-change\", hashQuery);\n\t});\n\n\tfunction setSearchString(query: string) {\n\t\tsearchString.value = query;\n\t}\n\n\tfunction handleSubmit(): void {\n\t\tsearchInput.value?.blur();\n\n\t\tvoid search(storage.autoZoom, storage.zoomToAll);\n\t}\n\n\tasync function search(zoom: boolean, zoomToAll?: boolean, smooth = true): Promise<void> {\n\t\tif (searchString.value != loadedSearchString.value) {\n\t\t\treset();\n\n\t\t\tconst counter = ++searchCounter.value;\n\n\t\t\tif(searchString.value.trim() != \"\") {\n\t\t\t\ttry {\n\t\t\t\t\tif (await openSpecialQuery(searchString.value, context, zoom)) {\n\t\t\t\t\t\tsearchString.value = \"\";\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst query = searchString.value;\n\t\t\t\t\tloadingSearchString.value = searchString.value;\n\n\t\t\t\t\tconst url = parseUrlQuery(query);\n\n\t\t\t\t\tconst [newSearchResults, newMapResults] = await Promise.all([\n\t\t\t\t\t\turl ? (\n\t\t\t\t\t\t\tclient.value.find({ query, loadUrls: true })\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\tmapContext.value.runOperation(async () => await find(query, {\n\t\t\t\t\t\t\t\tlang: isLanguageExplicit() ? getCurrentLanguage() : undefined\n\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t),\n\t\t\t\t\t\tclient.value.padData ? client.value.findOnMap({ query }) : undefined\n\t\t\t\t\t]);\n\n\t\t\t\t\tif (counter != searchCounter.value)\n\t\t\t\t\t\treturn; // Another search has been started in the meantime\n\n\t\t\t\t\tloadingSearchString.value = \"\";\n\t\t\t\t\tloadedSearchString.value = query;\n\n\t\t\t\t\tif(isSearchId(query) && Array.isArray(newSearchResults) && newSearchResults.length > 0 && newSearchResults[0].display_name) {\n\t\t\t\t\t\tsearchString.value = newSearchResults[0].display_name;\n\t\t\t\t\t\tloadedSearchString.value = query;\n\t\t\t\t\t}\n\n\t\t\t\t\tif(typeof newSearchResults == \"string\") {\n\t\t\t\t\t\tsearchResults.value = undefined;\n\t\t\t\t\t\tmapResults.value = undefined;\n\t\t\t\t\t\tfileResult.value = await mapContext.value.runOperation(async () => await parseFiles([ newSearchResults ]));\n\t\t\t\t\t\tmapContext.value.components.searchResultsLayer.setResults(fileResult.value.features);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst reactiveResults = reactive(newSearchResults);\n\t\t\t\t\t\tsearchResults.value = reactiveResults;\n\t\t\t\t\t\tmapContext.value.components.searchResultsLayer.setResults(newSearchResults);\n\t\t\t\t\t\tmapResults.value = newMapResults ?? undefined;\n\t\t\t\t\t\tfileResult.value = undefined;\n\n\t\t\t\t\t\tconst points = newSearchResults.filter((res) => (res.lon && res.lat));\n\t\t\t\t\t\tif(points.length > 0) {\n\t\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\t\tconst elevations = await Promise.all(points.map(async (point) => {\n\t\t\t\t\t\t\t\t\treturn await getElevationForPoint({ lat: Number(point.lat), lon: Number(point.lon) });\n\t\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\t\televations.forEach((elevation, i) => {\n\t\t\t\t\t\t\t\t\treactiveResults[i].elevation = elevation;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t})().catch((err) => {\n\t\t\t\t\t\t\t\tconsole.warn(\"Error fetching search result elevations\", err);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch(err) {\n\t\t\t\t\ttoasts.showErrorToast(`fm${context.id}-search-form-error`, () => i18n.t(\"search-form.search-error\"), err);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (zoomToAll || (zoomToAll == null && (searchResults.value?.length ?? 0) + (mapResults.value?.length ?? 0) > 1)) {\n\t\t\tif (zoom)\n\t\t\t\tzoomToAllResults(smooth);\n\t\t} else if (mapResults.value && mapResults.value.length > 0 && (mapResults.value[0].similarity == 1 || (!searchResults.value || searchResults.value.length == 0))) {\n\t\t\tmapContext.value.components.selectionHandler.setSelectedItems([{ type: mapResults.value[0].kind, id: mapResults.value[0].id }])\n\t\t\tif (zoom)\n\t\t\t\tzoomToResult(mapResults.value[0], smooth);\n\t\t} else if (searchResults.value && searchResults.value.length > 0) {\n\t\t\tmapContext.value.components.selectionHandler.setSelectedItems([{ type: \"searchResult\", result: searchResults.value[0], layerId }]);\n\t\t\tif (zoom)\n\t\t\t\tzoomToResult(searchResults.value[0], smooth);\n\t\t} else if (fileResult.value) {\n\t\t\tif (zoom)\n\t\t\t\tzoomToAllResults(smooth);\n\t\t}\n\t}\n\n\tfunction reset(): void {\n\t\tsearchCounter.value++;\n\n\t\tmapContext.value.components.selectionHandler.setSelectedItems(mapContext.value.selection.filter((item) => item.type != \"searchResult\" || item.layerId != layerId));\n\t\ttoasts.hideToast(`fm${context.id}-search-form-error`);\n\t\tloadingSearchString.value = \"\";\n\t\tloadedSearchString.value = \"\";\n\t\tsearchResults.value = undefined;\n\t\tmapResults.value = undefined;\n\t\tfileResult.value = undefined;\n\t\tmapContext.value.components.searchResultsLayer.setResults([]);\n\t};\n\n\tfunction zoomToResult(result: SearchResult | FindOnMapResult, smooth = true): void {\n\t\tconst dest = isMapResult(result) ? getZoomDestinationForMapResult(result) : getZoomDestinationForSearchResult(result);\n\t\tif (dest)\n\t\t\tflyTo(mapContext.value.components.map, dest, smooth);\n\t}\n\n\tfunction zoomToAllResults(smooth = true): void {\n\t\tif (zoomDestination.value)\n\t\t\tflyTo(mapContext.value.components.map, zoomDestination.value, smooth);\n\t}\n\n\tdefineExpose({\n\t\tsetSearchString,\n\t\tsearch\n\t});\n</script>\n\n<template>\n\t<div class=\"fm-search-form\">\n\t\t<form action=\"javascript:\" @submit.prevent=\"handleSubmit()\">\n\t\t\t<div class=\"input-group\">\n\t\t\t\t<input type=\"search\" class=\"form-control fm-autofocus\" v-model=\"searchString\" ref=\"searchInput\" />\n\t\t\t\t<button\n\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t>\n\t\t\t\t\t<Icon icon=\"search\" :alt=\"i18n.t('search-form.search-alt')\"></Icon>\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"searchResults || mapResults || fileResult\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t@click=\"reset()\"\n\t\t\t\t>\n\t\t\t\t\t<Icon icon=\"remove\" :alt=\"i18n.t('search-form.clear-alt')\"></Icon>\n\t\t\t\t</button>\n\t\t\t\t<DropdownMenu noWrapper>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t@click.capture.stop.prevent=\"storage.autoZoom = !storage.autoZoom\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon :icon=\"storage.autoZoom ? 'check' : 'unchecked'\"></Icon> {{i18n.t(\"search-form.auto-zoom\")}}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t@click.capture.stop.prevent=\"storage.zoomToAll = !storage.zoomToAll\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon :icon=\"storage.zoomToAll ? 'check' : 'unchecked'\"></Icon> {{i18n.t(\"search-form.zoom-to-all\")}}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</DropdownMenu>\n\t\t\t</div>\n\t\t</form>\n\n\t\t<FileResults\n\t\t\tv-if=\"fileResult\"\n\t\t\t:file=\"fileResult\"\n\t\t\t:auto-zoom=\"storage.autoZoom\"\n\t\t\t:union-zoom=\"storage.zoomToAll\"\n\t\t\t:layer-id=\"layerId\"\n\t\t/>\n\t\t<SearchResults\n\t\t\tv-else-if=\"searchResults || mapResults\"\n\t\t\t:search-results=\"searchResults\"\n\t\t\t:map-results=\"mapResults\"\n\t\t\t:auto-zoom=\"storage.autoZoom\"\n\t\t\t:union-zoom=\"storage.zoomToAll\"\n\t\t\t:layer-id=\"layerId\"\n\t\t></SearchResults>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-search-form {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\n\t\tfieldset {\n\t\t\tmargin-bottom: 0;\n\t\t}\n\n\t\t.fm-search-results {\n\t\t\tmargin-top: 0.5rem;\n\t\t}\n\n\t\t.fm-search-box-collapse-point {\n\t\t\t// Set min-height to one list group item\n\t\t\tmin-height: calc(/* line-height */ 1.5rem + /* list-group-item padding */ 2 * 7px + /* list-group-item border */ 2 * 1px);\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport SearchForm from \"./search-form.vue\";\n\timport { Util } from \"leaflet\";\n\timport type { HashQuery } from \"facilmap-leaflet\";\n\timport { readonly, ref, toRef } from \"vue\";\n\timport { useEventListener } from \"../../utils/utils\";\n\timport SearchBoxTab from \"../search-box/search-box-tab.vue\";\n\timport { injectContextRequired, requireMapContext, requireSearchBoxContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport type { WritableSearchFormTabContext } from \"../facil-map-context-provider/search-form-tab-context\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst searchBoxContext = requireSearchBoxContext(context);\n\tconst i18n = useI18n();\n\n\tconst searchForm = ref<InstanceType<typeof SearchForm>>();\n\n\tconst hashQuery = ref<HashQuery | undefined>(undefined);\n\n\tuseEventListener(mapContext, \"open-selection\", handleOpenSelection);\n\n\tfunction handleOpenSelection(): void {\n\t\tconst layerId = Util.stamp(mapContext.value.components.searchResultsLayer);\n\t\tif (mapContext.value.selection.some((item) => item.type == \"searchResult\" && item.layerId == layerId))\n\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-search-form-tab`, { expand: true });\n\t}\n\n\tconst searchFormTabContext: WritableSearchFormTabContext = {\n\t\tasync setQuery(query, zoom = false, smooth = true, autofocus = false): Promise<void> {\n\t\t\tsearchForm.value!.setSearchString(query);\n\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-search-form-tab`, { expand: !!query, autofocus });\n\t\t\tawait searchForm.value!.search(zoom, undefined, smooth);\n\t\t}\n\t};\n\n\tcontext.provideComponent(\"searchFormTab\", toRef(readonly(searchFormTabContext)));\n</script>\n\n<template>\n\t<SearchBoxTab\n\t\t:id=\"`fm${context.id}-search-form-tab`\"\n\t\t:title=\"i18n.t('search-form-tab.tab-label')\"\n\t\t:hashQuery=\"hashQuery\"\n\t\tclass=\"fm-search-form-tab\"\n\t>\n\t\t<SearchForm ref=\"searchForm\" @hash-query-change=\"hashQuery = $event\"></SearchForm>\n\t</SearchBoxTab>\n</template>\n\n<style lang=\"scss\">\n\t.fm-search-form-tab.fm-search-form-tab.fm-search-form-tab {\n\t\tpadding: 0.5rem;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\n\t\t.input-group {\n\t\t\tposition: static;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport type { ID, Type } from \"facilmap-types\";\n\timport EditTypeDialog from \"./edit-type-dialog/edit-type-dialog.vue\";\n\timport { computed, ref, watchEffect } from \"vue\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport { showConfirm } from \"./ui/alert.vue\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { injectContextRequired, requireClientContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport DropdownMenu from \"./ui/dropdown-menu.vue\";\n\timport { formatTypeName, getOrderedTypes } from \"facilmap-utils\";\n\timport Draggable from \"vuedraggable\";\n\timport Icon from \"./ui/icon.vue\";\n\timport { useI18n } from \"../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst isMoving = ref<ID>();\n\tconst isDeleting = ref<Record<ID, boolean>>({ });\n\tconst editDialogTypeId = ref<ID | \"createMarkerType\" | \"createLineType\">();\n\n\tconst isBusy = computed(() => Object.values(isDeleting.value).some((v) => v) || isMoving.value != null);\n\n\tasync function deleteType(type: Type): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-manage-types-delete-${type.id}`);\n\t\tisDeleting.value[type.id] = true;\n\n\t\ttry {\n\t\t\tif (!await showConfirm({\n\t\t\t\ttitle: i18n.t(\"manage-types-dialog.delete-title\"),\n\t\t\t\tmessage: i18n.t(\"manage-types-dialog.delete-message\", { typeName: formatTypeName(type.name) }),\n\t\t\t\tvariant: \"danger\",\n\t\t\t\tokLabel: i18n.t(\"manage-types-dialog.delete-ok\")\n\t\t\t})) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait client.value.deleteType({ id: type.id });\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-manage-types-delete-${type.id}`, () => i18n.t(\"manage-types-dialog.delete-error\", { typeName: formatTypeName(type.name) }), err);\n\t\t} finally {\n\t\t\tdelete isDeleting.value[type.id];\n\t\t}\n\t}\n\n\tconst orderedTypes = ref<Type[]>([]);\n\twatchEffect(() => {\n\t\tif (isMoving.value == null) {\n\t\t\torderedTypes.value = getOrderedTypes(client.value.types);\n\t\t}\n\t});\n\n\tconst handleDrag = toasts.toastErrors(async (e: any) => {\n\t\tif (e.moved) {\n\t\t\tisMoving.value = e.moved.element.id;\n\n\t\t\ttry {\n\t\t\t\t// This handler is called when orderedTypes is already reordered\n\t\t\t\tconst newIdx = e.moved.newIndex === 0 ? 0 : (orderedTypes.value[e.moved.newIndex - 1].idx + 1);\n\t\t\t\tawait client.value.editType({\n\t\t\t\t\tid: e.moved.element.id,\n\t\t\t\t\tidx: newIdx\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tisMoving.value = undefined;\n\t\t\t}\n\t\t}\n\t});\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('manage-types-dialog.title')\"\n\t\t:isBusy=\"isBusy\"\n\t\tsize=\"lg\"\n\t\tclass=\"fm-manage-types\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<table class=\"table table-striped table-hover\">\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th>{{i18n.t(\"manage-types-dialog.name\")}}</th>\n\t\t\t\t\t<th>{{i18n.t(\"manage-types-dialog.type\")}}</th>\n\t\t\t\t\t<th>{{i18n.t(\"manage-types-dialog.edit\")}}</th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<Draggable\n\t\t\t\tv-model=\"orderedTypes\"\n\t\t\t\ttag=\"tbody\"\n\t\t\t\thandle=\".fm-drag-handle\"\n\t\t\t\titemKey=\"id\"\n\t\t\t\t@change=\"handleDrag\"\n\t\t\t>\n\t\t\t\t<template #item=\"{ element: type }\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td class=\"text-break\">{{formatTypeName(type.name)}}</td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t{{type.type === \"marker\" ? i18n.t(\"manage-types-dialog.type-marker\") : i18n.t(\"manage-types-dialog.type-line\")}}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td class=\"td-buttons\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t\t\t\t:disabled=\"isDeleting[type.id]\"\n\t\t\t\t\t\t\t\t@click=\"editDialogTypeId = type.id\"\n\t\t\t\t\t\t\t>{{i18n.t(\"manage-types-dialog.edit-button\")}}</button>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t@click=\"deleteType(type)\"\n\t\t\t\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t\t\t\t:disabled=\"isDeleting[type.id] || isMoving != null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div v-if=\"isDeleting[type.id]\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t\t{{i18n.t(\"manage-types-dialog.delete-button\")}}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"btn btn-secondary fm-drag-handle\"\n\t\t\t\t\t\t\t\t:disabled=\"isDeleting[type.id] || isMoving != null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div v-if=\"isMoving === type.id\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t\t<Icon v-else icon=\"resize-vertical\" :alt=\"i18n.t('manage-types-dialog.reorder-alt')\"></Icon>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</template>\n\t\t\t</Draggable>\n\t\t\t<tfoot>\n\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=\"3\">\n\t\t\t\t\t\t<DropdownMenu :label=\"i18n.t('manage-types-dialog.create')\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t\t\t@click=\"editDialogTypeId = 'createMarkerType'\"\n\t\t\t\t\t\t\t\t>{{i18n.t(\"manage-types-dialog.marker-type\")}}</a>\n\t\t\t\t\t\t\t</li>\n\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t\t\t\t\t\t@click=\"editDialogTypeId = 'createLineType'\"\n\t\t\t\t\t\t\t\t>{{i18n.t(\"manage-types-dialog.line-type\")}}</a>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</tfoot>\n\t\t</table>\n\n\t\t<EditTypeDialog\n\t\t\tv-if=\"editDialogTypeId\"\n\t\t\t:typeId=\"editDialogTypeId\"\n\t\t\t@hidden=\"editDialogTypeId = undefined\"\n\t\t></EditTypeDialog>\n\t</ModalDialog>\n</template>","<script setup lang=\"ts\">\n\timport type { Type } from \"facilmap-types\";\n\timport { drawLine, drawMarker } from \"../../utils/draw\";\n\timport { computed, ref } from \"vue\";\n\timport ManageTypesDialog from \"../manage-types-dialog.vue\";\n\timport vLinkDisabled from \"../../utils/link-disabled\";\n\timport { useToasts } from \"../ui/toasts/toasts.vue\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { formatTypeName, getOrderedTypes, sleep } from \"facilmap-utils\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst emit = defineEmits<{\n\t\t\"hide-sidebar\": [];\n\t}>();\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst dialog = ref<\n\t\t| \"manage-types\"\n\t>();\n\n\tasync function addObject(type: Type): Promise<void> {\n\t\tif(type.type == \"marker\") {\n\t\t\tawait sleep(0); // For some reason this is necessary for the dropdown to close itself\n\t\t\tdrawMarker(type, context, toasts);\n\t\t} else if(type.type == \"line\") {\n\t\t\tawait drawLine(type, context, toasts);\n\t\t}\n\t}\n\n\tconst orderedTypes = computed(() => getOrderedTypes(client.value.types));\n</script>\n\n<template>\n\t<DropdownMenu\n\t\ttag=\"li\"\n\t\tclass=\"nav-item\"\n\t\tisLink\n\t\t:isDisabled=\"mapContext.interaction\"\n\t\tbuttonClass=\"nav-link\"\n\t\tmenuClass=\"dropdown-menu-end\"\n\t\t:label=\"i18n.t('toolbox-add-dropdown.label')\"\n\t>\n\t\t<li v-for=\"type in orderedTypes\" :key=\"type.id\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\tv-link-disabled=\"mapContext.interaction\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"addObject(type); emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{formatTypeName(type.name)}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"client.writable == 2\">\n\t\t\t<hr class=\"dropdown-divider\">\n\t\t</li>\n\n\t\t<li v-if=\"client.writable == 2\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\tv-link-disabled=\"!!mapContext.interaction\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'manage-types'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-add-dropdown.manage-types\")}}</a>\n\t\t</li>\n\t</DropdownMenu>\n\n\t<ManageTypesDialog\n\t\tv-if=\"dialog === 'manage-types' && client.padData\"\n\t\t@hidden=\"dialog = undefined\"\n\t></ManageTypesDialog>\n</template>","<script setup lang=\"ts\">\n\timport storage, { type Bookmark } from \"../utils/storage\";\n\timport Icon from \"./ui/icon.vue\";\n\timport Draggable from \"vuedraggable\";\n\timport { computed } from \"vue\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { injectContextRequired, requireClientContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { useI18n } from \"../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst isBookmarked = computed(() => {\n\t\treturn !!client.value.padId && storage.bookmarks.some((bookmark) => bookmark.id == client.value.padId);\n\t});\n\n\tfunction deleteBookmark(bookmark: Bookmark): void {\n\t\tconst index = storage.bookmarks.indexOf(bookmark);\n\t\tif (index != -1)\n\t\t\tstorage.bookmarks.splice(index, 1);\n\t}\n\n\tfunction addBookmark(): void {\n\t\tstorage.bookmarks.push({ id: client.value.padId!, padId: client.value.padData!.id, name: client.value.padData!.name });\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('manage-bookmarks-dialog.title')\"\n\t\tsize=\"lg\"\n\t\tclass=\"fm-manage-bookmarks\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<p>{{i18n.t(\"manage-bookmarks-dialog.introduction\")}}</p>\n\t\t<table class=\"table table-striped table-hover\">\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th>{{i18n.t(\"manage-bookmarks-dialog.map-id\")}}</th>\n\t\t\t\t\t<th>{{i18n.t(\"manage-bookmarks-dialog.name\")}}</th>\n\t\t\t\t\t<th></th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<Draggable\n\t\t\t\tv-model=\"storage.bookmarks\"\n\t\t\t\ttag=\"tbody\"\n\t\t\t\thandle=\".fm-drag-handle\"\n\t\t\t\t:itemKey=\"(bookmark: any) => storage.bookmarks.indexOf(bookmark)\"\n\t\t\t>\n\t\t\t\t<template #item=\"{ element: bookmark }\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td class=\"align-middle text-break\" :class=\"{ 'font-weight-bold': bookmark.id == client.padId }\">\n\t\t\t\t\t\t\t{{bookmark.id}}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td class=\"align-middle\">\n\t\t\t\t\t\t\t<input class=\"form-control\" v-model=\"bookmark.customName\" :placeholder=\"bookmark.name\" />\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td class=\"align-middle td-buttons text-right\">\n\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" @click=\"deleteBookmark(bookmark)\">{{i18n.t(\"manage-bookmarks-dialog.delete\")}}</button>\n\t\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary fm-drag-handle\"><Icon icon=\"resize-vertical\" :alt=\"i18n.t('manage-bookmarks-dialog.reorder-alt')\"></Icon></button>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</template>\n\t\t\t</Draggable>\n\t\t\t<tfoot v-if=\"client.padData && !isBookmarked\">\n\t\t\t\t<tr>\n\t\t\t\t\t<td colspan=\"3\">\n\t\t\t\t\t\t<button type=\"button\" class=\"btn btn-secondary\" @click=\"addBookmark()\">{{i18n.t(\"manage-bookmarks-dialog.bookmark-current\")}}</button>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</tfoot>\n\t\t</table>\n\t</ModalDialog>\n</template>","<script setup lang=\"ts\">\n\timport { range } from \"lodash-es\";\n\timport { computed } from \"vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\tpages: number;\n\t\tmodelValue: number;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:modelValue\": [page: number];\n\t}>();\n\n\tfunction handleClick(page: number): void {\n\t\temit(\"update:modelValue\", page);\n\t}\n\n\tconst isPrevDisabled = computed(() => props.modelValue === 0);\n\tconst isNextDisabled = computed(() => props.modelValue === props.pages - 1);\n\tconst pagesFrom = computed(() => Math.max(0, Math.min(props.modelValue - 2, props.pages - 3)));\n\tconst pagesTo = computed(() => Math.min(props.pages - 1, Math.max(props.modelValue + 2, 2)));\n\tconst pageLinks = computed(() => range(pagesFrom.value, pagesTo.value + 1));\n\tconst showEllipsisBefore = computed(() => pagesFrom.value > 0);\n\tconst showEllipsisAfter = computed(() => pagesTo.value < props.pages - 1);\n</script>\n\n<template>\n\t<ul class=\"pagination justify-content-center\">\n\t\t<li class=\"page-item\" :class=\"{ disabled: isPrevDisabled }\">\n\t\t\t<a\n\t\t\t\t:href=\"isPrevDisabled ? undefined : 'javascript:'\"\n\t\t\t\tclass=\"page-link\"\n\t\t\t\t:aria-label=\"i18n.t('pagination.first-label')\"\n\t\t\t\t@click=\"handleClick(0)\"\n\t\t\t>\n\t\t\t\t<span aria-hidden=\"true\">«</span>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li class=\"page-item\" :class=\"{ disabled: isPrevDisabled }\">\n\t\t\t<a\n\t\t\t\t:href=\"isPrevDisabled ? undefined : 'javascript:'\"\n\t\t\t\tclass=\"page-link\"\n\t\t\t\t:aria-label=\"i18n.t('pagination.previous-label')\"\n\t\t\t\t@click=\"handleClick(props.modelValue - 1)\"\n\t\t\t>\n\t\t\t\t<span aria-hidden=\"true\">‹</span>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li v-if=\"showEllipsisBefore\" class=\"page-item\">\n\t\t\t<span class=\"page-link\">…</span>\n\t\t</li>\n\n\t\t<template v-for=\"page in pageLinks\" :key=\"page\">\n\t\t\t<li class=\"page-item\" :class=\"{ active: page === props.modelValue }\">\n\t\t\t\t<a href=\"javascript:\" class=\"page-link\" @click=\"handleClick(page)\">{{page + 1}}</a>\n\t\t\t</li>\n\t\t</template>\n\n\t\t<li v-if=\"showEllipsisAfter\" class=\"page-item\">\n\t\t\t<span class=\"page-link\">…</span>\n\t\t</li>\n\n\t\t<li class=\"page-item\" :class=\"{ disabled: isNextDisabled }\">\n\t\t\t<a\n\t\t\t\t:href=\"isNextDisabled ? undefined : 'javascript:'\"\n\t\t\t\tclass=\"page-link\"\n\t\t\t\t:aria-label=\"i18n.t('pagination.next-label')\"\n\t\t\t\t@click=\"handleClick(props.modelValue + 1)\"\n\t\t\t>\n\t\t\t\t<span aria-hidden=\"true\">›</span>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li class=\"page-item\" :class=\"{ disabled: isNextDisabled }\">\n\t\t\t<a\n\t\t\t\t:href=\"isNextDisabled ? undefined : 'javascript:'\"\n\t\t\t\tclass=\"page-link\"\n\t\t\t\t:aria-label=\"i18n.t('pagination.last-label')\"\n\t\t\t\t@click=\"handleClick(pages - 1)\"\n\t\t\t>\n\t\t\t\t<span aria-hidden=\"true\">»</span>\n\t\t\t</a>\n\t\t</li>\n\t</ul>\n</template>","<script setup lang=\"ts\">\n\timport Icon from \"./ui/icon.vue\";\n\timport type { FindPadsResult } from \"facilmap-types\";\n\timport { computed, ref } from \"vue\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport Pagination from \"./ui/pagination.vue\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { getUniqueId } from \"../utils/utils\";\n\timport ValidatedForm from \"./ui/validated-form/validated-form.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport type { FacilMapContext } from \"./facil-map-context-provider/facil-map-context\";\n\timport ValidatedField from \"./ui/validated-form/validated-field.vue\";\n\timport { parsePadUrl } from \"facilmap-utils\";\n\timport { useI18n } from \"../utils/i18n\";\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst ITEMS_PER_PAGE = 20;\n\n\tfunction parsePadId(val: string, context: FacilMapContext): { padId: string; hash: string } | undefined {\n\t\tconst url = val.startsWith(context.baseUrl) ? val : `${context.baseUrl}${val}`;\n\t\treturn parsePadUrl(url, context.baseUrl);\n\t}\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\n\tconst id = getUniqueId(\"fm-open-map\");\n\n\tconst padId = ref(\"\");\n\tconst searchQuery = ref(\"\");\n\tconst submittedSearchQuery = ref<string>();\n\tconst isSearching = ref(false);\n\tconst results = ref<FindPadsResult[]>([]);\n\tconst pages = ref(0);\n\tconst activePage = ref(0);\n\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\tconst openFormRef = ref<InstanceType<typeof ValidatedForm>>();\n\n\tconst url = computed(() => {\n\t\tconst parsed = parsePadId(padId.value, context);\n\t\tif (parsed) {\n\t\t\treturn context.baseUrl + encodeURIComponent(parsed.padId) + parsed.hash;\n\t\t}\n\t});\n\n\tfunction handleSubmit(): void {\n\t\tconst parsed = parsePadId(padId.value, context);\n\t\tif (parsed) {\n\t\t\tclient.value.openPad(parsed.padId);\n\t\t\tmodalRef.value!.modal.hide();\n\n\t\t\tsetTimeout(() => {\n\t\t\t\t// TODO: This is called too early\n\t\t\t\tmapContext.value.components.hashHandler.applyHash(parsed.hash);\n\t\t\t}, 0);\n\t\t}\n\t}\n\n\tfunction openResult(result: FindPadsResult): void {\n\t\tclient.value.openPad(result.id);\n\t\tmodalRef.value!.modal.hide();\n\n\t\tsetTimeout(() => {\n\t\t\t// TODO: This is called too early\n\t\t\tmapContext.value.components.hashHandler.applyHash(\"#\");\n\t\t}, 0);\n\t}\n\n\tasync function search(query: string, page: number): Promise<void> {\n\t\tif (!query) {\n\t\t\tsubmittedSearchQuery.value = undefined;\n\t\t\tresults.value = [];\n\t\t\tpages.value = 0;\n\t\t\tactivePage.value = 0;\n\t\t\treturn;\n\t\t}\n\n\t\tisSearching.value = true;\n\t\ttoasts.hideToast(`fm${context.id}-open-map-search-error`);\n\n\t\ttry {\n\t\t\tconst newResults = await client.value.findPads({\n\t\t\t\tquery,\n\t\t\t\tstart: page * ITEMS_PER_PAGE,\n\t\t\t\tlimit: ITEMS_PER_PAGE\n\t\t\t});\n\t\t\tsubmittedSearchQuery.value = query;\n\t\t\tactivePage.value = page;\n\t\t\tresults.value = newResults.results;\n\t\t\tpages.value = Math.ceil(newResults.totalLength / ITEMS_PER_PAGE);\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-open-map-search-error`, () => i18n.t(\"open-map-dialog.find-pads-error\"), err);\n\t\t} finally {\n\t\t\tisSearching.value = false;\n\t\t}\n\t}\n\n\tfunction validatePadIdFormat(padId: string) {\n\t\tconst parsed = parsePadId(padId, context);\n\n\t\tif (!parsed) {\n\t\t\treturn i18n.t(\"open-map-dialog.map-id-format-error\");\n\t\t}\n\t}\n\n\tasync function validatePadExistence(padId: string) {\n\t\tconst parsed = parsePadId(padId, context);\n\n\t\tif (parsed) {\n\t\t\tconst padInfo = await client.value.getPad({ padId: parsed.padId });\n\t\t\tif (!padInfo) {\n\t\t\t\treturn i18n.t(\"open-map-dialog.map-not-found-error\");\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('open-map-dialog.title')\"\n\t\tsize=\"lg\"\n\t\tclass=\"fm-open-map\"\n\t\tref=\"modalRef\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<p>{{i18n.t(\"open-map-dialog.introduction\")}}</p>\n\t\t<ValidatedField\n\t\t\t:value=\"padId\"\n\t\t\t:validators=\"padId ? [\n\t\t\t\tvalidatePadIdFormat,\n\t\t\t\tvalidatePadExistence\n\t\t\t] : []\"\n\t\t\t:reportValid=\"!!padId\"\n\t\t\t:debounceMs=\"300\"\n\t\t\tclass=\"input-group has-validation position-relative\"\n\t\t>\n\t\t\t<template #default=\"slotProps\">\n\t\t\t\t<input\n\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\tv-model=\"padId\"\n\t\t\t\t\t:form=\"`${id}-open-form`\"\n\t\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\t/>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\tclass=\"btn btn-primary\"\n\t\t\t\t\t:disabled=\"!padId\"\n\t\t\t\t\t:form=\"`${id}-open-form`\"\n\t\t\t\t>\n\t\t\t\t\t<div v-if=\"openFormRef?.formData.isValidating\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t{{i18n.t(\"open-map-dialog.open-map-by-id-button\")}}\n\t\t\t\t</button>\n\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t</ValidatedField>\n\n\t\t<hr/>\n\n\t\t<h4>{{i18n.t(\"open-map-dialog.search-public-maps\")}}</h4>\n\n\t\t<div class=\"input-group\">\n\t\t\t<input\n\t\t\t\tclass=\"form-control\"\n\t\t\t\ttype=\"search\"\n\t\t\t\tv-model=\"searchQuery\"\n\t\t\t\tplaceholder=\"Search term\"\n\t\t\t\t:form=\"`${id}-search-form`\"\n\t\t\t/>\n\t\t\t<button\n\t\t\t\ttype=\"submit\"\n\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t:disabled=\"isSearching\"\n\t\t\t\t:form=\"`${id}-search-form`\"\n\t\t\t>\n\t\t\t\t<div v-if=\"isSearching\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t<Icon v-else icon=\"search\" :alt=\"i18n.t('open-map-dialog.search-alt')\"></Icon>\n\t\t\t</button>\n\t\t</div>\n\n\t\t<div v-if=\"submittedSearchQuery && results.length == 0\" class=\"alert alert-danger mt-2\">\n\t\t\t{{i18n.t(\"open-map-dialog.no-maps-found\")}}\n\t\t</div>\n\n\t\t<template v-if=\"submittedSearchQuery && results.length > 0\">\n\t\t\t<div class=\"table-wrapper\">\n\t\t\t\t<table class=\"table table-hover table-striped\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th>{{i18n.t(\"open-map-dialog.name\")}}</th>\n\t\t\t\t\t\t\t<th>{{i18n.t(\"open-map-dialog.description\")}}</th>\n\t\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<tr v-for=\"result in results\" :key=\"result.id\">\n\t\t\t\t\t\t\t<td>{{result.name}}</td>\n\t\t\t\t\t\t\t<td>{{result.description}}</td>\n\t\t\t\t\t\t\t<td class=\"td-buttons\">\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t\t\t\t\t:href=\"context.baseUrl + encodeURIComponent(result.id)\"\n\t\t\t\t\t\t\t\t\t@click.exact.prevent=\"openResult(result)\"\n\t\t\t\t\t\t\t\t>{{i18n.t(\"open-map-dialog.open-map-by-search-button\")}}</a>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t</div>\n\n\t\t\t<Pagination\n\t\t\t\tv-if=\"pages > 1\"\n\t\t\t\t:pages=\"pages\"\n\t\t\t\t:modelValue=\"activePage\"\n\t\t\t\t@update:modelValue=\"search(submittedSearchQuery, $event)\"\n\t\t\t></Pagination>\n\t\t</template>\n\t</ModalDialog>\n\n\t<ValidatedForm\n\t\t:id=\"`${id}-open-form`\"\n\t\tmethod=\"get\"\n\t\t:action=\"url\"\n\t\t@submit.prevent=\"handleSubmit\"\n\t\tref=\"openFormRef\"\n\t></ValidatedForm>\n\n\t<ValidatedForm\n\t\t:id=\"`${id}-search-form`\"\n\t\t@submit.prevent=\"$event.waitUntil(search(searchQuery, 0))\"\n\t\tclass=\"results\"\n\t></ValidatedForm>\n</template>\n\n<style lang=\"scss\">\n\t.fm-open-map {\n\t\t.modal-body {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tmin-height: 0;\n\t\t}\n\n\t\thr {\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.results {\n\t\t\tmin-height: 0;\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\n\t\t\t.alert, .table-wrapper {\n\t\t\t\tmargin-top: 1rem;\n\t\t\t}\n\n\t\t\t.table-wrapper {\n\t\t\t\toverflow: auto;\n\t\t\t\tmin-height: 7rem;\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport PadSettingsDialog from \"../pad-settings-dialog/pad-settings-dialog.vue\";\n\timport storage from \"../../utils/storage\";\n\timport ManageBookmarksDialog from \"../manage-bookmarks-dialog.vue\";\n\timport OpenMapDialog from \"../open-map-dialog.vue\";\n\timport { computed, ref } from \"vue\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { normalizePadName } from \"facilmap-utils\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\t\"hide-sidebar\": [];\n\t}>();\n\n\tconst dialog = ref<\n\t\t| \"open-map\"\n\t\t| \"manage-bookmarks\"\n\t\t| \"create-pad\"\n\t>();\n\n\tconst hash = computed(() => {\n\t\tconst v = mapContext.value;\n\t\treturn v.hash && v.hash != \"#\" ? v.hash : `${v.zoom}/${v.center.lat}/${v.center.lng}`;\n\t});\n\n\tconst isBookmarked = computed(() => {\n\t\treturn !!client.value.padId && storage.bookmarks.some((bookmark) => bookmark.id == client.value.padId);\n\t});\n\n\tfunction addBookmark(): void {\n\t\tstorage.bookmarks.push({ id: client.value.padId!, padId: client.value.padData!.id, name: client.value.padData!.name });\n\t}\n</script>\n\n<template>\n\t<DropdownMenu\n\t\ttag=\"li\"\n\t\tclass=\"nav-item\"\n\t\tisLink\n\t\t:isDisabled=\"mapContext.interaction\"\n\t\tbuttonClass=\"nav-link\"\n\t\tmenuClass=\"dropdown-menu-end\"\n\t\t:label=\"i18n.t('toolbox-collab-maps-dropdown.label')\"\n\t>\n\t\t<li v-for=\"bookmark in storage.bookmarks\" :key=\"bookmark.id\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t:class=\"{ active: bookmark.id == client.padId }\"\n\t\t\t\t:href=\"`${context.baseUrl}${encodeURIComponent(bookmark.id)}#${hash}`\"\n\t\t\t\t@click.exact.prevent=\"client.openPad(bookmark.id); emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{bookmark.customName || normalizePadName(bookmark.name)}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"storage.bookmarks.length > 0\">\n\t\t\t<hr class=\"dropdown-divider\">\n\t\t</li>\n\n\t\t<li v-if=\"client.padData && !isBookmarked\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"addBookmark()\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t('toolbox-collab-maps-dropdown.bookmark', { padName: normalizePadName(client.padData.name) })}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"storage.bookmarks.length > 0\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'manage-bookmarks'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t('toolbox-collab-maps-dropdown.manage-bookmarks')}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"(client.padData && !isBookmarked) || storage.bookmarks.length > 0\">\n\t\t\t<hr class=\"dropdown-divider\">\n\t\t</li>\n\n\t\t<li v-if=\"!client.padId\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'create-pad'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t('toolbox-collab-maps-dropdown.create-map')}}</a>\n\t\t</li>\n\n\t\t<li>\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'open-map'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{client.padId ? i18n.t(\"toolbox-collab-maps-dropdown.open-other-map\") : i18n.t(\"toolbox-collab-maps-dropdown.open-map\")}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"client.padData\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t:href=\"`${context.baseUrl}#${hash}`\"\n\t\t\t\t@click.exact.prevent=\"client.openPad(undefined)\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-collab-maps-dropdown.close-map\", { padName: normalizePadName(client.padData.name) })}}</a>\n\t\t</li>\n\t</DropdownMenu>\n\n\t<OpenMapDialog\n\t\tv-if=\"dialog === 'open-map'\"\n\t\t@hidden=\"dialog = undefined\"\n\t></OpenMapDialog>\n\n\t<ManageBookmarksDialog\n\t\tv-if=\"dialog === 'manage-bookmarks'\"\n\t\t@hidden=\"dialog = undefined\"\n\t></ManageBookmarksDialog>\n\n\t<PadSettingsDialog\n\t\tv-if=\"dialog === 'create-pad'\"\n\t\t@hidden=\"dialog = undefined\"\n\t\t:isCreate=\"true\"\n\t></PadSettingsDialog>\n</template>","<script setup lang=\"ts\">\n\timport { getLayers } from \"facilmap-leaflet\";\n\timport { Util } from \"leaflet\";\n\timport { computed } from \"vue\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { injectContextRequired, requireMapContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { T, useI18n } from \"../utils/i18n\";\n\n\tconst i18n = useI18n();\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst layers = computed(() => {\n\t\tconst { baseLayers, overlays } = getLayers(mapContext.value.components.map);\n\t\treturn [...Object.values(baseLayers), ...Object.values(overlays)].flatMap((layer) => {\n\t\t\tconst attributionHtml = layer.getAttribution?.();\n\t\t\tif (attributionHtml) {\n\t\t\t\treturn [{\n\t\t\t\t\tid: Util.stamp(layer),\n\t\t\t\t\tname: layer.options.fmGetName?.() ?? layer.options.fmName,\n\t\t\t\t\tattributionHtml\n\t\t\t\t}];\n\t\t\t} else {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t});\n\t});\n\n\tconst fmVersion = __FM_VERSION__;\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('about-dialog.header', { version: fmVersion })\"\n\t\tclass=\"fm-about\"\n\t\tsize=\"lg\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<p>\n\t\t\t<T k=\"about-dialog.license-text\">\n\t\t\t\t<template #facilmap>\n\t\t\t\t\t<a href=\"https://github.com/facilmap/facilmap\" target=\"_blank\"><strong>{{i18n.t('about-dialog.license-text-facilmap')}}</strong></a>\n\t\t\t\t</template>\n\t\t\t\t<template #license>\n\t\t\t\t\t<a href=\"https://www.gnu.org/licenses/agpl-3.0.en.html\" target=\"_blank\">{{i18n.t('about-dialog.license-text-license')}}</a>\n\t\t\t\t</template>\n\t\t\t</T>\n\t\t</p>\n\t\t<p>\n\t\t\t<T k=\"about-dialog.issues-text\">\n\t\t\t\t<template #tracker>\n\t\t\t\t\t<a href=\"https://github.com/FacilMap/facilmap/issues\" target=\"_blank\">{{i18n.t('about-dialog.issues-text-tracker')}}</a>\n\t\t\t\t</template>\n\t\t\t</T>\n\t\t</p>\n\n\t\t<p>\n\t\t\t<T k=\"about-dialog.help-text\">\n\t\t\t\t<template #documentation>\n\t\t\t\t\t<a href=\"https://docs.facilmap.org/users/\" target=\"_blank\">{{i18n.t('about-dialog.help-text-documentation')}}</a>\n\t\t\t\t</template>\n\t\t\t\t<template #discussions>\n\t\t\t\t\t<a href=\"https://github.com/FacilMap/facilmap/discussions\" target=\"_blank\">{{i18n.t('about-dialog.help-text-discussions')}}</a>\n\t\t\t\t</template>\n\t\t\t\t<template #chat>\n\t\t\t\t\t<a href=\"https://matrix.to/#/#facilmap:rankenste.in\" target=\"_blank\">{{i18n.t('about-dialog.help-text-chat')}}</a>\n\t\t\t\t</template>\n\t\t\t</T>\n\t\t</p>\n\n\t\t<p><a href=\"https://docs.facilmap.org/users/privacy/\" target=\"_blank\">{{i18n.t('about-dialog.privacy-information')}}</a></p>\n\t\t<h4>{{i18n.t('about-dialog.map-data')}}</h4>\n\t\t<dl class=\"row\">\n\t\t\t<template v-for=\"{ id, name, attributionHtml } in layers\" :key=\"id\">\n\t\t\t\t<dt class=\"col-sm-3\">{{name}}</dt>\n\t\t\t\t<dd class=\"col-sm-9\" v-html=\"attributionHtml\"></dd>\n\t\t\t</template>\n\n\t\t\t<dt class=\"col-sm-3\">{{i18n.t('about-dialog.map-data-search')}}</dt>\n\t\t\t<dd class=\"col-sm-9\"><a href=\"https://nominatim.openstreetmap.org/\" target=\"_blank\">Nominatim</a> / <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">{{i18n.t('about-dialog.attribution-osm-contributors')}}</a></dd>\n\n\t\t\t<dt class=\"col-sm-3\">{{i18n.t('about-dialog.map-data-pois')}}</dt>\n\t\t\t<dd class=\"col-sm-9\"><a href=\"https://overpass-api.de/\" target=\"_blank\">Overpass API</a> / <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">{{i18n.t('about-dialog.attribution-osm-contributors')}}</a></dd>\n\n\t\t\t<dt class=\"col-sm-3\">{{i18n.t('about-dialog.map-data-directions')}}</dt>\n\t\t\t<dd class=\"col-sm-9\"><a href=\"https://www.mapbox.com/api-documentation/#directions\">Mapbox Directions API</a> / <a href=\"https://openrouteservice.org/\">OpenRouteService</a> / <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">{{i18n.t('about-dialog.attribution-osm-contributors')}}</a></dd>\n\n\t\t\t<dt class=\"col-sm-3\">{{i18n.t('about-dialog.map-data-geoip')}}</dt>\n\t\t\t<dd class=\"col-sm-9\">\n\t\t\t\t<T k=\"about-dialog.map-data-geoip-description\">\n\t\t\t\t\t<template #maxmind>\n\t\t\t\t\t\t<a href=\"https://www.maxmind.com\">https://www.maxmind.com</a>\n\t\t\t\t\t</template>\n\t\t\t\t</T>\n\t\t\t</dd>\n\t\t</dl>\n\t\t<h4>{{i18n.t('about-dialog.programs-libraries')}}</h4>\n\t\t<ul>\n\t\t\t<li><a href=\"https://nodejs.org/\" target=\"_blank\">Node.js</a></li>\n\t\t\t<li><a href=\"https://sequelize.org/\" target=\"_blank\">Sequelize</a></li>\n\t\t\t<li><a href=\"https://socket.io/\" target=\"_blank\">socket.io</a></li>\n\t\t\t<li><a href=\"https://www.typescriptlang.org/\" target=\"_blank\">TypeScript</a></li>\n\t\t\t<li><a href=\"https://vuejs.org/\" target=\"_blank\">Vue.js</a></li>\n\t\t\t<li><a href=\"https://vitejs.dev/\" target=\"_blank\">Vite</a></li>\n\t\t\t<li><a href=\"https://getbootstrap.com/\" target=\"_blank\">Bootstrap</a></li>\n\t\t\t<li><a href=\"https://leafletjs.com/\" target=\"_blank\">Leaflet</a></li>\n\t\t\t<li><a href=\"http://project-osrm.org/\" target=\"_blank\">OSRM</a></li>\n\t\t\t<li><a href=\"https://openrouteservice.org/\" target=\"_blank\">OpenRouteService</a></li>\n\t\t\t<li><a href=\"https://nominatim.openstreetmap.org/\" target=\"_blank\">Nominatim</a></li>\n\t\t\t<li><a href=\"https://github.com/joewalnes/filtrex\" target=\"_blank\">Filtrex</a></li>\n\t\t\t<li><a href=\"https://github.com/chjj/marked\" target=\"_blank\">Marked</a></li>\n\t\t\t<li><a href=\"https://github.com/cure53/DOMPurify\" target=\"_blank\">DOMPurify</a></li>\n\t\t\t<li><a href=\"https://expressjs.com/\" target=\"_blank\">Express</a></li>\n\t\t\t<li><a href=\"https://vuepress.vuejs.org/\" target=\"_blank\">Vuepress</a></li>\n\t\t\t<li><a href=\"https://www.i18next.com/\" target=\"_blank\">I18next</a></li>\n\t\t</ul>\n\t\t<h4>{{i18n.t('about-dialog.icons')}}</h4>\n\t\t<ul>\n\t\t\t<li><a href=\"https://github.com/twain47/Open-SVG-Map-Icons/\" target=\"_blank\">Open SVG Map Icons</a></li>\n\t\t\t<li><a href=\"https://glyphicons.com/\" target=\"_blank\">Glyphicons</a></li>\n\t\t\t<li><a href=\"https://zavoloklom.github.io/material-design-iconic-font/index.html\" target=\"_blank\">Material Design Iconic Font</a></li>\n\t\t\t<li><a href=\"https://fontawesome.com/\" target=\"_blank\">Font Awesome</a></li>\n\t\t</ul>\n\t</ModalDialog>\n</template>\n\n<style lang=\"scss\">\n\t.fm-about {\n\t\tul {\n\t\t\tmargin-left: 0;\n\t\t\tpadding-left: 0;\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: repeat(auto-fit, 180px);\n\t\t\tgap: 5px;\n\n\t\t\tli {\n\t\t\t\tborder: 1px solid rgba(0,0,0,.125);\n\t\t\t\tdisplay: flex;\n\n\t\t\t\ta {\n\t\t\t\t\tflex-grow: 1;\n\t\t\t\t\tpadding: 5px 10px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport AboutDialog from \"../about-dialog.vue\";\n\timport { ref } from \"vue\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\timport { injectContextRequired } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport Icon from \"../ui/icon.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\t\"hide-sidebar\": [];\n\t}>();\n\n\tconst dialog = ref<\n\t\t| \"about\"\n\t>();\n</script>\n\n<template>\n\t<DropdownMenu\n\t\ttag=\"li\"\n\t\tclass=\"nav-item\"\n\t\tisLink\n\t\tbuttonClass=\"nav-link\"\n\t\tmenuClass=\"dropdown-menu-end\"\n\t\t:label=\"i18n.t('toolbox-help-dropdown.label')\"\n\t>\n\t\t<li>\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item fm-toolbox-new-window-item\"\n\t\t\t\thref=\"https://docs.facilmap.org/users/\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>\n\t\t\t\t<span>{{i18n.t(\"toolbox-help-dropdown.documentation\")}}</span>\n\t\t\t\t<Icon icon=\"new-window\"></Icon>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li>\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item fm-toolbox-new-window-item\"\n\t\t\t\thref=\"https://matrix.to/#/#facilmap:rankenste.in\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>\n\t\t\t\t<span>{{i18n.t(\"toolbox-help-dropdown.matrix-chat\")}}</span>\n\t\t\t\t<Icon icon=\"new-window\"></Icon>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li>\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item fm-toolbox-new-window-item\"\n\t\t\t\thref=\"https://github.com/FacilMap/facilmap/issues\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>\n\t\t\t\t<span>{{i18n.t(\"toolbox-help-dropdown.bugtracker\")}}</span>\n\t\t\t\t<Icon icon=\"new-window\"></Icon>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li>\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item fm-toolbox-new-window-item\"\n\t\t\t\thref=\"https://github.com/FacilMap/facilmap/discussions\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>\n\t\t\t\t<span>{{i18n.t(\"toolbox-help-dropdown.forum\")}}</span>\n\t\t\t\t<Icon icon=\"new-window\"></Icon>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li>\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t@click=\"dialog = 'about'; emit('hide-sidebar')\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-help-dropdown.about\", { appName: context.appName })}}</a>\n\t\t</li>\n\t</DropdownMenu>\n\n\t<AboutDialog\n\t\tv-if=\"dialog === 'about'\"\n\t\t@hidden=\"dialog = undefined\"\n\t></AboutDialog>\n</template>","<script setup lang=\"ts\">\n\timport { getLayers, setBaseLayer, toggleOverlay } from \"facilmap-leaflet\";\n\timport { computed } from \"vue\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\timport { injectContextRequired, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport Icon from \"../ui/icon.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst links = computed(() => {\n\t\tconst v = mapContext.value;\n\t\treturn {\n\t\t\tosm: `https://www.openstreetmap.org/#map=${v.zoom}/${v.center.lat}/${v.center.lng}`,\n\t\t\tgoogle: `https://www.google.com/maps/@?api=1&map_action=map&center=${v.center.lat},${v.center.lng}&zoom=${v.zoom}`,\n\t\t\tgoogleSatellite: `https://www.google.com/maps/@?api=1&map_action=map&center=${v.center.lat},${v.center.lng}&zoom=${v.zoom}&basemap=satellite`,\n\t\t\tbing: `https://www.bing.com/maps?cp=${v.center.lat}~${v.center.lng}&lvl=${v.zoom}`\n\t\t};\n\t});\n\n\tconst baseLayers = computed(() => {\n\t\tconst { baseLayers } = getLayers(mapContext.value.components.map);\n\t\treturn Object.keys(baseLayers).map((key) => ({\n\t\t\tkey,\n\t\t\tname: baseLayers[key].options.fmGetName!(),\n\t\t\tactive: mapContext.value.layers.baseLayer === key\n\t\t}));\n\t});\n\n\tconst overlays = computed(() => {\n\t\tconst { overlays } = getLayers(mapContext.value.components.map);\n\t\treturn Object.keys(overlays).map((key) => ({\n\t\t\tkey,\n\t\t\tname: overlays[key].options.fmGetName?.() ?? overlays[key].options.fmName!,\n\t\t\tactive: mapContext.value.layers.overlays.includes(key)\n\t\t}));\n\t});\n\n\tfunction doSetBaseLayer(key: string): void {\n\t\tsetBaseLayer(mapContext.value.components.map, key);\n\t}\n\n\tfunction doToggleOverlay(key: string): void {\n\t\ttoggleOverlay(mapContext.value.components.map, key);\n\t}\n</script>\n\n<template>\n\t<DropdownMenu\n\t\ttag=\"li\"\n\t\tclass=\"nav-item fm-toolbox-map-style-dropdown\"\n\t\tisLink\n\t\tbuttonClass=\"nav-link\"\n\t\tmenuClass=\"dropdown-menu-end\"\n\t\t:label=\"i18n.t('toolbox-map-style-dropdown.label')\"\n\t>\n\t\t<li v-for=\"layerInfo in baseLayers\" :key=\"layerInfo.key\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t:class=\"{ active: layerInfo.active }\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click.capture.stop=\"doSetBaseLayer(layerInfo.key)\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{layerInfo.name}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"baseLayers.length > 0 && overlays.length > 0\">\n\t\t\t<hr class=\"dropdown-divider\">\n\t\t</li>\n\n\t\t<li v-for=\"layerInfo in overlays\" :key=\"layerInfo.key\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\t:class=\"{ active: layerInfo.active }\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click.capture.stop=\"doToggleOverlay(layerInfo.key)\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{layerInfo.name}}</a>\n\t\t</li>\n\n\t\t<li>\n\t\t\t<hr class=\"dropdown-divider\">\n\t\t</li>\n\n\t\t<li>\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item fm-toolbox-new-window-item\"\n\t\t\t\t:href=\"links.osm\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>\n\t\t\t\t<span>{{i18n.t(\"toolbox-map-style-dropdown.openstreetmap\")}}</span>\n\t\t\t\t<Icon icon=\"new-window\"></Icon>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li v-if=\"!context.hideCommercialMapLinks\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item fm-toolbox-new-window-item\"\n\t\t\t\t:href=\"links.google\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>\n\t\t\t\t<span>{{i18n.t(\"toolbox-map-style-dropdown.google-maps\")}}</span>\n\t\t\t\t<Icon icon=\"new-window\"></Icon>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li v-if=\"!context.hideCommercialMapLinks\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item fm-toolbox-new-window-item\"\n\t\t\t\t:href=\"links.googleSatellite\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>\n\t\t\t\t<span>{{i18n.t(\"toolbox-map-style-dropdown.google-maps-satellite\")}}</span>\n\t\t\t\t<Icon icon=\"new-window\"></Icon>\n\t\t\t</a>\n\t\t</li>\n\n\t\t<li v-if=\"!context.hideCommercialMapLinks\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item fm-toolbox-new-window-item\"\n\t\t\t\t:href=\"links.bing\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>\n\t\t\t\t<span>{{i18n.t(\"toolbox-map-style-dropdown.bing-maps\")}}</span>\n\t\t\t\t<Icon icon=\"new-window\"></Icon>\n\t\t\t</a>\n\t\t</li>\n\t</DropdownMenu>\n</template>","<script setup lang=\"ts\">\n\timport { filterHasError, getOrderedTypes } from \"facilmap-utils\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { computed, ref } from \"vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ValidatedField from \"./ui/validated-form/validated-field.vue\";\n\timport { T, useI18n } from \"../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst client = requireClientContext(context);\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\tconst filter = ref(mapContext.value.filter ?? \"\");\n\n\tconst types = computed(() => getOrderedTypes(client.value.types));\n\n\tfunction validateFilter(filter: string) {\n\t\treturn filterHasError(filter)?.message;\n\t}\n\n\tconst isModified = computed(() => {\n\t\treturn filter.value != (mapContext.value.filter ?? \"\");\n\t});\n\n\tfunction save(): void {\n\t\tmapContext.value.components.map.setFmFilter(filter.value || undefined);\n\t\tmodalRef.value?.modal.hide();\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('edit-filter-dialog.title')\"\n\t\tclass=\"fm-edit-filter\"\n\t\t:isModified=\"isModified\"\n\t\t@submit=\"save\"\n\t\t:okLabel=\"isModified ? i18n.t('edit-filter-dialog.apply') : undefined\"\n\t\tref=\"modalRef\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<p>{{i18n.t(\"edit-filter-dialog.introduction\")}}</p>\n\n\t\t<ValidatedField\n\t\t\t:value=\"filter\"\n\t\t\t:validators=\"[\n\t\t\t\tvalidateFilter\n\t\t\t]\"\n\t\t\t:reportValid=\"!!filter\"\n\t\t\timmediate\n\t\t>\n\t\t\t<template #default=\"slotProps\">\n\t\t\t\t<textarea\n\t\t\t\t\tclass=\"form-control text-monospace\"\n\t\t\t\t\tv-model=\"filter\"\n\t\t\t\t\trows=\"5\"\n\t\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\t></textarea>\n\t\t\t\t<div class=\"invalid-feedback\" v-if=\"slotProps.validationError\">\n\t\t\t\t\t<pre>{{slotProps.validationError}}</pre>\n\t\t\t\t</div>\n\t\t\t</template>\n\t\t</ValidatedField>\n\n\t\t<hr />\n\n\t\t<div class=\"fm-edit-filter-syntax\">\n\t\t\t<h3>{{i18n.t(\"edit-filter-dialog.syntax-header\")}}</h3>\n\t\t\t<table class=\"table table-condensed table-striped\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>{{i18n.t(\"edit-filter-dialog.variable\")}}</th>\n\t\t\t\t\t\t<th>{{i18n.t(\"edit-filter-dialog.description\")}}</th>\n\t\t\t\t\t\t<th>{{i18n.t(\"edit-filter-dialog.example\")}}</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>name</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.name-description\")}}</td>\n\t\t\t\t\t\t<td><code>name == &quot;Berlin&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>type</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.type-description\">\n\t\t\t\t\t\t\t\t<template #marker>\n\t\t\t\t\t\t\t\t\t<code>marker</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #line>\n\t\t\t\t\t\t\t\t\t<code>line</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>type == &quot;marker&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>typeId</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.typeId-description\">\n\t\t\t\t\t\t\t\t<template #items>\n\t\t\t\t\t\t\t\t\t<span v-for=\"(type, idx) in types\" :key=\"type.id\">\n\t\t\t\t\t\t\t\t\t\t<span v-if=\"idx != 0\">{{i18n.t(\"edit-filter-dialog.typeId-description-separator\")}}</span>\n\t\t\t\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.typeId-description-item\">\n\t\t\t\t\t\t\t\t\t\t\t<template #typeId>\n\t\t\t\t\t\t\t\t\t\t\t\t<code>{{type.id}}</code>\n\t\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t\t<template #typeName>\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-break\">{{type.name}}</span>\n\t\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>typeId == {{types[0]?.id || 1}}</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>data.&lt;field&gt;</code> / <code>prop(data, &lt;field&gt;)</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.data-description-1\">\n\t\t\t\t\t\t\t\t<template #example1>\n\t\t\t\t\t\t\t\t\t<code>data.Description</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #example2>\n\t\t\t\t\t\t\t\t\t<code>prop(data, &quot;Description&quot;)</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.data-description-2\">\n\t\t\t\t\t\t\t\t<template #uncheckedValue>\n\t\t\t\t\t\t\t\t\t<code>0</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #checkedValue>\n\t\t\t\t\t\t\t\t\t<code>1</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>lower(data.Description) ~= &quot;camp&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>lat</code>, <code>lon</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.lon-lat-description\")}}</td>\n\t\t\t\t\t\t<td><code>lat &lt; 50</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>colour</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.colour-description\")}}</td>\n\t\t\t\t\t\t<td><code>colour == &quot;ff0000&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>size</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.size-description\")}}</td>\n\t\t\t\t\t\t<td><code>size &gt; 30</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>symbol</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.symbol-description\")}}</td>\n\t\t\t\t\t\t<td><code>symbol == &quot;accommodation_camping&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>shape</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.shape-description\")}}</td>\n\t\t\t\t\t\t<td><code>shape == &quot;circle&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>ele</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.ele-description\")}}</td>\n\t\t\t\t\t\t<td><code>ele &gt; 500</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>mode</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.mode-description\">\n\t\t\t\t\t\t\t\t<template #straight>\n\t\t\t\t\t\t\t\t\t<code>&quot;&quot;</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #car>\n\t\t\t\t\t\t\t\t\t<code>&quot;car&quot;</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #bicycle>\n\t\t\t\t\t\t\t\t\t<code>&quot;bicycle&quot;</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #pedestrian>\n\t\t\t\t\t\t\t\t\t<code>&quot;pedestrian&quot;</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #track>\n\t\t\t\t\t\t\t\t\t<code>&quot;track&quot;</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>mode in (&quot;bicycle&quot;, &quot;pedestrian&quot;)</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>width</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.width-description\")}}</td>\n\t\t\t\t\t\t<td><code>width &gt; 10</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>stroke</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.stroke-description\">\n\t\t\t\t\t\t\t\t<template #solid>\n\t\t\t\t\t\t\t\t\t<code>&quot;&quot;</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #dashed>\n\t\t\t\t\t\t\t\t\t<code>&quot;dashed&quot;</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #dotted>\n\t\t\t\t\t\t\t\t\t<code>&quot;dotted&quot;</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>shape == &quot;dotted&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>distance</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.distance-description\")}}</td>\n\t\t\t\t\t\t<td><code>distance &lt; 50</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>time</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.time-description\")}}</td>\n\t\t\t\t\t\t<td><code>time &gt; 3600</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>ascent</code>, <code>descent</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.ascent-descent-description\")}}</td>\n\t\t\t\t\t\t<td><code>ascent &gt; 1000</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>routePoints</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.routePoints-description\")}}</td>\n\t\t\t\t\t\t<td><code>routePoints.0.lon &gt; 60 and routePoints.2.lat &lt; 50</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>{{i18n.t(\"edit-filter-dialog.operator\")}}</th>\n\t\t\t\t\t\t<th>{{i18n.t(\"edit-filter-dialog.description\")}}</th>\n\t\t\t\t\t\t<th>{{i18n.t(\"edit-filter-dialog.example\")}}</th>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>number</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.number-description\")}}</td>\n\t\t\t\t\t\t<td><code>distance &lt; 1.5</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>\"text\"</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.text-description\")}}</td>\n\t\t\t\t\t\t<td><code>name == &quot;Athens&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, <code>%</code>, <code>^</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.mathematical-description\">\n\t\t\t\t\t\t\t\t<template #plus>\n\t\t\t\t\t\t\t\t\t<code>+</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #minus>\n\t\t\t\t\t\t\t\t\t<code>-</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #times>\n\t\t\t\t\t\t\t\t\t<code>*</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #divided>\n\t\t\t\t\t\t\t\t\t<code>/</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #modulo>\n\t\t\t\t\t\t\t\t\t<code>%</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #power>\n\t\t\t\t\t\t\t\t\t<code>^</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>distance / time &gt; 30</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>and</code>, <code>or</code>, <code>not</code>, <code>()</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.logical-description\")}}</td>\n\t\t\t\t\t\t<td><code>not (size&gt;10) or (type==&quot;line&quot; and length&lt;=10)</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>? :</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.ternary-description\")}}</td>\n\t\t\t\t\t\t<td><code>(type==&quot;marker&quot; ? size : width) &gt; 10</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>==</code>, <code>!=</code>, <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, <code>&gt;=</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.comparison-description\">\n\t\t\t\t\t\t\t\t<template #notEqual>\n\t\t\t\t\t\t\t\t\t<code>!=</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>type != &quot;marker&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>in</code>, <code>not in</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.list-description\">\n\t\t\t\t\t\t\t\t<template #in>\n\t\t\t\t\t\t\t\t\t<code>in</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #notIn>\n\t\t\t\t\t\t\t\t\t<code>not in</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>typeId not in (1,2)</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>~=</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.regexp-description\")}}</td>\n\t\t\t\t\t\t<td><code>name ~= &quot;^[Cc]amp$&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>lower()</code></td>\n\t\t\t\t\t\t<td>{{i18n.t(\"edit-filter-dialog.lower-description\")}}</td>\n\t\t\t\t\t\t<td><code>lower(name) ~= &quot;untitled&quot;</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>ceil()</code>, <code>floor()</code>, <code>round()</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.round-description\">\n\t\t\t\t\t\t\t\t<template #round>\n\t\t\t\t\t\t\t\t\t<code>round</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #ceil>\n\t\t\t\t\t\t\t\t\t<code>ceil</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #floor>\n\t\t\t\t\t\t\t\t\t<code>floor</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>floor(distance/100) == 5</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>abs()</code>, <code>log()</code>, <code>sqrt()</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.functions-description\">\n\t\t\t\t\t\t\t\t<template #abs>\n\t\t\t\t\t\t\t\t\t<code>abs</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #log>\n\t\t\t\t\t\t\t\t\t<code>log</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #sqrt>\n\t\t\t\t\t\t\t\t\t<code>sqrt</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>abs(lat) &lt; 30</code></td>\n\t\t\t\t\t</tr>\n\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td><code>min()</code>, <code>max()</code></td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<T k=\"edit-filter-dialog.min-max-description\">\n\t\t\t\t\t\t\t\t<template #min>\n\t\t\t\t\t\t\t\t\t<code>min</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template #max>\n\t\t\t\t\t\t\t\t\t<code>max</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td><code>min(routePoints.0.lat,routePoints.1.lat) &lt; 50</code></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t</ModalDialog>\n</template>\n\n<style lang=\"scss\">\n\t.fm-edit-filter {\n\t\t.modal-body.modal-body, form {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tmin-height: 0;\n\t\t}\n\n\t\thr {\n\t\t\twidth: 100%;\n\t\t}\n\n\t\t.fm-edit-filter-syntax {\n\t\t\toverflow: auto;\n\t\t\tmargin-right: -16px;\n\t\t\tpadding-right: 16px;\n\t\t\tmin-height: 150px;\n\t\t\tmax-width: 100%;\n\t\t}\n\n\t\tpre {\n\t\t\tcolor: inherit;\n\t\t\tfont-size: inherit;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { getLayers } from \"facilmap-leaflet\";\n\timport { getLegendItems } from \"./legend/legend-utils\";\n\timport type { Writable } from \"facilmap-types\";\n\timport { formatCoordinates, quoteHtml } from \"facilmap-utils\";\n\timport { computed, ref } from \"vue\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { getUniqueId } from \"../utils/utils\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport CopyToClipboardInput from \"./ui/copy-to-clipboard-input.vue\";\n\timport { T, useI18n } from \"../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst id = getUniqueId(\"fm-share-dialog\");\n\n\tconst includeMapView = ref(true);\n\tconst showToolbox = ref(true);\n\tconst showSearch = ref(true);\n\tconst showRoute = ref(true);\n\tconst showPois = ref(true);\n\tconst showLegend = ref(true);\n\tconst showLocate = ref(true);\n\tconst padIdType = ref<Writable>(2);\n\tconst activeShareTab = ref(0);\n\n\tconst layers = computed(() => {\n\t\tconst { baseLayers, overlays } = getLayers(mapContext.value.components.map);\n\t\treturn [\n\t\t\tbaseLayers[mapContext.value.layers.baseLayer]?.options.fmName || mapContext.value.layers.baseLayer,\n\t\t\t...mapContext.value.layers.overlays.map((key) => overlays[key].options.fmName || key)\n\t\t].join(i18n.t(\"share-dialog.include-view-interpolation-layers-joiner\"));\n\t});\n\n\tconst hasLegend = computed(() => {\n\t\treturn !!client.value.padData && getLegendItems(context).length > 0;\n\t});\n\n\tconst padIdTypes = computed(() => {\n\t\treturn [\n\t\t\t{ value: 2, text: i18n.t(\"share-dialog.type-admin\") },\n\t\t\t{ value: 1, text: i18n.t(\"share-dialog.type-write\") },\n\t\t\t{ value: 0, text: i18n.t(\"share-dialog.type-read\") }\n\t\t].filter((option) => client.value.writable != null && option.value <= client.value.writable);\n\t});\n\n\tconst url = computed(() => {\n\t\tconst params = new URLSearchParams();\n\t\tif (!showToolbox.value) {\n\t\t\tparams.set(\"toolbox\", \"false\");\n\t\t}\n\t\tif (!showSearch.value) {\n\t\t\tparams.set(\"search\", \"false\");\n\t\t} else {\n\t\t\tif (!showRoute.value) {\n\t\t\t\tparams.set(\"route\", \"false\");\n\t\t\t}\n\t\t\tif (!showPois.value) {\n\t\t\t\tparams.set(\"pois\", \"false\");\n\t\t\t}\n\t\t}\n\t\tif (!showLegend.value) {\n\t\t\tparams.set(\"legend\", \"false\");\n\t\t}\n\t\tif (!showLocate.value) {\n\t\t\tparams.set(\"locate\", \"false\");\n\t\t}\n\t\tconst paramsStr = params.toString();\n\n\t\treturn context.baseUrl\n\t\t\t+ (client.value.padData ? encodeURIComponent((padIdType.value == 2 && client.value.padData.adminId) || (padIdType.value == 1 && client.value.padData.writeId) || client.value.padData.id) : '')\n\t\t\t+ (paramsStr ? `?${paramsStr}` : '')\n\t\t\t+ (includeMapView.value && mapContext.value.hash ? `#${mapContext.value.hash}` : '');\n\t});\n\n\tconst embedCode = computed(() => {\n\t\treturn `<iframe style=\"height:500px; width:100%; border:none;\" src=\"${quoteHtml(url.value)}\"></iframe>`;\n\t});\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('share-dialog.title')\"\n\t\tsize=\"lg\"\n\t\tclass=\"fm-share-dialog\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<div class=\"row mb-3\">\n\t\t\t<label class=\"col-sm-3 col-form-label\">{{i18n.t(\"share-dialog.settings\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"`${id}-include-map-view-input`\"\n\t\t\t\t\t\tv-model=\"includeMapView\"\n\t\t\t\t\t\t:disabled=\"!client.padData\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label :for=\"`${id}-include-map-view-input`\" class=\"form-check-label\">\n\t\t\t\t\t\t<T k=\"share-dialog.include-view\">\n\t\t\t\t\t\t\t<template #centre>\n\t\t\t\t\t\t\t\t<code>{{formatCoordinates({ lat: mapContext.center.lat, lon: mapContext.center.lng })}}</code>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template #zoom>\n\t\t\t\t\t\t\t\t<code>{{mapContext.zoom}}</code>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template #layers>\n\t\t\t\t\t\t\t\t{{layers}}\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template #conditionalPois>\n\t\t\t\t\t\t\t\t<template v-if=\"mapContext.overpassIsCustom ? !!mapContext.overpassCustom : mapContext.overpassPresets.length > 0\">\n\t\t\t\t\t\t\t\t\t<T k=\"share-dialog.include-view-interpolation-conditionalPois\">\n\t\t\t\t\t\t\t\t\t\t<template #pois>\n\t\t\t\t\t\t\t\t\t\t\t<code v-if=\"mapContext.overpassIsCustom\">{{mapContext.overpassCustom}}</code>\n\t\t\t\t\t\t\t\t\t\t\t<template v-else>{{mapContext.overpassPresets.map((p) => p.label).join(i18n.t(\"share-dialog.include-view-interpolation-conditionalPois-interpolation-pois-joiner\"))}}</template>\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template #conditionalSelection>\n\t\t\t\t\t\t\t\t<template v-if=\"mapContext.activeQuery\">\n\t\t\t\t\t\t\t\t\t<T k=\"share-dialog.include-view-interpolation-conditionalSelection\">\n\t\t\t\t\t\t\t\t\t\t<template #description>\n\t\t\t\t\t\t\t\t\t\t\t<template v-if=\"mapContext.activeQuery.description\">{{mapContext.activeQuery.description}}</template>\n\t\t\t\t\t\t\t\t\t\t\t<code v-else>{{mapContext.activeQuery.query}}</code>\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t<template #conditionalFilter>\n\t\t\t\t\t\t\t\t<template v-if=\"mapContext.filter\">\n\t\t\t\t\t\t\t\t\t<T k=\"share-dialog.include-view-interpolation-conditionalFilter\">\n\t\t\t\t\t\t\t\t\t\t<template #filter>\n\t\t\t\t\t\t\t\t\t\t\t<code>{{mapContext.filter}}</code>\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label class=\"col-sm-3 col-form-label\">{{i18n.t(\"share-dialog.show-controls\")}}</label>\n\t\t\t<div class=\"col-sm-9 checkbox-grid\">\n\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"`${id}-show-toolbox-input`\"\n\t\t\t\t\t\tv-model=\"showToolbox\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label :for=\"`${id}-show-toolbox-input`\" class=\"form-check-label\">\n\t\t\t\t\t\t{{i18n.t(\"share-dialog.show-toolbox\")}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"`${id}-show-search-input`\"\n\t\t\t\t\t\tv-model=\"showSearch\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label :for=\"`${id}-show-search-input`\" class=\"form-check-label\">\n\t\t\t\t\t\t{{i18n.t(\"share-dialog.show-search-box\")}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"`${id}-show-route-input`\"\n\t\t\t\t\t\t:disabled=\"!showSearch\"\n\t\t\t\t\t\t:checked=\"showSearch && showRoute\"\n\t\t\t\t\t\t@change=\"showRoute = ($event.target as HTMLInputElement).checked\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label :for=\"`${id}-show-route-input`\" class=\"form-check-label\">\n\t\t\t\t\t\t{{i18n.t(\"share-dialog.show-route\")}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"`${id}-show-pois-input`\"\n\t\t\t\t\t\t:disabled=\"!showSearch\"\n\t\t\t\t\t\t:checked=\"showSearch && showPois\"\n\t\t\t\t\t\t@change=\"showPois = ($event.target as HTMLInputElement).checked\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label :for=\"`${id}-show-pois-input`\" class=\"form-check-label\">\n\t\t\t\t\t\t{{i18n.t(\"share-dialog.show-pois\")}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"form-check\" v-if=\"hasLegend\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"`${id}-show-legend-input`\"\n\t\t\t\t\t\tv-model=\"showLegend\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label :for=\"`${id}-show-legend-input`\" class=\"form-check-label\">\n\t\t\t\t\t\t{{i18n.t(\"share-dialog.show-legend\")}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"form-check\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"`${id}-show-locate-input`\"\n\t\t\t\t\t\tv-model=\"showLocate\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label :for=\"`${id}-show-locate-input`\" class=\"form-check-label\">\n\t\t\t\t\t\t{{i18n.t(\"share-dialog.show-locate\")}}\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<template v-if=\"client.padData\">\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-padIdType-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"share-dialog.link-type\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<select :id=\"`${id}-padIdType-input`\" class=\"form-select\" v-model=\"padIdType\">\n\t\t\t\t\t\t<option v-for=\"type in padIdTypes\" :key=\"type.value\" :value=\"type.value\">{{type.text}}</option>\n\t\t\t\t\t</select>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<ul class=\"nav nav-tabs\">\n\t\t\t<li class=\"nav-item\">\n\t\t\t\t<a\n\t\t\t\t\tclass=\"nav-link\"\n\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t:class=\"{ active: activeShareTab === 0 }\"\n\t\t\t\t\t@click=\"activeShareTab = 0\"\n\t\t\t\t>{{i18n.t(\"share-dialog.share-link\")}}</a>\n\t\t\t</li>\n\n\t\t\t<li class=\"nav-item\">\n\t\t\t\t<a\n\t\t\t\t\tclass=\"nav-link\"\n\t\t\t\t\thref=\"javascript:\"\n\t\t\t\t\t:class=\"{ active: activeShareTab === 1 }\"\n\t\t\t\t\t@click=\"activeShareTab = 1\"\n\t\t\t\t>{{i18n.t(\"share-dialog.embed\")}}</a>\n\t\t\t</li>\n\t\t</ul>\n\n\t\t<template v-if=\"activeShareTab === 0\">\n\t\t\t<CopyToClipboardInput\n\t\t\t\tclass=\"mt-2\"\n\t\t\t\t:modelValue=\"url\"\n\t\t\t\treadonly\n\t\t\t\t:successTitle=\"i18n.t('share-dialog.link-copied-title')\"\n\t\t\t\t:successMessage=\"i18n.t('share-dialog.link-copied-message')\"\n\t\t\t></CopyToClipboardInput>\n\t\t</template>\n\n\t\t<template v-else-if=\"activeShareTab === 1\">\n\t\t\t<CopyToClipboardInput\n\t\t\t\tclass=\"mt-2\"\n\t\t\t\t:modelValue=\"embedCode\"\n\t\t\t\treadonly\n\t\t\t\t:successTitle=\"i18n.t('share-dialog.embed-copied-title')\"\n\t\t\t\t:successMessage=\"i18n.t('share-dialog.embed-copied-message', { appName: context.appName })\"\n\t\t\t\t:rows=\"2\"\n\t\t\t\tnoQr\n\t\t\t></CopyToClipboardInput>\n\n\t\t\t<p class=\"mt-2\">\n\t\t\t\t<T k=\"share-dialog.embed-explanation\">\n\t\t\t\t\t<template #appName>\n\t\t\t\t\t\t{{context.appName}}\n\t\t\t\t\t</template>\n\t\t\t\t\t<template #learnMore>\n\t\t\t\t\t\t<a href=\"https://docs.facilmap.org/developers/embed.html\" target=\"_blank\">{{i18n.t(\"share-dialog.embed-explanation-interpolation-learnMore\")}}</a>\n\t\t\t\t\t</template>\n\t\t\t\t</T>\n\t\t\t</p>\n\t\t</template>\n\t</ModalDialog>\n</template>\n\n<style lang=\"scss\">\n\t.fm-share-dialog {\n\t\t.checkbox-grid {\n\t\t\tcolumn-width: 160px;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport Icon from \"./icon.vue\";\n\timport { ref } from \"vue\";\n\timport Popover from \"./popover.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst i18n = useI18n();\n\n\tconst helpLinkRef = ref<HTMLElement>();\n\tconst showPopover = ref(false);\n</script>\n\n<template>\n\t<a href=\"javascript:\" ref=\"helpLinkRef\" @click.prevent=\"showPopover = !showPopover\">\n\t\t<Icon icon=\"question-sign\" :alt=\"i18n.t('help-popover.show-alt')\"></Icon>\n\t</a>\n\t<Popover :element=\"helpLinkRef\" v-model:show=\"showPopover\" hideOnOutsideClick>\n\t\t<slot></slot>\n\t</Popover>\n</template>","<script setup lang=\"ts\">\n\timport { computed, ref } from \"vue\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { getUniqueId } from \"../utils/utils\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport HelpPopover from \"./ui/help-popover.vue\";\n\timport CopyToClipboardInput from \"./ui/copy-to-clipboard-input.vue\";\n\timport type { ComponentProps } from \"../utils/vue\";\n\timport type { ID } from \"facilmap-types\";\n\timport validatedField from \"./ui/validated-form/validated-field.vue\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport copyToClipboard from \"copy-to-clipboard\";\n\timport type { CustomSubmitEvent } from \"./ui/validated-form/validated-form.vue\";\n\timport { formatFieldName, formatTypeName, getOrderedTypes } from \"facilmap-utils\";\n\timport { T, useI18n } from \"../utils/i18n\";\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\n\tconst id = getUniqueId(\"fm-export-map\");\n\n\tconst orderedTypes = computed(() => getOrderedTypes(client.value.types));\n\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\n\tconst copyRef = ref<InstanceType<typeof CopyToClipboardInput>>();\n\n\tconst formatOptions = computed(() => ({\n\t\tgpx: i18n.t(\"export-dialog.format-option-gpx\"),\n\t\tgeojson: i18n.t(\"export-dialog.format-option-geojson\"),\n\t\ttable: i18n.t(\"export-dialog.format-option-html\"),\n\t\tcsv: i18n.t(\"export-dialog.format-option-csv\")\n\t}));\n\n\tconst hideOptions = computed(() => ({\n\t\tName: i18n.t(\"export-dialog.column-name\"),\n\t\tPosition: i18n.t(\"export-dialog.column-position\"),\n\t\tDistance: i18n.t(\"export-dialog.column-distance\"),\n\t\tTime: i18n.t(\"export-dialog.column-time\"),\n\t\t// TODO: Include only types not currently filtered\n\t\t...Object.fromEntries(orderedTypes.value.flatMap((type) => type.fields.map((field) => [field.name, formatFieldName(field.name)])))\n\t}));\n\n\tconst routeTypeOptions = computed(() => ({\n\t\t\"tracks\": i18n.t(\"export-dialog.route-type-track\"),\n\t\t\"zip\": i18n.t(\"export-dialog.route-type-track-zip\"),\n\t\t\"routes\": i18n.t(\"export-dialog.route-type-route\")\n\t}));\n\n\tconst format = ref<keyof typeof formatOptions[\"value\"]>(\"gpx\");\n\tconst routeType = ref<keyof typeof routeTypeOptions[\"value\"]>(\"tracks\");\n\tconst filter = ref(true);\n\tconst hide = ref(new Set<string>());\n\tconst typeId = ref<ID>();\n\n\tconst methodOptions = computed(() => ({\n\t\tdownload: format.value === \"table\" ? i18n.t(\"export-dialog.open-file\") : i18n.t(\"export-dialog.download-file\"),\n\t\tlink: i18n.t(\"export-dialog.generate-link\"),\n\t\t...(format.value === \"table\" ? {\n\t\t\tcopy: i18n.t(\"export-dialog.copy-to-clipboard\")\n\t\t} : {})\n\t}));\n\n\tconst rawMethod = ref<keyof typeof methodOptions[\"value\"]>();\n\tconst method = computed({\n\t\tget: () => (rawMethod.value && Object.keys(methodOptions.value).includes(rawMethod.value)) ? rawMethod.value : (Object.keys(methodOptions.value) as Array<keyof typeof methodOptions[\"value\"]>)[0],\n\t\tset: (method) => {\n\t\t\trawMethod.value = method;\n\t\t}\n\t});\n\n\tconst resolveTypeId = (typeId: ID | undefined) => typeId != null && client.value.types[typeId] ? typeId : undefined;\n\tconst resolvedTypeId = computed(() => resolveTypeId(typeId.value));\n\n\tconst canSelectRouteType = computed(() => format.value === \"gpx\");\n\tconst canSelectType = computed(() => format.value === \"csv\" || (format.value === \"table\" && method.value === \"copy\"));\n\tconst mustSelectType = computed(() => canSelectType.value);\n\tconst canSelectHide = computed(() => [\"table\", \"csv\"].includes(format.value));\n\tconst validateImmediate = computed(() => method.value === \"link\"); // No submit button\n\n\tfunction validateTypeId(typeId: ID | undefined) {\n\t\tif (mustSelectType.value && resolveTypeId(typeId) == null) {\n\t\t\treturn i18n.t(\"export-dialog.select-type-error\");\n\t\t}\n\t}\n\n\tconst url = computed(() => {\n\t\tconst params = new URLSearchParams();\n\t\tif (canSelectRouteType.value) {\n\t\t\tparams.set(\"useTracks\", routeType.value === \"routes\" ? \"0\" : \"1\");\n\t\t}\n\t\tif (canSelectHide.value && hide.value.size > 0) {\n\t\t\tparams.set(\"hide\", [...hide.value].join(\",\"));\n\t\t}\n\t\tif (filter.value && mapContext.value.filter) {\n\t\t\tparams.set(\"filter\", mapContext.value.filter);\n\t\t}\n\t\tconst paramsStr = params.toString();\n\n\t\tswitch (format.value) {\n\t\t\tcase \"table\": {\n\t\t\t\tif (method.value === \"copy\") {\n\t\t\t\t\tif (resolvedTypeId.value == null) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\treturn (\n\t\t\t\t\t\tcontext.baseUrl\n\t\t\t\t\t\t\t+ client.value.padData!.id\n\t\t\t\t\t\t\t+ `/rawTable`\n\t\t\t\t\t\t\t+ `/${resolvedTypeId.value}`\n\t\t\t\t\t\t\t+ (paramsStr ? `?${paramsStr}` : '')\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treturn (\n\t\t\t\t\t\tcontext.baseUrl\n\t\t\t\t\t\t\t+ client.value.padData!.id\n\t\t\t\t\t\t\t+ `/table`\n\t\t\t\t\t\t\t+ (paramsStr ? `?${paramsStr}` : '')\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcase \"csv\": {\n\t\t\t\tif (resolvedTypeId.value == null) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\tcontext.baseUrl\n\t\t\t\t\t\t+ client.value.padData!.id\n\t\t\t\t\t\t+ `/csv`\n\t\t\t\t\t\t+ `/${resolvedTypeId.value}`\n\t\t\t\t\t\t+ (paramsStr ? `?${paramsStr}` : '')\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"gpx\": {\n\t\t\t\treturn (\n\t\t\t\t\tcontext.baseUrl\n\t\t\t\t\t\t+ client.value.padData!.id\n\t\t\t\t\t\t+ `/${format.value}`\n\t\t\t\t\t\t+ (routeType.value === \"zip\" ? `/zip` : \"\")\n\t\t\t\t\t\t+ (paramsStr ? `?${paramsStr}` : '')\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\treturn (\n\t\t\t\t\tcontext.baseUrl\n\t\t\t\t\t\t+ client.value.padData!.id\n\t\t\t\t\t\t+ `/${format.value}`\n\t\t\t\t\t\t+ (paramsStr ? `?${paramsStr}` : '')\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t});\n\n\tconst modalProps = computed((): Partial<ComponentProps<typeof ModalDialog>> => {\n\t\tif (method.value === \"download\") {\n\t\t\treturn {\n\t\t\t\taction: url.value,\n\t\t\t\ttarget: format.value === \"table\" ? \"_blank\" : undefined,\n\t\t\t\tisCreate: true,\n\t\t\t\tokLabel: i18n.t(\"export-dialog.export-ok\")\n\t\t\t};\n\t\t} else if (method.value === \"copy\") {\n\t\t\treturn {\n\t\t\t\tisCreate: true,\n\t\t\t\tokLabel: i18n.t(\"export-dialog.copy-ok\")\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tisCreate: false,\n\t\t\t\tokVariant: \"secondary\"\n\t\t\t};\n\t\t}\n\t});\n\n\tfunction handleSubmit(e: CustomSubmitEvent): void {\n\t\tif (method.value === \"copy\") {\n\t\t\te.preventDefault();\n\n\t\t\tconst fetchUrl = url.value;\n\t\t\tif (fetchUrl) {\n\t\t\t\te.waitUntil((async () => {\n\t\t\t\t\tconst res = await fetch(fetchUrl);\n\t\t\t\t\tconst html = await res.text();\n\t\t\t\t\tcopyToClipboard(html, { format: \"text/html\" });\n\t\t\t\t\ttoasts.showToast(undefined, () => i18n.t(\"export-dialog.export-copied-title\", { format: formatOptions.value[format.value] }), () => i18n.t(\"export-dialog.export-copied-message\", { format: formatOptions.value[format.value] }), { variant: \"success\", autoHide: true });\n\t\t\t\t})());\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('export-dialog.title')\"\n\t\tsize=\"lg\"\n\t\tclass=\"fm-export-dialog\"\n\t\tref=\"modalRef\"\n\t\tv-bind=\"modalProps\"\n\t\t@submit=\"handleSubmit\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<p>{{i18n.t(\"export-dialog.introduction\")}}</p>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label class=\"col-sm-3 col-form-label\" :for=\"`${id}-format-select`\">\n\t\t\t\t{{i18n.t(\"export-dialog.format\")}}\n\t\t\t\t<HelpPopover>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<T k=\"export-dialog.gpx-explanation\">\n\t\t\t\t\t\t\t<template #gpx>\n\t\t\t\t\t\t\t\t<strong>{{i18n.t(\"export-dialog.gpx-explanation-interpolation-gpx\")}}</strong>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</p>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<T k=\"export-dialog.geojson-explanation\">\n\t\t\t\t\t\t\t<template #geojson>\n\t\t\t\t\t\t\t\t<strong>{{i18n.t(\"export-dialog.geojson-explanation-interpolation-geojson\")}}</strong>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</p>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<T k=\"export-dialog.html-explanation\">\n\t\t\t\t\t\t\t<template #html>\n\t\t\t\t\t\t\t\t<strong>{{i18n.t(\"export-dialog.html-explanation-interpolation-html\")}}</strong>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</p>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<T k=\"export-dialog.csv-explanation\">\n\t\t\t\t\t\t\t<template #csv>\n\t\t\t\t\t\t\t\t<strong>{{i18n.t(\"export-dialog.csv-explanation-interpolation-csv\")}}</strong>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</p>\n\t\t\t\t</HelpPopover>\n\t\t\t</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<select class=\"form-select\" v-model=\"format\" :id=\"`${id}-format-select`\">\n\t\t\t\t\t<option v-for=\"(label, value) in formatOptions\" :value=\"value\" :key=\"value\">{{label}}</option>\n\t\t\t\t</select>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label class=\"col-sm-3 col-form-label\" :for=\"`${id}-method`\">{{i18n.t(\"export-dialog.export-method\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<select class=\"form-select\" v-model=\"method\" :id=\"`${id}-method`\">\n\t\t\t\t\t<option v-for=\"(label, value) in methodOptions\" :value=\"value\" :key=\"value\">{{label}}</option>\n\t\t\t\t</select>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div v-if=\"canSelectRouteType\" class=\"row mb-3\">\n\t\t\t<label class=\"col-sm-3 col-form-label\" :for=\"`${id}-route-type-select`\">\n\t\t\t\t{{i18n.t(\"export-dialog.route-type\")}}\n\t\t\t\t<HelpPopover>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<T k=\"export-dialog.track-explanation\">\n\t\t\t\t\t\t\t<template #track>\n\t\t\t\t\t\t\t\t<strong>{{i18n.t(\"export-dialog.track-explanation-interpolation-track\")}}</strong>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</p>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<T k=\"export-dialog.track-zip-explanation\">\n\t\t\t\t\t\t\t<template #trackZip>\n\t\t\t\t\t\t\t\t<strong>{{i18n.t(\"export-dialog.track-zip-explanation-interpolation-trackZip\")}}</strong>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</p>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<T k=\"export-dialog.route-explanation\">\n\t\t\t\t\t\t\t<template #route>\n\t\t\t\t\t\t\t\t<strong>{{i18n.t(\"export-dialog.route-explanation-interpolation-route\")}}</strong>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</T>\n\t\t\t\t\t</p>\n\t\t\t\t</HelpPopover>\n\t\t\t</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<select class=\"form-select\" v-model=\"routeType\" :id=\"`${id}-route-type-select`\">\n\t\t\t\t\t<option v-for=\"(label, value) in routeTypeOptions\" :value=\"value\" :key=\"value\">{{label}}</option>\n\t\t\t\t</select>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div v-if=\"canSelectType\" class=\"row mb-3\">\n\t\t\t<label class=\"col-sm-3 col-form-label\" :for=\"`${id}-type-select`\">\n\t\t\t\t{{i18n.t(\"export-dialog.type\")}}\n\t\t\t</label>\n\t\t\t<validatedField\n\t\t\t\t:value=\"typeId\"\n\t\t\t\t:validators=\"[\n\t\t\t\t\tvalidateTypeId\n\t\t\t\t]\"\n\t\t\t\tclass=\"col-sm-9 position-relative\"\n\t\t\t\t:immediate=\"validateImmediate\"\n\t\t\t>\n\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t<select class=\"form-select\" v-model=\"typeId\" :id=\"`${id}-type-select`\" :ref=\"slotProps.inputRef\">\n\t\t\t\t\t\t<option v-for=\"type of orderedTypes\" :key=\"type.id\" :value=\"type.id\">{{formatTypeName(type.name)}}</option>\n\t\t\t\t\t</select>\n\t\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t</ValidatedField>\n\t\t</div>\n\n\t\t<div v-if=\"canSelectHide\" class=\"row mb-3\">\n\t\t\t<label class=\"col-sm-3 col-form-label\">{{i18n.t(\"export-dialog.include-columns\")}}</label>\n\t\t\t<div class=\"col-sm-9 fm-export-dialog-hide-options\">\n\t\t\t\t<template v-for=\"(label, value) in hideOptions\" :key=\"value\">\n\t\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t:id=\"`${id}-show-${value}-checkbox`\"\n\t\t\t\t\t\t\t:checked=\"!hide.has(value)\"\n\t\t\t\t\t\t\t@change=\"hide.has(value) ? hide.delete(value) : hide.add(value)\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t<label class=\"form-check-label\" :for=\"`${id}-show-${value}-checkbox`\">{{label}}</label>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div v-if=\"mapContext.filter\" class=\"row mb-3\">\n\t\t\t<label class=\"col-sm-3 col-form-label\" :for=\"`${id}-filter-checkbox`\">{{i18n.t(\"export-dialog.apply-filter\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t:id=\"`${id}-filter-checkbox`\"\n\t\t\t\t\t\tv-model=\"filter\"\n\t\t\t\t\t>\n\t\t\t\t\t<label class=\"form-check-label\" :for=\"`${id}-filter-checkbox`\">{{i18n.t(\"export-dialog.apply-filter-label\")}}</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<template v-if=\"method === 'link' && url != null\">\n\t\t\t<hr />\n\n\t\t\t<CopyToClipboardInput\n\t\t\t\t:modelValue=\"url\"\n\t\t\t\treadonly\n\t\t\t\tref=\"copyRef\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t></CopyToClipboardInput>\n\t\t</template>\n\t</ModalDialog>\n</template>\n\n<style lang=\"scss\">\n\t.fm-export-dialog {\n\t\t.fm-export-dialog-hide-options {\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { getCurrentLanguage, getCurrentUnits, getLocalizedLanguageList } from \"facilmap-utils\";\n\timport { Units } from \"facilmap-types\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { computed, reactive, ref, toRef } from \"vue\";\n\timport {  T, useI18n } from \"../utils/i18n\";\n\timport { getUniqueId } from \"../utils/utils\";\n\timport { setLangCookie, setUnitsCookie } from \"../utils/cookies\";\n\timport { isEqual } from \"lodash-es\";\n\timport { injectContextOptional } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\n\tconst i18n = useI18n();\n\tconst context = injectContextOptional();\n\tconst client = toRef(() => context?.components.client);\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\tconst id = getUniqueId(\"fm-user-preferences-dialog\");\n\n\tconst initialValues = {\n\t\tlang: getCurrentLanguage(),\n\t\tunits: getCurrentUnits()\n\t};\n\n\tconst values = reactive({ ...initialValues });\n\n\tconst isModified = computed(() => {\n\t\treturn !isEqual(values, reactive(initialValues));\n\t});\n\n\tconst languageList = computed(() => getLocalizedLanguageList());\n\n\tasync function save() {\n\t\tawait setLangCookie(values.lang);\n\t\tawait setUnitsCookie(values.units);\n\n\t\tif (client.value) {\n\t\t\tawait client.value.setLanguage({\n\t\t\t\tlang: values.lang,\n\t\t\t\tunits: values.units\n\t\t\t});\n\t\t}\n\n\t\tawait i18n.changeLanguage(values.lang);\n\n\t\tmodalRef.value?.modal.hide();\n\t}\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('user-preferences-dialog.title')\"\n\t\tclass=\"fm-user-preferences\"\n\t\t:isModified=\"isModified\"\n\t\t@submit=\"save\"\n\t\tref=\"modalRef\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<p>{{i18n.t(\"user-preferences-dialog.introduction\")}}</p>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-language-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"user-preferences-dialog.language\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<select :id=\"`${id}-language-input`\" class=\"form-select\" v-model=\"values.lang\">\n\t\t\t\t\t<option v-for=\"(label, key) in languageList\" :key=\"key\" :value=\"key\">{{label}}</option>\n\t\t\t\t</select>\n\t\t\t\t<div class=\"form-text\">\n\t\t\t\t\t<T k=\"user-preferences-dialog.language-description\">\n\t\t\t\t\t\t<template #weblate>\n\t\t\t\t\t\t\t<a href=\"https://hosted.weblate.org/projects/facilmap/\" target=\"_blank\" rel=\"noopener\">\n\t\t\t\t\t\t\t\t{{i18n.t(\"user-preferences-dialog.language-description-interpolation-weblate\")}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</T>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-units-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"user-preferences-dialog.units\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<select :id=\"`${id}-units-input`\" class=\"form-select\" v-model=\"values.units\">\n\t\t\t\t\t<option :value=\"Units.METRIC\">{{i18n.t(\"user-preferences-dialog.units-metric\")}}</option>\n\t\t\t\t\t<option :value=\"Units.US_CUSTOMARY\">{{i18n.t(\"user-preferences-dialog.units-us\")}}</option>\n\t\t\t\t</select>\n\t\t\t</div>\n\t\t</div>\n\t</ModalDialog>\n</template>","<script setup lang=\"ts\">\n\timport PadSettingsDialog from \"../pad-settings-dialog/pad-settings-dialog.vue\";\n\timport EditFilterDialog from \"../edit-filter-dialog.vue\";\n\timport HistoryDialog from \"../history-dialog/history-dialog.vue\";\n\timport ShareDialog from \"../share-dialog.vue\";\n\timport { ref, toRef } from \"vue\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\timport { injectContextRequired, requireClientContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ExportDialog from \"../export-dialog.vue\";\n\timport UserPreferencesDialog from \"../user-preferences-dialog.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst i18n = useI18n();\n\tconst importTabContext = toRef(() => context.components.importTab);\n\n\tconst props = defineProps<{\n\t\tinteractive: boolean;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"hide-sidebar\": [];\n\t}>();\n\n\tconst dialog = ref<\n\t\t| \"edit-pad\"\n\t\t| \"share\"\n\t\t| \"export\"\n\t\t| \"edit-filter\"\n\t\t| \"history\"\n\t\t| \"user-preferences\"\n\t>();\n</script>\n\n<template>\n\t<DropdownMenu\n\t\ttag=\"li\"\n\t\tclass=\"nav-item\"\n\t\tisLink\n\t\tbuttonClass=\"nav-link\"\n\t\tmenuClass=\"dropdown-menu-end\"\n\t\t:label=\"i18n.t('toolbox-tools-dropdown.label')\"\n\t>\n\t\t<li v-if=\"props.interactive\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'share'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-tools-dropdown.share\")}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"props.interactive && importTabContext\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"importTabContext.openFilePicker(); emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-tools-dropdown.open-file\")}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"client.padData\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'export'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-tools-dropdown.export\")}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"client.padData\">\n\t\t\t<hr class=\"dropdown-divider\">\n\t\t</li>\n\n\t\t<li v-if=\"client.padData\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'edit-filter'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-tools-dropdown.filter\")}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"client.writable == 2 && client.padData\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'edit-pad'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-tools-dropdown.settings\")}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"!client.readonly && client.padData\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'history'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-tools-dropdown.history\")}}</a>\n\t\t</li>\n\n\t\t<li>\n\t\t\t<hr class=\"dropdown-divider\">\n\t\t</li>\n\n\t\t<li>\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'user-preferences'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-tools-dropdown.user-preferences\")}}</a>\n\t\t</li>\n\t</DropdownMenu>\n\n\t<PadSettingsDialog\n\t\tv-if=\"dialog === 'edit-pad' && client.padData\"\n\t\t@hidden=\"dialog = undefined\"\n\t></PadSettingsDialog>\n\n\t<ShareDialog\n\t\tv-if=\"dialog === 'share'\"\n\t\t@hidden=\"dialog = undefined\"\n\t></ShareDialog>\n\n\t<KeepAlive>\n\t\t<ExportDialog\n\t\t\tv-if=\"dialog === 'export'\"\n\t\t\t@hidden=\"dialog = undefined\"\n\t\t></ExportDialog>\n\t</KeepAlive>\n\n\t<EditFilterDialog\n\t\tv-if=\"dialog === 'edit-filter' && client.padData\"\n\t\t@hidden=\"dialog = undefined\"\n\t></EditFilterDialog>\n\n\t<HistoryDialog\n\t\tv-if=\"dialog === 'history' && client.padData\"\n\t\t@hidden=\"dialog = undefined\"\n\t></HistoryDialog>\n\n\t<UserPreferencesDialog\n\t\tv-if=\"dialog === 'user-preferences'\"\n\t\t@hidden=\"dialog = undefined\"\n\t></UserPreferencesDialog>\n</template>","<script setup lang=\"ts\">\n\timport { getCurrentView, getLayers } from \"facilmap-leaflet\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport { computed, ref } from \"vue\";\n\timport { getUniqueId, getZodValidator, validateRequired } from \"../utils/utils\";\n\timport { formatCoordinates } from \"facilmap-utils\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport ValidatedField from \"./ui/validated-form/validated-field.vue\";\n\timport { viewValidator } from \"facilmap-types\";\n\timport { T, useI18n } from \"../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst client = requireClientContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst id = getUniqueId(\"fm-save-view\");\n\n\tconst name = ref(\"\");\n\tconst includeOverpass = ref(false);\n\tconst includeFilter = ref(false);\n\tconst makeDefault = ref(false);\n\n\tconst modalRef = ref<InstanceType<typeof ModalDialog>>();\n\n\tconst baseLayer = computed(() => {\n\t\tconst { baseLayers } = getLayers(mapContext.value.components.map);\n\t\treturn baseLayers[mapContext.value.layers.baseLayer].options.fmName || mapContext.value.layers.baseLayer;\n\t});\n\n\tconst overlays = computed(() => {\n\t\tconst { overlays } = getLayers(mapContext.value.components.map);\n\t\treturn mapContext.value.layers.overlays.map((key) => overlays[key].options.fmName || key).join(i18n.t(\"save-view-dialog.overlays-joiner\")) || i18n.t(\"save-view-dialog.empty\");\n\t});\n\n\tasync function save(): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-save-view-error`);\n\n\t\ttry {\n\t\t\tconst view = await client.value.addView({\n\t\t\t\t...getCurrentView(mapContext.value.components.map, {\n\t\t\t\t\tincludeFilter: includeFilter.value,\n\t\t\t\t\toverpassLayer: includeOverpass.value ? mapContext.value.components.overpassLayer : undefined\n\t\t\t\t}),\n\t\t\t\tname: name.value\n\t\t\t});\n\n\t\t\tif (makeDefault.value) {\n\t\t\t\tawait client.value.editPad({ defaultViewId: view.id });\n\t\t\t}\n\n\t\t\tmodalRef.value?.modal.hide();\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-save-view-error`, () => i18n.t(\"save-view-dialog.save-view-error\"), err);\n\t\t}\n\t};\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('save-view-dialog.title')\"\n\t\tclass=\"fm-save-view\"\n\t\t:isCreate=\"true\"\n\t\tref=\"modalRef\"\n\t\t@submit=\"$event.waitUntil(save())\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-name-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.name\")}}</label>\n\t\t\t<ValidatedField\n\t\t\t\t:value=\"name\"\n\t\t\t\t:validators=\"[\n\t\t\t\t\tvalidateRequired,\n\t\t\t\t\tgetZodValidator(viewValidator.update.shape.name)\n\t\t\t\t]\"\n\t\t\t\tclass=\"col-sm-9 position-relative\"\n\t\t\t>\n\t\t\t\t<template #default=\"slotProps\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclass=\"form-control\"\n\t\t\t\t\t\t:id=\"`${id}-name-input`\"\n\t\t\t\t\t\tv-model=\"name\"\n\t\t\t\t\t\t:ref=\"slotProps.inputRef\"\n\t\t\t\t\t/>\n\t\t\t\t\t<div class=\"invalid-tooltip\">\n\t\t\t\t\t\t{{slotProps.validationError}}\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t</ValidatedField>\n\t\t</div>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-topleft-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.top-left\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<input\n\t\t\t\t\tclass=\"form-control-plaintext\"\n\t\t\t\t\treadonly\n\t\t\t\t\t:id=\"`${id}-topleft-input`\"\n\t\t\t\t\t:value=\"formatCoordinates({ lat: mapContext.bounds.getNorth(), lon: mapContext.bounds.getWest() })\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-bottomright-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.bottom-right\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<input\n\t\t\t\t\tclass=\"form-control-plaintext\"\n\t\t\t\t\treadonly\n\t\t\t\t\t:id=\"`${id}-bottomright-input`\"\n\t\t\t\t\t:value=\"formatCoordinates({ lat: mapContext.bounds.getSouth(), lon: mapContext.bounds.getEast() })\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-base-layer-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.base-layer\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<input\n\t\t\t\t\tclass=\"form-control-plaintext\"\n\t\t\t\t\treadonly\n\t\t\t\t\t:id=\"`${id}-base-layer-input`\"\n\t\t\t\t\t:value=\"baseLayer\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-overlays-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.overlays\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<input\n\t\t\t\t\tclass=\"form-control-plaintext\"\n\t\t\t\t\treadonly\n\t\t\t\t\t:id=\"`${id}-overlays-input`\"\n\t\t\t\t\t:value=\"overlays\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<template v-if=\"mapContext.overpassIsCustom ? !mapContext.overpassCustom : mapContext.overpassPresets.length == 0\">\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-overpass-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.pois\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclass=\"form-control-plaintext\"\n\t\t\t\t\t\treadonly\n\t\t\t\t\t\t:id=\"`${id}-overpass-input`\"\n\t\t\t\t\t\t:value=\"i18n.t('save-view-dialog.empty')\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<template v-else>\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-overpass-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.pois\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t:id=\"`${id}-overpass-input`\"\n\t\t\t\t\t\t\tv-model=\"includeOverpass\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<label class=\"form-check-label\" :for=\"`${id}-overpass-input`\">\n\t\t\t\t\t\t\t<T k=\"save-view-dialog.include-pois\">\n\t\t\t\t\t\t\t\t<template #pois>\n\t\t\t\t\t\t\t\t\t<code v-if=\"mapContext.overpassIsCustom\">{{mapContext.overpassCustom}}</code><template v-else>{{mapContext.overpassPresets.map((p) => p.label).join(i18n.t(\"save-view-dialog.include-pois-interpolation-pois-joiner\"))}}</template>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<template v-if=\"!mapContext.filter\">\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-filter-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.filter\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<input class=\"form-control-plaintext\" :id=\"`${id}-filter-input`\" :value=\"i18n.t('save-view-dialog.empty')\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<template v-else>\n\t\t\t<div class=\"row mb-3\">\n\t\t\t\t<label :for=\"`${id}-filter-checkbox`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.filter\")}}</label>\n\t\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t\t:id=\"`${id}-filter-checkbox`\"\n\t\t\t\t\t\t\tv-model=\"includeFilter\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<label :for=\"`${id}-filter-checkbox`\" class=\"form-check-label\">\n\t\t\t\t\t\t\t<T k=\"save-view-dialog.include-current-filter\">\n\t\t\t\t\t\t\t\t<template #filter>\n\t\t\t\t\t\t\t\t\t<code>{{mapContext.filter}}</code>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</T>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<div class=\"row mb-3\">\n\t\t\t<label :for=\"`${id}-make-default-input`\" class=\"col-sm-3 col-form-label\">{{i18n.t(\"save-view-dialog.default-view\")}}</label>\n\t\t\t<div class=\"col-sm-9\">\n\t\t\t\t<div class=\"form-check fm-form-check-with-label\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclass=\"form-check-input\"\n\t\t\t\t\t\t:id=\"`${id}-make-default-input`\"\n\t\t\t\t\t\tv-model=\"makeDefault\"\n\t\t\t\t\t/>\n\t\t\t\t\t<label :for=\"`${id}-make-default-input`\" class=\"form-check-label\">{{i18n.t(\"save-view-dialog.make-default\")}}</label>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</ModalDialog>\n</template>\n\n<style lang=\"scss\">\n</style>","<script setup lang=\"ts\">\n\timport type { ID, View } from \"facilmap-types\";\n\timport { displayView } from \"facilmap-leaflet\";\n\timport { computed, ref, watchEffect } from \"vue\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport { showConfirm } from \"./ui/alert.vue\";\n\timport ModalDialog from \"./ui/modal-dialog.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { getOrderedViews } from \"facilmap-utils\";\n\timport Draggable from \"vuedraggable\";\n\timport Icon from \"./ui/icon.vue\";\n\timport { useI18n } from \"../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst isSavingDefaultView = ref<ID>();\n\tconst isMoving = ref<ID>();\n\tconst isDeleting = ref(new Set<ID>());\n\n\tconst isBusy = computed(() => {\n\t\treturn isSavingDefaultView.value != null || isDeleting.value.size > 0 || isMoving.value != null;\n\t});\n\n\tfunction display(view: View): void {\n\t\tdisplayView(mapContext.value.components.map, view, { overpassLayer: mapContext.value.components.overpassLayer });\n\t};\n\n\tasync function makeDefault(view: View): Promise<void> {\n\t\tisSavingDefaultView.value = view.id;\n\t\ttoasts.hideToast(`fm${context.id}-save-view-error-default`);\n\n\t\ttry {\n\t\t\tawait client.value.editPad({ defaultViewId: view.id });\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-save-view-error-default`, () => i18n.t(\"manage-views-dialog.default-view-error\"), err);\n\t\t} finally {\n\t\t\tisSavingDefaultView.value = undefined;\n\t\t}\n\t};\n\n\tasync function deleteView(view: View): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-save-view-error-${view.id}`);\n\n\t\ttry {\n\t\t\tif (!await showConfirm({\n\t\t\t\ttitle: i18n.t(\"manage-views-dialog.delete-view-title\"),\n\t\t\t\tmessage: i18n.t(\"manage-views-dialog.delete-view-message\", { viewName: view.name }),\n\t\t\t\tvariant: \"danger\",\n\t\t\t\tokLabel: i18n.t(\"manage-views-dialog.delete-view-ok\")\n\t\t\t}))\n\t\t\t\treturn;\n\n\t\t\tisDeleting.value.add(view.id);\n\n\t\t\tawait client.value.deleteView({ id: view.id });\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-save-view-error-${view.id}`, () => i18n.t(\"manage-views-dialog.delete-view-error\", { viewName: view.name }), err);\n\t\t} finally {\n\t\t\tisDeleting.value.delete(view.id);\n\t\t}\n\t};\n\n\tconst orderedViews = ref<View[]>([]);\n\twatchEffect(() => {\n\t\tif (isMoving.value == null) {\n\t\t\torderedViews.value = getOrderedViews(client.value.views);\n\t\t}\n\t});\n\n\tconst handleDrag = toasts.toastErrors(async (e: any) => {\n\t\tif (e.moved) {\n\t\t\tisMoving.value = e.moved.element.id;\n\n\t\t\ttry {\n\t\t\t\t// This handler is called when orderedViews is already reordered\n\t\t\t\tconst newIdx = e.moved.newIndex === 0 ? 0 : (orderedViews.value[e.moved.newIndex - 1].idx + 1);\n\t\t\t\tawait client.value.editView({\n\t\t\t\t\tid: e.moved.element.id,\n\t\t\t\t\tidx: newIdx\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tisMoving.value = undefined;\n\t\t\t}\n\t\t}\n\t});\n</script>\n\n<template>\n\t<ModalDialog\n\t\t:title=\"i18n.t('manage-views-dialog.title')\"\n\t\t:isBusy=\"isBusy\"\n\t\tsize=\"lg\"\n\t\tclass=\"fm-manage-views\"\n\t\t@hidden=\"emit('hidden')\"\n\t>\n\t\t<table class=\"table table-striped table-hover\">\n\t\t\t<Draggable\n\t\t\t\tv-model=\"orderedViews\"\n\t\t\t\ttag=\"tbody\"\n\t\t\t\thandle=\".fm-drag-handle\"\n\t\t\t\titemKey=\"id\"\n\t\t\t\t@change=\"handleDrag\"\n\t\t\t>\n\t\t\t\t<template #item=\"{ element: view }\">\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td\n\t\t\t\t\t\t\tclass=\"text-break align-middle\"\n\t\t\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t\t\t'font-weight-bold': client.padData?.defaultView && view.id == client.padData.defaultView.id\n\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"display(view)\">{{view.name}}</a>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td class=\"td-buttons text-right align-middle\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t\t\t\tv-show=\"!client.padData?.defaultView || view.id !== client.padData.defaultView.id\"\n\t\t\t\t\t\t\t\t@click=\"makeDefault(view)\"\n\t\t\t\t\t\t\t\t:disabled=\"!!isSavingDefaultView || isDeleting.has(view.id)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div v-if=\"isSavingDefaultView == view.id\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t\t{{i18n.t(\"manage-views-dialog.make-default\")}}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"btn btn-secondary\"\n\t\t\t\t\t\t\t\t@click=\"deleteView(view)\"\n\t\t\t\t\t\t\t\t:disabled=\"isDeleting.has(view.id) || isSavingDefaultView == view.id || isMoving != null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div v-if=\"isDeleting.has(view.id)\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t\t{{i18n.t(\"manage-views-dialog.delete\")}}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"btn btn-secondary fm-drag-handle\"\n\t\t\t\t\t\t\t\t:disabled=\"isDeleting.has(view.id) || isMoving != null\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div v-if=\"isMoving === view.id\" class=\"spinner-border spinner-border-sm\"></div>\n\t\t\t\t\t\t\t\t<Icon v-else icon=\"resize-vertical\" :alt=\"i18n.t('manage-views-dialog.reorder-alt')\"></Icon>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</template>\n\t\t\t</Draggable>\n\t\t</table>\n\t</ModalDialog>\n</template>","<script setup lang=\"ts\">\n\timport { displayView } from \"facilmap-leaflet\";\n\timport type { View } from \"facilmap-types\";\n\timport SaveViewDialog from \"../save-view-dialog.vue\";\n\timport ManageViewsDialog from \"../manage-views-dialog.vue\";\n\timport { computed, ref } from \"vue\";\n\timport DropdownMenu from \"../ui/dropdown-menu.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { getOrderedViews } from \"facilmap-utils\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst emit = defineEmits<{\n\t\t\"hide-sidebar\": [];\n\t}>();\n\n\tconst dialog = ref<\n\t\t| \"save-view\"\n\t\t| \"manage-views\"\n\t>();\n\n\tconst orderedViews = computed(() => getOrderedViews(client.value.views));\n\n\tfunction doDisplayView(view: View): void {\n\t\tdisplayView(mapContext.value.components.map, view, { overpassLayer: mapContext.value.components.overpassLayer });\n\t}\n</script>\n\n<template>\n\t<DropdownMenu\n\t\ttag=\"li\"\n\t\tclass=\"nav-item\"\n\t\tisLink\n\t\tbuttonClass=\"nav-link\"\n\t\tmenuClass=\"dropdown-menu-end\"\n\t\t:label=\"i18n.t('toolbox-views-dropdown.label')\"\n\t>\n\t\t<li v-for=\"view in orderedViews\" :key=\"view.id\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"doDisplayView(view); emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{view.name}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"client.writable == 2 && orderedViews.length > 0\">\n\t\t\t<hr class=\"dropdown-divider\">\n\t\t</li>\n\n\t\t<li v-if=\"client.writable == 2\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'save-view'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-views-dropdown.save-current-view\")}}</a>\n\t\t</li>\n\n\t\t<li v-if=\"client.writable == 2 && orderedViews.length > 0\">\n\t\t\t<a\n\t\t\t\tclass=\"dropdown-item\"\n\t\t\t\thref=\"javascript:\"\n\t\t\t\t@click=\"dialog = 'manage-views'; emit('hide-sidebar')\"\n\t\t\t\tdraggable=\"false\"\n\t\t\t>{{i18n.t(\"toolbox-views-dropdown.manage-views\")}}</a>\n\t\t</li>\n\t</DropdownMenu>\n\n\t<SaveViewDialog\n\t\tv-if=\"dialog === 'save-view' && client.padData\"\n\t\t@hidden=\"dialog = undefined\"\n\t></SaveViewDialog>\n\n\t<ManageViewsDialog\n\t\tv-if=\"dialog === 'manage-views' && client.padData\"\n\t\t@hidden=\"dialog = undefined\"\n\t></ManageViewsDialog>\n</template>","<script setup lang=\"ts\">\n\timport hammer from \"hammerjs\";\n\timport { ref, watchEffect } from \"vue\";\n\timport { useRefWithOverride } from \"../../utils/vue\";\n\timport { injectContextRequired } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\n\tconst context = injectContextRequired();\n\n\tconst props = withDefaults(defineProps<{\n\t\tvisible?: boolean;\n\t}>(), {\n\t\tvisible: undefined\n\t});\n\n\tconst emit = defineEmits<{\n\t\t\"update:visible\": [visible: boolean];\n\t}>();\n\n\tconst isDragging = ref(false);\n\n\tconst innerSidebarRef = ref<HTMLElement>();\n\n\tconst sidebarVisible = useRefWithOverride(false, () => props.visible, (visible) => {\n\t\temit(\"update:visible\", visible);\n\t});\n\n\twatchEffect((onCleanup) => {\n\t\tif (innerSidebarRef.value) {\n\t\t\tconst pan = new hammer.Manager(innerSidebarRef.value);\n\t\t\tpan.add(new hammer.Pan({ direction: hammer.DIRECTION_RIGHT }));\n\t\t\tpan.on(\"panstart\", handleDragStart);\n\t\t\tpan.on(\"pan\", handleDragMove);\n\t\t\tpan.on(\"panend\", handleDragEnd);\n\n\t\t\tonCleanup(() => {\n\t\t\t\tpan.destroy();\n\t\t\t});\n\t\t}\n\t});\n\n\tfunction handleDragStart(): void {\n\t\tisDragging.value = true;\n\t}\n\n\tfunction handleDragMove(event: any): void {\n\t\tObject.assign(innerSidebarRef.value!.style, {\n\t\t\ttransform: `translateX(${Math.max(0, event.deltaX)}px)`,\n\t\t\ttransition: \"none\"\n\t\t});\n\t}\n\n\tfunction handleDragEnd(event: any): void {\n\t\tisDragging.value = false;\n\n\t\tObject.assign(innerSidebarRef.value!.style, {\n\t\t\ttransform: \"\",\n\t\t\ttransition: \"\"\n\t\t});\n\n\t\tif (event.velocityX > 0.3 || event.deltaX > innerSidebarRef.value!.offsetWidth / 2) {\n\t\t\tsidebarVisible.value = false;\n\t\t}\n\t}\n\n\tfunction handleSidebarKeyDown(event: KeyboardEvent): void {\n\t\tif (event.key === \"Escape\") {\n\t\t\tsidebarVisible.value = false;\n\t\t}\n\t}\n\n\tfunction handleBackdropClick(): void {\n\t\tsidebarVisible.value = false;\n\t}\n</script>\n\n<template>\n\t<div class=\"fm-sidebar\" :class=\"{ isNarrow: context.isNarrow, isDragging }\">\n\t\t<template v-if=\"context.isNarrow\">\n\t\t\t<div class=\"fm-sidebar-outer\" @keydown=\"handleSidebarKeyDown\" :class=\"{ show: sidebarVisible }\">\n\t\t\t\t<div class=\"fm-sidebar-backdrop bg-dark\" @click=\"handleBackdropClick\"></div>\n\t\t\t\t<div class=\"fm-sidebar-inner bg-body\" ref=\"innerSidebarRef\" :class=\"{ shadow: sidebarVisible }\">\n\t\t\t\t\t<nav class=\"navbar\">\n\t\t\t\t\t\t<div class=\"container-fluid\">\n\t\t\t\t\t\t\t<slot></slot>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</nav>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<nav v-if=\"!context.isNarrow\" class=\"navbar navbar-expand bg-light\">\n\t\t\t<div class=\"container-fluid\">\n\t\t\t\t<slot></slot>\n\t\t\t</div>\n\t\t</nav>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-sidebar {\n\n\t\t&.isDragging .fm-sidebar-inner {\n\t\t\tcursor: grabbing;\n\n\t\t\t> * {\n\t\t\t\t// Prevent click event on drag end (see https://stackoverflow.com/a/59957886/242365)\n\t\t\t\tpointer-events: none;\n\t\t\t}\n\t\t}\n\n\t\t.navbar-toggler {\n\t\t\tposition: absolute;\n\t\t\ttop: 10px;\n\t\t\tright: 10px;\n\t\t}\n\n\t\t.fm-sidebar-outer {\n\t\t\tposition: absolute;\n\t\t\ttop: 0;\n\t\t\tright: 0;\n\t\t\tbottom: 0;\n\t\t\tleft: 0;\n\t\t\tz-index: 1035;\n\t\t\tpointer-events: none;\n\n\t\t\t&.show {\n\t\t\t\tpointer-events: auto;\n\t\t\t}\n\t\t}\n\n\t\t.fm-sidebar-backdrop {\n\t\t\tposition: fixed;\n\t\t\ttop: 0;\n\t\t\tright: 0;\n\t\t\tbottom: 0;\n\t\t\tleft: 0;\n\t\t\tz-index: -1;\n\t\t\topacity: 0;\n\t\t\ttransition: opacity 0.3s;\n\t\t}\n\n\t\t.fm-sidebar-outer.show .fm-sidebar-backdrop {\n\t\t\topacity: 0.6;\n\t\t}\n\n\t\t.fm-sidebar-inner {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\tposition: fixed;\n\t\t\ttop: 0;\n\t\t\tright: 0;\n\t\t\twidth: 320px;\n\t\t\tmax-width: 80%;\n\t\t\theight: 100%;\n\t\t\toverflow: auto;\n\t\t\ttouch-action: pan-y;\n\t\t\ttransform: translateX(100%);\n\t\t\ttransition: transform 0.3s, box-shadow 0.3s;\n\t\t}\n\n\t\t.fm-sidebar-outer.show .fm-sidebar-inner {\n\t\t\ttransform: translateX(0);\n\t\t}\n\n\t\t&.isNarrow {\n\t\t\t&, .dropdown-menu {\n\t\t\t\tfont-size: 14px;\n\t\t\t}\n\t\t}\n\n\t}\n</style>","<script setup lang=\"ts\">\n\timport Sidebar from \"../ui/sidebar.vue\";\n\timport Icon from \"../ui/icon.vue\";\n\timport { ref } from \"vue\";\n\timport ToolboxAddDropdown from \"./toolbox-add-dropdown.vue\";\n\timport ToolboxCollabMapsDropdown from \"./toolbox-collab-maps-dropdown.vue\";\n\timport ToolboxHelpDropdown from \"./toolbox-help-dropdown.vue\";\n\timport ToolboxMapStyleDropdown from \"./toolbox-map-style-dropdown.vue\";\n\timport ToolboxToolsDropdown from \"./toolbox-tools-dropdown.vue\";\n\timport ToolboxViewsDropdown from \"./toolbox-views-dropdown.vue\";\n\timport { injectContextRequired, requireClientContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\n\tconst props = withDefaults(defineProps<{\n\t\tinteractive?: boolean;\n\t}>(), {\n\t\tinteractive: true\n\t});\n\n\tconst sidebarVisible = ref(false);\n</script>\n\n<template>\n\t<div class=\"fm-toolbox\">\n\t\t<a\n\t\t\tv-if=\"context.isNarrow\"\n\t\t\tv-show=\"!sidebarVisible\"\n\t\t\thref=\"javascript:\"\n\t\t\tclass=\"fm-toolbox-toggle\"\n\t\t\t@click=\"sidebarVisible = true\"\n\t\t><Icon icon=\"menu-hamburger\"></Icon></a>\n\n\t\t<Sidebar :id=\"`fm${context.id}-toolbox-sidebar`\" v-model:visible=\"sidebarVisible\">\n\t\t\t<ul class=\"navbar-nav\">\n\t\t\t\t<ToolboxCollabMapsDropdown\n\t\t\t\t\tv-if=\"props.interactive\"\n\t\t\t\t\t@hide-sidebar=\"sidebarVisible = false\"\n\t\t\t\t></ToolboxCollabMapsDropdown>\n\n\t\t\t\t<ToolboxAddDropdown\n\t\t\t\t\tv-if=\"!client.readonly && client.padData\"\n\t\t\t\t\t@hide-sidebar=\"sidebarVisible = false\"\n\t\t\t\t></ToolboxAddDropdown>\n\n\t\t\t\t<ToolboxViewsDropdown\n\t\t\t\t\tv-if=\"client.padData && (!client.readonly || Object.keys(client.views).length > 0)\"\n\t\t\t\t\t@hide-sidebar=\"sidebarVisible = false\"\n\t\t\t\t></ToolboxViewsDropdown>\n\n\t\t\t\t<ToolboxMapStyleDropdown></ToolboxMapStyleDropdown>\n\n\t\t\t\t<ToolboxToolsDropdown\n\t\t\t\t\tv-if=\"props.interactive || client.padData\"\n\t\t\t\t\t:interactive=\"props.interactive\"\n\t\t\t\t\t@hide-sidebar=\"sidebarVisible = false\"\n\t\t\t\t></ToolboxToolsDropdown>\n\n\t\t\t\t<ToolboxHelpDropdown\n\t\t\t\t\t@hide-sidebar=\"sidebarVisible = false\"\n\t\t\t\t></ToolboxHelpDropdown>\n\t\t\t</ul>\n\t\t</Sidebar>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-toolbox {\n\t\tposition: absolute;\n\t\ttop: 10px;\n\t\tright: 10px;\n\n\t\t&:hover {\n\t\t\tz-index: 1000;\n\t\t}\n\n\t\t.fm-toolbox-toggle {\n\t\t\tcolor: #444;\n\t\t\tborder-radius: 4px;\n\t\t\tbackground: #fff;\n\t\t\tborder: 2px solid rgba(0,0,0,0.2);\n\t\t\twidth: 34px;\n\t\t\theight: 34px;\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\n\t\t\t&:hover {\n\t\t\t\tbackground: #f4f4f4;\n\t\t\t}\n\t\t}\n\n\t\t.fm-sidebar.isNarrow {\n\t\t\t.navbar-nav {\n\t\t\t\tmax-width: 100%;\n\t\t\t}\n\t\t}\n\n\t\t.fm-sidebar:not(.isNarrow) {\n\t\t\topacity: .5;\n\t\t\ttransition: opacity .7s;\n\n\t\t\t&:hover {\n\t\t\t\topacity: 1;\n\t\t\t}\n\t\t}\n\n\t\t.fm-toolbox-new-window-item {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\n\t\t\t> span:nth-child(1) {\n\t\t\t\tflex-grow: 1;\n\t\t\t}\n\n\t\t\t> span:nth-child(2) {\n\t\t\t\tdisplay: inline-flex;\n\t\t\t\tmargin-left: 0.5rem;\n\t\t\t}\n\t\t}\n\n\t\t@media print {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { computed, onBeforeUnmount, onMounted } from \"vue\";\n\timport { useToasts } from \"./toasts.vue\";\n\timport type { ToastAction } from \"./toasts.vue\";\n\timport type { ThemeColour } from \"../../../utils/bootstrap\";\n\n\t/* eslint-disable vue/valid-template-root */\n\n\tconst toasts = useToasts();\n\n\tconst props = defineProps<{\n\t\tid: string;\n\t\ttitle: string;\n\t\tmessage: string | Error;\n\t\tactions?: ToastAction[];\n\t\tspinner?: boolean;\n\t\tvariant?: ThemeColour;\n\t\tnoCloseButton?: boolean;\n\t\tautoHide?: boolean;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\thidden: [];\n\t}>();\n\n\tconst resolvedOptions = computed(() => ({\n\t\tactions: props.actions,\n\t\tspinner: props.spinner,\n\t\tvariant: props.variant,\n\t\tnoCloseButton: props.noCloseButton,\n\t\tautoHide: props.autoHide,\n\t\tonHidden: () => {\n\t\t\temit(\"hidden\");\n\t\t}\n\t}));\n\n\tonMounted(() => {\n\t\tif (props.message instanceof Error) {\n\t\t\ttoasts.showErrorToast(props.id, () => props.title, props.message, () => resolvedOptions.value);\n\t\t} else {\n\t\t\ttoasts.showToast(props.id, () => props.title, () => props.message as string, () => resolvedOptions.value);\n\t\t}\n\t});\n\n\tonBeforeUnmount(() => {\n\t\ttoasts.hideToast(props.id);\n\t});\n</script>\n\n<template>\n</template>","<script setup lang=\"ts\">\n\timport type { SearchResult } from \"facilmap-types\";\n\timport { find, formatCoordinates, getCurrentLanguage, getElevationForPoint, getFallbackLonLatResult } from \"facilmap-utils\";\n\timport { SearchResultsLayer } from \"facilmap-leaflet\";\n\timport SearchResultInfo from \"./search-result-info.vue\";\n\timport { Util } from \"leaflet\";\n\timport { computed, markRaw, nextTick, reactive, readonly, ref, toRef, watch, type Raw } from \"vue\";\n\timport { useEventListener } from \"../utils/utils\";\n\timport SearchBoxTab from \"./search-box/search-box-tab.vue\"\n\timport { injectContextRequired, requireMapContext, requireSearchBoxContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport type { WritableClickMarkerTabContext } from \"./facil-map-context-provider/click-marker-tab-context\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport { isLanguageExplicit, useI18n } from \"../utils/i18n\";\n\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst searchBoxContext = requireSearchBoxContext(context);\n\n\ttype Tab = {\n\t\tid: number;\n\t\tresult: SearchResult;\n\t\tlayer: Raw<SearchResultsLayer>;\n\t\tisLoading: boolean;\n\t};\n\n\tconst tabs = ref<Tab[]>([]);\n\n\tuseEventListener(mapContext, \"open-selection\", handleOpenSelection);\n\n\tconst layerIds = computed(() => tabs.value.map((tab) => Util.stamp(tab.layer)));\n\n\twatch(() => mapContext.value.selection, () => {\n\t\tfor (let i = tabs.value.length - 1; i >= 0; i--) {\n\t\t\tif (!mapContext.value.selection.some((item) => item.type == \"searchResult\" && item.layerId == layerIds.value[i]))\n\t\t\t\tclose(tabs.value[i]);\n\t\t}\n\t});\n\n\tlet idCounter = 1;\n\n\tconst clickMarkerTabContext = ref<WritableClickMarkerTabContext>({\n\t\tasync openClickMarker(point) {\n\t\t\tconst result = reactive(getFallbackLonLatResult({ lat: point.lat, lon: point.lon, zoom: mapContext.value.zoom }));\n\n\t\t\tconst layer = markRaw(new SearchResultsLayer([result]).addTo(mapContext.value.components.map));\n\t\t\tmapContext.value.components.selectionHandler.addSearchResultLayer(layer);\n\n\t\t\tconst tab = reactive<Tab>({\n\t\t\t\tid: idCounter++,\n\t\t\t\tresult,\n\t\t\t\tlayer,\n\t\t\t\tisLoading: true\n\t\t\t});\n\n\t\t\ttabs.value.push(tab);\n\n\t\t\tmapContext.value.components.selectionHandler.setSelectedItems([{ type: \"searchResult\", result, layerId: Util.stamp(layer) }]);\n\n\t\t\tawait nextTick();\n\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-click-marker-tab-${tabs.value.length - 1}`, { expand: true });\n\n\t\t\t(async () => {\n\t\t\t\tconst results = await mapContext.value.runOperation(async () => (\n\t\t\t\t\tawait find(`geo:${formatCoordinates(point)}?z=${mapContext.value.zoom}`, {\n\t\t\t\t\t\tlang: isLanguageExplicit() ? getCurrentLanguage() : undefined\n\t\t\t\t\t})\n\t\t\t\t));\n\n\t\t\t\tif (results.length > 0) {\n\t\t\t\t\ttab.result = { ...results[0], elevation: tab.result.elevation };\n\t\t\t\t}\n\n\t\t\t\ttab.isLoading = false;\n\t\t\t})().catch((err) => {\n\t\t\t\ttoasts.showErrorToast(`find-error-${tab.id}`, () => i18n.t(\"click-marker-tab.look-up-error\"), err);\n\t\t\t});\n\n\t\t\t(async () => {\n\t\t\t\tconst elevation = await getElevationForPoint(point);\n\t\t\t\tif (elevation != null) {\n\t\t\t\t\ttab.result.elevation = elevation;\n\t\t\t\t}\n\t\t\t})().catch((err) => {\n\t\t\t\tconsole.warn(\"Error fetching click marker elevation\", err);\n\t\t\t});\n\t\t},\n\n\t\tcloseLastClickMarker() {\n\t\t\tif (tabs.value.length > 0) {\n\t\t\t\tclose(tabs.value[tabs.value.length - 1]);\n\t\t\t}\n\t\t}\n\t});\n\n\tcontext.provideComponent(\"clickMarkerTab\", toRef(readonly(clickMarkerTabContext)));\n\n\tfunction handleOpenSelection(): void {\n\t\tfor (let i = 0; i < layerIds.value.length; i++) {\n\t\t\tif (mapContext.value.selection.some((item) => item.type == \"searchResult\" && item.layerId == layerIds.value[i])) {\n\t\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-click-marker-tab-${i}`, { expand: true });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction close(tab: Tab): void {\n\t\tconst idx = tabs.value.indexOf(tab);\n\t\tif (idx == -1)\n\t\t\treturn;\n\n\t\ttoasts.hideToast(`find-error-${tab.id}`);\n\t\tmapContext.value.components.selectionHandler.removeSearchResultLayer(tab.layer);\n\t\ttab.layer.remove();\n\t\ttabs.value.splice(idx, 1);\n\t}\n</script>\n\n<template>\n\t<template v-for=\"(tab, idx) in tabs\" :key=\"tab.id\">\n\t\t<SearchBoxTab\n\t\t\t:id=\"`fm${context.id}-click-marker-tab-${idx}`\"\n\t\t\t:title=\"tab.result.short_name\"\n\t\t\tisCloseable\n\t\t\t@close=\"close(tab)\"\n\t\t>\n\t\t\t<SearchResultInfo :result=\"tab.result\" :isLoading=\"tab.isLoading\"></SearchResultInfo>\n\t\t</SearchBoxTab>\n\t</template>\n</template>","<script lang=\"ts\">\n\timport { computed, onBeforeUnmount, reactive, ref, toRaw, watch } from \"vue\";\n\timport Client from \"facilmap-client\";\n\timport { PadNotFoundError, type PadData, type PadId } from \"facilmap-types\";\n\timport PadSettingsDialog from \"./pad-settings-dialog/pad-settings-dialog.vue\";\n\timport storage from \"../utils/storage\";\n\timport { type ToastAction } from \"./ui/toasts/toasts.vue\";\n\timport Toast from \"./ui/toasts/toast.vue\";\n\timport type { ClientContext } from \"./facil-map-context-provider/client-context\";\n\timport { injectContextRequired } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { isLanguageExplicit, isUnitsExplicit, useI18n } from \"../utils/i18n\";\n\timport { getCurrentLanguage, getCurrentUnits } from \"facilmap-utils\";\n\n\tfunction isPadNotFoundError(serverError: Client[\"serverError\"]): boolean {\n\t\treturn !!serverError && serverError instanceof PadNotFoundError;\n\t}\n</script>\n\n<script setup lang=\"ts\">\n\tconst context = injectContextRequired();\n\tconst i18n = useI18n();\n\n\tconst client = ref<ClientContext>();\n\tconst connectingClient = ref<ClientContext>();\n\n\tconst props = defineProps<{\n\t\tpadId: string | undefined;\n\t\tserverUrl: string;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:padId\": [padId: string | undefined];\n\t}>();\n\n\tfunction openPad(padId: string | undefined): void {\n\t\temit(\"update:padId\", padId);\n\t}\n\n\twatch([\n\t\t() => props.padId,\n\t\t() => props.serverUrl\n\t], async () => {\n\t\tconst existingClient = connectingClient.value || client.value;\n\t\tif (existingClient && existingClient.server == props.serverUrl && existingClient.padId == props.padId)\n\t\t\treturn;\n\n\t\tclass CustomClient extends Client implements ClientContext {\n\t\t\t_makeReactive<O extends object>(obj: O) {\n\t\t\t\treturn reactive(obj) as O;\n\t\t\t}\n\n\t\t\topenPad(padId: string | undefined) {\n\t\t\t\topenPad(padId);\n\t\t\t}\n\n\t\t\tget isCreatePad() {\n\t\t\t\treturn context.settings.interactive && isPadNotFoundError(super.serverError);\n\t\t\t}\n\t\t}\n\n\t\tconst newClient = new CustomClient(props.serverUrl, props.padId, {\n\t\t\tquery: {\n\t\t\t\t...isLanguageExplicit() ? { lang: getCurrentLanguage() } : {},\n\t\t\t\t...isUnitsExplicit() ? { units: getCurrentUnits() } : {}\n\t\t\t}\n\t\t});\n\t\tconnectingClient.value = newClient;\n\n\t\tlet lastPadId: PadId | undefined = undefined;\n\t\tlet lastPadData: PadData | undefined = undefined;\n\n\t\tnewClient.on(\"padData\", () => {\n\t\t\tfor (const bookmark of storage.bookmarks) {\n\t\t\t\tif (lastPadId && bookmark.id == lastPadId)\n\t\t\t\t\tbookmark.id = newClient.padId!;\n\n\t\t\t\tif (lastPadData && lastPadData.id == bookmark.padId)\n\t\t\t\t\tbookmark.padId = newClient.padData!.id;\n\n\t\t\t\tif (bookmark.padId == newClient.padData!.id)\n\t\t\t\t\tbookmark.name = newClient.padData!.name;\n\t\t\t}\n\n\t\t\tlastPadId = newClient.padId;\n\t\t\tlastPadData = newClient.padData;\n\t\t});\n\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tnewClient.once(props.padId ? \"padData\" : \"connect\", () => { resolve(); });\n\t\t\tnewClient.on(\"serverError\", () => { resolve(); });\n\t\t});\n\n\t\tif (toRaw(connectingClient.value) !== newClient) {\n\t\t\t// Another client has been initiated in the meantime\n\t\t\tnewClient.disconnect();\n\t\t\treturn;\n\t\t}\n\n\t\tconnectingClient.value = undefined;\n\t\tclient.value?.disconnect();\n\t\tclient.value = newClient;\n\t}, { immediate: true });\n\n\tonBeforeUnmount(() => {\n\t\tclient.value?.disconnect();\n\t});\n\n\tcontext.provideComponent(\"client\", client);\n\n\tfunction handleCreateDialogHide() {\n\t\tif (client.value?.isCreatePad) {\n\t\t\tclient.value.openPad(undefined);\n\t\t}\n\t}\n\n\tconst closeMapAction = computed<ToastAction>(() => ({\n\t\tlabel: i18n.t(\"client-provider.close-map\"),\n\t\thref: context.baseUrl,\n\t\tonClick: (e) => {\n\t\t\tif (!e.ctrlKey && !e.shiftKey && !e.metaKey && !e.altKey) {\n\t\t\t\te.preventDefault();\n\t\t\t\topenPad(undefined);\n\t\t\t}\n\t\t}\n\t}));\n</script>\n\n<template>\n\t<template v-if=\"connectingClient\">\n\t\t<Toast\n\t\t\t:id=\"`fm${context.id}-client-connecting`\"\n\t\t\t:title=\"props.padId ? i18n.t('client-provider.loading-map-header') : i18n.t('client-provider.connecting-header')\"\n\t\t\t:message=\"props.padId ? i18n.t('client-provider.loading-map') : i18n.t('client-provider.connecting')\"\n\t\t\tspinner\n\t\t\tnoCloseButton\n\t\t/>\n\t</template>\n\t<template v-else-if=\"client\">\n\t\t<template v-if=\"client.serverError && !client.isCreatePad\">\n\t\t\t<template v-if=\"client.disconnected || !props.padId\">\n\t\t\t\t<Toast\n\t\t\t\t\t:id=\"`fm${context.id}-client-error`\"\n\t\t\t\t\t:title=\"i18n.t('client-provider.connection-error')\"\n\t\t\t\t\t:message=\"client.serverError\"\n\t\t\t\t\t:noCloseButton=\"!!props.padId\"\n\t\t\t\t/>\n\t\t\t</template>\n\t\t\t<template v-else>\n\t\t\t\t<Toast\n\t\t\t\t\t:id=\"`fm${context.id}-client-error`\"\n\t\t\t\t\t:title=\"i18n.t('client-provider.open-map-error')\"\n\t\t\t\t\t:message=\"client.serverError\"\n\t\t\t\t\tnoCloseButton\n\t\t\t\t\t:actions=\"context.settings.interactive ? [closeMapAction] : []\"\n\t\t\t\t/>\n\t\t\t</template>\n\t\t</template>\n\t\t<template v-else-if=\"client.disconnected\">\n\t\t\t<Toast\n\t\t\t\t:id=\"`fm${context.id}-client-disconnected`\"\n\t\t\t\tvariant=\"danger\"\n\t\t\t\t:title=\"i18n.t('client-provider.disconnected-header')\"\n\t\t\t\t:message=\"i18n.t('client-provider.disconnected')\"\n\t\t\t\tno-close-button visible\n\t\t\t\tspinner\n\t\t\t/>\n\t\t</template>\n\t\t<template v-else-if=\"client.deleted\">\n\t\t\t<Toast\n\t\t\t\t:id=\"`fm${context.id}-client-deleted`\"\n\t\t\t\tvariant=\"danger\"\n\t\t\t\t:title=\"i18n.t('client-provider.map-deleted-header')\"\n\t\t\t\t:message=\"i18n.t('client-provider.map-deleted')\"\n\t\t\t\tnoCloseButton\n\t\t\t\t:actions=\"context.settings.interactive ? [closeMapAction] : []\"\n\t\t\t/>\n\t\t</template>\n\t</template>\n\n\t<PadSettingsDialog\n\t\tv-if=\"client?.isCreatePad\"\n\t\tisCreate\n\t\t:proposedAdminId=\"client.padId\"\n\t\t@hide=\"handleCreateDialogHide\"\n\t></PadSettingsDialog>\n</template>","<script setup lang=\"ts\">\n\timport { type FileResultObject, parseFiles } from \"../utils/files\";\n\timport pluralize from \"pluralize\";\n\timport { SearchResultsLayer } from \"facilmap-leaflet\";\n\timport { Util } from \"leaflet\";\n\timport FileResults from \"./file-results.vue\";\n\timport SearchBoxTab from \"./search-box/search-box-tab.vue\";\n\timport { computed, markRaw, readonly, ref, shallowReactive, toRef } from \"vue\";\n\timport { useDomEventListener, useEventListener } from \"../utils/utils\";\n\timport { useToasts } from \"./ui/toasts/toasts.vue\";\n\timport { injectContextRequired, requireMapContext, requireSearchBoxContext } from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport type { WritableImportTabContext } from \"./facil-map-context-provider/import-tab-context\";\n\timport { useI18n } from \"../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst searchBoxContext = requireSearchBoxContext(context);\n\tconst toasts = useToasts();\n\tconst i18n = useI18n();\n\n\tconst fileInputRef = ref<HTMLInputElement>();\n\n\tconst files = ref<Array<FileResultObject & { title: string }>>([]);\n\tconst layers = shallowReactive<SearchResultsLayer[]>([]);\n\n\tuseEventListener(mapContext, \"open-selection\", handleOpenSelection);\n\n\tuseDomEventListener(mapContext.value.components.container, \"dragenter\", handleMapDragEnter);\n\tuseDomEventListener(mapContext.value.components.container, \"dragover\", handleMapDragOver);\n\tuseDomEventListener(mapContext.value.components.container, \"drop\", handleMapDrop);\n\n\tconst layerIds = computed(() => layers.map((layer) => Util.stamp(layer)));\n\n\tconst importTabContext = ref<WritableImportTabContext>({\n\t\topenFilePicker() {\n\t\t\tfileInputRef.value?.click();\n\t\t}\n\t});\n\n\tcontext.provideComponent(\"importTab\", toRef(readonly(importTabContext)));\n\n\tfunction handleOpenSelection(): void {\n\t\tfor (let i = 0; i < layerIds.value.length; i++) {\n\t\t\tif (mapContext.value.selection.some((item) => item.type == \"searchResult\" && item.layerId == layerIds.value[i])) {\n\t\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-import-tab-${i}`, { expand: true });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction handleMapDragEnter(event: Event): void {\n\t\tevent.preventDefault();\n\t}\n\n\tfunction handleMapDragOver(event: Event): void {\n\t\tevent.preventDefault();\n\t}\n\n\tfunction handleMapDrop(event: Event): void {\n\t\tevent.preventDefault();\n\n\t\tvoid importFiles((event as DragEvent).dataTransfer?.files);\n\t}\n\n\tasync function importFiles(fileList: FileList | undefined): Promise<void> {\n\t\ttoasts.hideToast(`fm${context.id}-import-error`);\n\n\t\tif(!fileList || fileList.length == 0)\n\t\t\treturn;\n\n\t\ttry {\n\t\t\tconst loadedFiles = await Promise.all([...fileList].map((file) => new Promise<string>((resolve, reject) => {\n\t\t\t\tconst reader = new FileReader();\n\t\t\t\treader.onload = () => {\n\t\t\t\t\tresolve(reader.result as string);\n\t\t\t\t};\n\t\t\t\treader.onerror = () => {\n\t\t\t\t\treject(reader.error);\n\t\t\t\t};\n\t\t\t\treader.readAsText(file);\n\t\t\t})));\n\n\t\t\tconst result = {\n\t\t\t\t...await parseFiles(loadedFiles),\n\t\t\t\ttitle: (fileList.length == 1 && fileList[0].name) || pluralize(\"file\", fileList.length, true)\n\t\t\t};\n\t\t\tconst hasAnyItems = result.features.length > 0 || Object.keys(result.types).length > 0 || Object.keys(result.views).length > 0;\n\t\t\tif (!hasAnyItems && result.errors)\n\t\t\t\ttoasts.showErrorToast(`fm${context.id}-import-error`, () => i18n.t(\"import-tab.parse-error-title\"), () => i18n.t(\"import-tab.parse-error-message\", { count: fileList.length }));\n\t\t\telse if (!hasAnyItems)\n\t\t\t\ttoasts.showErrorToast(`fm${context.id}-import-error`, () => i18n.t(\"import-tab.no-geometries-error-title\"), () => i18n.t(\"import-tab.no-geometries-error-message\", { count: fileList.length }));\n\t\t\telse {\n\t\t\t\tif (result.errors)\n\t\t\t\t\ttoasts.showErrorToast(`fm${context.id}-import-error`, () => i18n.t(\"import-tab.partial-parse-error-title\"), () => i18n.t(\"import-tab.partial-parse-error-message\"), { variant: \"warning\" });\n\n\t\t\t\tconst layer = markRaw(new SearchResultsLayer(result.features, { pathOptions: { weight: 7 } }).addTo(mapContext.value.components.map));\n\t\t\t\tif (result.features.length > 0) {\n\t\t\t\t\tmapContext.value.components.map.flyToBounds(layer.getBounds());\n\t\t\t\t}\n\n\t\t\t\tmapContext.value.components.selectionHandler.addSearchResultLayer(layer);\n\n\t\t\t\tfiles.value.push(result);\n\t\t\t\tlayers.push(layer);\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-import-tab-${files.value.length - 1}`, { expand: true });\n\t\t\t\t}, 0);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\ttoasts.showErrorToast(`fm${context.id}-import-error`, () => i18n.t(\"import-tab.read-error-title\"), err);\n\t\t}\n\t}\n\n\tfunction close(idx: number): void {\n\t\tfiles.value.splice(idx, 1);\n\t\tmapContext.value.components.selectionHandler.removeSearchResultLayer(layers[idx]);\n\t\tlayers[idx].remove();\n\t\tlayers.splice(idx, 1);\n\t}\n</script>\n\n<template>\n\t<div>\n\t\t<input type=\"file\" multiple class=\"d-none\" ref=\"fileInputRef\" @change=\"importFiles(fileInputRef!.files ?? undefined)\">\n\t\t<template v-for=\"(file, idx) in files\" :key=\"idx\">\n\t\t\t<SearchBoxTab\n\t\t\t\t:id=\"`fm${context.id}-import-tab-${idx}`\"\n\t\t\t\tclass=\"fm-import-tab\"\n\t\t\t\tisCloseable\n\t\t\t\t:title=\"file.title\"\n\t\t\t\t@close=\"close(idx)\"\n\t\t\t>\n\t\t\t\t<FileResults\n\t\t\t\t\t:file=\"file\"\n\t\t\t\t\t:layer-id=\"layerIds[idx]\"\n\t\t\t\t\tauto-zoom\n\t\t\t\t></FileResults>\n\t\t\t</SearchBoxTab>\n\t\t</template>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-import-tab.fm-import-tab.fm-import-tab {\n\t\tpadding: 0.5rem;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { formatCoordinates, formatPOIName, renderOsmTag } from \"facilmap-utils\";\n\timport Icon from \"../ui/icon.vue\";\n\timport { getZoomDestinationForMarker } from \"../../utils/zoom\";\n\timport type { OverpassElement } from \"facilmap-leaflet\";\n\timport Coordinates from \"../ui/coordinates.vue\";\n\timport { computed } from \"vue\";\n\timport type { Type } from \"facilmap-types\";\n\timport UseAsDropdown from \"../ui/use-as-dropdown.vue\";\n\timport ZoomToObjectButton from \"../ui/zoom-to-object-button.vue\";\n\timport type { RouteDestination } from \"../facil-map-context-provider/route-form-tab-context\";\n\timport { overpassElementsToMarkersWithTags } from \"../../utils/add\";\n\timport AddToMapDropdown from \"../ui/add-to-map-dropdown.vue\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst i18n = useI18n();\n\n\tconst props = withDefaults(defineProps<{\n\t\telement: OverpassElement;\n\t\tshowBackButton?: boolean;\n\t\tisAdding?: boolean;\n\t}>(), {\n\t\tshowBackButton: false,\n\t\tisAdding: false\n\t});\n\n\tconst emit = defineEmits<{\n\t\tback: [];\n\t\t\"add-to-map\": [type: Type];\n\t}>();\n\n\tconst zoomDestination = computed(() => getZoomDestinationForMarker(props.element));\n\n\tconst routeDestination = computed<RouteDestination>(() => {\n\t\treturn {\n\t\t\tquery: formatCoordinates(props.element)\n\t\t};\n\t});\n\n\tconst markersWithTags = computed(() => overpassElementsToMarkersWithTags([props.element]));\n</script>\n\n<template>\n\t<div class=\"fm-overpass-info\">\n\t\t<h2>\n\t\t\t<a v-if=\"showBackButton\" href=\"javascript:\" @click=\"emit('back')\"><Icon icon=\"arrow-left\"></Icon></a>\n\t\t\t{{formatPOIName(element.tags.name)}}\n\t\t</h2>\n\t\t<dl class=\"fm-search-box-collapse-point fm-search-box-dl\">\n\t\t\t<dt>{{i18n.t(\"overpass-info.coordinates\")}}</dt>\n\t\t\t<dd><Coordinates :point=\"element\"></Coordinates></dd>\n\n\t\t\t<template v-for=\"(value, key) in element.tags\" :key=\"key\">\n\t\t\t\t<dt>{{key}}</dt>\n\t\t\t\t<dd v-html=\"renderOsmTag(key, value)\"></dd>\n\t\t\t</template>\n\t\t</dl>\n\n\t\t<div class=\"btn-toolbar\">\n\t\t\t<ZoomToObjectButton\n\t\t\t\t:label=\"i18n.t('overpass-info.zoom-to-object-label')\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\t:destination=\"zoomDestination\"\n\t\t\t></ZoomToObjectButton>\n\n\t\t\t<AddToMapDropdown\n\t\t\t\t:markers=\"markersWithTags\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\tisSingle\n\t\t\t></AddToMapDropdown>\n\n\t\t\t<UseAsDropdown\n\t\t\t\tsize=\"sm\"\n\t\t\t\t:isDisabled=\"isAdding\"\n\t\t\t\t:destination=\"routeDestination\"\n\t\t\t></UseAsDropdown>\n\t\t</div>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-overpass-info {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tmin-height: 0;\n\n\t\t.fm-search-box-collapse-point {\n\t\t\tmin-height: 1.5em;\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport { combineZoomDestinations, flyTo, getZoomDestinationForMarker } from \"../../utils/zoom\";\n\timport Icon from \"../ui/icon.vue\";\n\timport OverpassInfo from \"./overpass-info.vue\";\n\timport type { OverpassElement } from \"facilmap-leaflet\";\n\timport vTooltip from \"../../utils/tooltip\";\n\timport { computed, ref } from \"vue\";\n\timport { useCarousel } from \"../../utils/carousel\";\n\timport ZoomToObjectButton from \"../ui/zoom-to-object-button.vue\";\n\timport { injectContextRequired, requireClientContext, requireMapContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { overpassElementsToMarkersWithTags } from \"../../utils/add\";\n\timport AddToMapDropdown from \"../ui/add-to-map-dropdown.vue\";\n\timport { formatPOIName } from \"facilmap-utils\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst client = requireClientContext(context);\n\tconst mapContext = requireMapContext(context);\n\tconst i18n = useI18n();\n\n\tconst props = defineProps<{\n\t\telements: OverpassElement[];\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"click-element\": [element: OverpassElement, event: MouseEvent];\n\t}>();\n\n\tconst openedElement = ref<OverpassElement>();\n\n\tconst carouselRef = ref<HTMLElement>();\n\tconst carousel = useCarousel(carouselRef);\n\n\tfunction zoomToElement(element: OverpassElement): void {\n\t\tconst zoomDestination = getZoomDestinationForMarker(element);\n\t\tif (zoomDestination)\n\t\t\tflyTo(mapContext.value.components.map, zoomDestination);\n\t}\n\n\tfunction openElement(element: OverpassElement): void {\n\t\topenedElement.value = element;\n\t\tcarousel.setTab(1);\n\t}\n\n\tconst markersWithTags = computed(() => overpassElementsToMarkersWithTags(props.elements));\n\n\tconst zoomDestination = computed(() => combineZoomDestinations(props.elements.map((element) => getZoomDestinationForMarker(element))));\n</script>\n\n<template>\n\t<div class=\"fm-overpass-multiple-info\">\n\t\t<template v-if=\"elements.length == 1\">\n\t\t\t<OverpassInfo :element=\"elements[0]\"></OverpassInfo>\n\t\t</template>\n\t\t<template v-else>\n\t\t\t<div class=\"carousel slide\" ref=\"carouselRef\">\n\t\t\t\t<div class=\"carousel-item\" :class=\"{ active: carousel.tab === 0 }\">\n\t\t\t\t\t<ul class=\"list-group\">\n\t\t\t\t\t\t<li v-for=\"element in elements\" :key=\"element.id\" class=\"list-group-item active\">\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"emit('click-element', element, $event)\">{{formatPOIName(element.tags.name)}}</a>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"zoomToElement(element)\" v-tooltip.left=\"i18n.t('overpass-multiple-info.zoom-to-object')\"><Icon icon=\"zoom-in\" :alt=\"i18n.t('overpass-multiple-info.zoom')\"></Icon></a>\n\t\t\t\t\t\t\t<a href=\"javascript:\" @click=\"openElement(element)\" v-tooltip.right=\"i18n.t('overpass-multiple-info.show-details')\"><Icon icon=\"arrow-right\" :alt=\"i18n.t('overpass-multiple-info.details')\"></Icon></a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\n\t\t\t\t\t<div v-if=\"client.padData && !client.readonly\" class=\"btn-toolbar mt-2\">\n\t\t\t\t\t\t<ZoomToObjectButton\n\t\t\t\t\t\t\tv-if=\"zoomDestination\"\n\t\t\t\t\t\t\t:label=\"i18n.t('overpass-multiple-info.zoom-to-object-label')\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t:destination=\"zoomDestination\"\n\t\t\t\t\t\t></ZoomToObjectButton>\n\n\t\t\t\t\t\t<AddToMapDropdown\n\t\t\t\t\t\t\t:markers=\"markersWithTags\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t></AddToMapDropdown>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"carousel-item\" :class=\"{ active: carousel.tab === 1 }\">\n\t\t\t\t\t<OverpassInfo\n\t\t\t\t\t\tv-if=\"openedElement\"\n\t\t\t\t\t\t:element=\"openedElement\"\n\t\t\t\t\t\tshow-back-button\n\t\t\t\t\t\t@back=\"carousel.setTab(0)\"\n\t\t\t\t\t></OverpassInfo>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</template>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-overpass-multiple-info {\n\t\t.list-group-item {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\n\t\t\t> :first-child {\n\t\t\t\tflex-grow: 1;\n\t\t\t}\n\t\t}\n\t}\n</style>","<script setup lang=\"ts\">\n\timport type { OverpassElement } from \"facilmap-leaflet\";\n\timport OverpassMultipleInfo from \"./overpass-multiple-info.vue\";\n\timport SearchBoxTab from \"../search-box/search-box-tab.vue\";\n\timport { useEventListener } from \"../../utils/utils\";\n\timport { computed } from \"vue\";\n\timport { injectContextRequired, requireMapContext, requireSearchBoxContext } from \"../facil-map-context-provider/facil-map-context-provider.vue\";\n\timport { formatPOIName } from \"facilmap-utils\";\n\timport { useI18n } from \"../../utils/i18n\";\n\n\tconst context = injectContextRequired();\n\tconst mapContext = requireMapContext(context);\n\tconst searchBoxContext = requireSearchBoxContext(context);\n\tconst i18n = useI18n();\n\n\tuseEventListener(mapContext, \"open-selection\", handleOpenSelection);\n\n\tconst elements = computed(() => {\n\t\treturn mapContext.value.selection.flatMap((item) => (item.type == \"overpass\" ? [item.element] : []));\n\t});\n\n\tfunction handleOpenSelection(): void {\n\t\tif (elements.value.length > 0)\n\t\t\tsearchBoxContext.value.activateTab(`fm${context.id}-overpass-info-tab`, { expand: true });\n\t}\n\n\tfunction handleElementClick(element: OverpassElement, event: MouseEvent): void {\n\t\tif (event.ctrlKey)\n\t\t\tmapContext.value.components.selectionHandler.setSelectedItems(mapContext.value.selection.filter((it) => it.type != \"overpass\" || it.element !== element), true);\n\t\telse\n\t\t\tmapContext.value.components.selectionHandler.setSelectedItems(mapContext.value.selection.filter((it) => it.type == \"overpass\" && it.element === element), true);\n\t}\n\n\tfunction close(): void {\n\t\tmapContext.value.components.selectionHandler.setSelectedItems([]);\n\t}\n</script>\n\n<template>\n\t<template v-if=\"elements.length > 0\">\n\t\t<SearchBoxTab\n\t\t\t:id=\"`fm${context.id}-overpass-info-tab`\"\n\t\t\t:title=\"elements.length == 1 ? (formatPOIName(elements[0].tags.name)) : i18n.t('overpass-info-tab.tab-label', { count: elements.length })\"\n\t\t\tisCloseable\n\t\t\t@close=\"close()\"\n\t\t>\n\t\t\t<OverpassMultipleInfo :elements=\"elements\" @click-element=\"handleElementClick\"></OverpassMultipleInfo>\n\t\t</SearchBoxTab>\n\t</template>\n</template>","<script setup lang=\"ts\">\n\timport { computed, ref, toRef, watch } from \"vue\";\n\timport Toolbox from \"./toolbox/toolbox.vue\";\n\timport SearchBox from \"./search-box/search-box.vue\";\n\timport Legend from \"./legend/legend.vue\";\n\timport LeafletMap from \"./leaflet-map/leaflet-map.vue\";\n\timport ImportTab from \"./import-tab.vue\";\n\timport ClickMarkerTab from \"./click-marker-tab.vue\";\n\timport SearchFormTab from \"./search-form/search-form-tab.vue\";\n\timport RouteFormTab from \"./route-form/route-form-tab.vue\";\n\timport OverpassFormTab from \"./overpass-form/overpass-form-tab.vue\";\n\timport MarkerInfoTab from \"./marker-info/marker-info-tab.vue\";\n\timport LineInfoTab from \"./line-info/line-info-tab.vue\";\n\timport MultipleInfoTab from \"./multiple-info/multiple-info-tab.vue\";\n\timport OverpassInfoTab from \"./overpass-info/overpass-info-tab.vue\";\n\timport FacilMapContextProvider from \"./facil-map-context-provider/facil-map-context-provider.vue\";\n\timport type { FacilMapSettings } from \"./facil-map-context-provider/facil-map-context\";\n\timport ClientProvider from \"./client-provider.vue\";\n\timport { preloadExtraSymbols } from \"facilmap-leaflet\";\n\n\tconst props = defineProps<{\n\t\tbaseUrl: string;\n\t\tserverUrl: string;\n\t\tpadId: string | undefined;\n\t\tappName?: string;\n\t\thideCommercialMapLinks?: boolean;\n\t\tsettings?: Partial<FacilMapSettings>;\n\t}>();\n\n\tconst emit = defineEmits<{\n\t\t\"update:padId\": [padId: string | undefined];\n\t\t\"update:padName\": [padName: string | undefined];\n\t}>();\n\n\tconst padId = computed({\n\t\tget: () => props.padId,\n\t\tset: (padId) => {\n\t\t\temit(\"update:padId\", padId);\n\t\t}\n\t});\n\n\tconst contextRef = ref<InstanceType<typeof FacilMapContextProvider>>();\n\tconst context = toRef(() => contextRef.value?.context);\n\tconst client = toRef(() => context.value?.components.client);\n\n\twatch(() => client.value?.padId, () => {\n\t\tif (client.value && client.value.padId !== props.padId) {\n\t\t\temit(\"update:padId\", client.value.padId);\n\t\t}\n\t});\n\n\twatch(() => client.value?.padData?.name, () => {\n\t\tif (client.value) {\n\t\t\temit(\"update:padName\", client.value.padData?.name);\n\t\t}\n\t});\n\n\tdefineExpose({\n\t\tcontext\n\t});\n\n\tpreloadExtraSymbols().catch((err) => {\n\t\tconsole.error(\"Error preloading extra icons\", err);\n\t});\n</script>\n\n<template>\n\t<div class=\"fm-facilmap\">\n\t\t<FacilMapContextProvider\n\t\t\t:baseUrl=\"props.baseUrl\"\n\t\t\t:appName=\"props.appName\"\n\t\t\t:hideCommercialMapLinks=\"props.hideCommercialMapLinks\"\n\t\t\t:settings=\"props.settings\"\n\t\t\tref=\"contextRef\"\n\t\t>\n\t\t\t<ClientProvider v-model:padId=\"padId\" :serverUrl=\"serverUrl\"></ClientProvider>\n\n\t\t\t<LeafletMap v-if=\"context?.components.client\">\n\t\t\t\t<Toolbox v-if=\"context.settings.toolbox\" :interactive=\"context.settings.interactive\"></Toolbox>\n\n\t\t\t\t<template v-if=\"context.components.searchBox\">\n\t\t\t\t\t<SearchFormTab v-if=\"context.settings.search\"></SearchFormTab>\n\t\t\t\t\t<RouteFormTab v-if=\"context.settings.search && context.settings.routing && context.settings.route\"></RouteFormTab>\n\t\t\t\t\t<OverpassFormTab v-if=\"context.settings.search && context.settings.pois\"></OverpassFormTab>\n\t\t\t\t\t<MarkerInfoTab></MarkerInfoTab>\n\t\t\t\t\t<LineInfoTab></LineInfoTab>\n\t\t\t\t\t<MultipleInfoTab></MultipleInfoTab>\n\t\t\t\t\t<OverpassInfoTab></OverpassInfoTab>\n\t\t\t\t\t<ImportTab v-if=\"context.settings.interactive\"></ImportTab>\n\t\t\t\t\t<ClickMarkerTab></ClickMarkerTab>\n\t\t\t\t\t<Legend v-if=\"context.settings.legend\"></Legend>\n\t\t\t\t</template>\n\n\t\t\t\t<template #before>\n\t\t\t\t\t<slot name=\"before\"></slot>\n\t\t\t\t</template>\n\n\t\t\t\t<template #after>\n\t\t\t\t\t<SearchBox></SearchBox>\n\t\t\t\t\t<slot name=\"after\"></slot>\n\t\t\t\t</template>\n\n\t\t\t\t<slot></slot>\n\t\t\t</LeafletMap>\n\t\t</FacilMapContextProvider>\n\t</div>\n</template>\n\n<style lang=\"scss\">\n\t.fm-facilmap {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tflex-grow: 1;\n\t}\n\n\t.td-buttons {\n\t\twhite-space: nowrap;\n\t\twidth: 1px;\n\n\t\t> button {\n\t\t\tmargin-left: 0.25rem;\n\t\t}\n\t}\n\n\t.fm-drag-handle {\n\t\tcursor: grab !important;\n\t}\n\n\t.btn-toolbar {\n\t\t> * + * {\n\t\t\tmargin-left: 0.25rem;\n\t\t}\n\t}\n\n\t.closeable-tab-title {\n\t\tdisplay: inline-flex;\n\t\twidth: 100%;\n\n\t\t> span {\n\t\t\talign-items: center;\n\t\t\tmin-width: 0;\n\t\t\toverflow: hidden;\n\t\t\ttext-overflow: ellipsis;\n\t\t\tflex-grow: 1;\n\t\t}\n\n\t\ta {\n\t\t\tpadding: 0 !important;\n\t\t}\n\n\t\tobject, a, .fm-icon {\n\t\t\tdisplay: inline-flex;\n\t\t\talign-items: center;\n\t\t}\n\t}\n</style>"],"names":["map","ref","idCounter","Toasts","ret","toasts","Map","files","items","e","_a","__default__","className","attributes","show","value","val","slots","app","Alert","validate","ValidatedField","save","type","mapRef","leafletMap","_useSlots","add","hashQuery","route","query","err","zoomDestination","openedObject","objects","presets","_useModel","id","isMarker","context","url","padId","baseLayers","overlays","filter","method","typeId"],"mappings":"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"}