{"version":3,"file":"gui-base-ec6e3cbd.js","sources":["../../../src/gui/base/Dropdown.ts","../../../src/gui/base/SnackBar.ts","../../../src/gui/base/GuiUtils.ts","../../../src/gui/base/WizardDialog.ts","../../../src/gui/base/Table.ts","../../../src/gui/base/ListUtils.ts","../../../src/gui/base/icons/Icons.ts","../../../src/gui/base/icons/BootIcons.ts","../../../src/gui/base/Icon.ts","../../../src/gui/base/Button.ts","../../../src/gui/base/DialogHeaderBar.ts","../../../src/gui/base/TextField.ts","../../../src/gui/base/PureComponent.ts","../../../src/gui/base/IconButton.ts","../../../src/gui/base/DropDownSelector.ts","../../../src/gui/base/DialogInjectionRight.ts","../../../src/gui/base/Dialog.ts","../../../src/gui/base/NotificationOverlay.ts","../../../src/gui/base/ProgressBar.ts","../../../src/gui/base/OfflineIndicatorViewModel.ts","../../../src/gui/base/Checkbox.ts","../../../src/gui/base/Expander.ts","../../../src/gui/base/icons/FontIcons.ts","../../../src/gui/base/DesktopBaseHeader.ts","../../../src/gui/base/ViewColumn.ts","../../../src/gui/base/NavBar.ts","../../../src/gui/base/NavButton.ts","../../../src/gui/base/OfflineIndicator.ts","../../../src/gui/base/buttons/ToggleButton.ts","../../../src/gui/base/SwipeHandler.ts","../../../src/gui/base/ListSwipeHandler.ts","../../../src/gui/base/List.ts","../../../src/gui/base/ColumnEmptyMessageBox.ts","../../../src/gui/base/RichTextToolbar.ts","../../../src/gui/base/TextDisplayArea.ts","../../../src/gui/base/CounterBadge.ts","../../../src/gui/base/buttons/FolderColumnHeaderButton.ts","../../../src/gui/base/BubbleTextField.ts","../../../src/gui/base/MessageBox.ts","../../../src/gui/base/Badge.ts","../../../src/gui/base/InfoBanner.ts","../../../src/gui/base/RecipientButton.ts","../../../src/gui/base/RadioSelector.ts","../../../src/gui/base/StatusField.ts","../../../src/gui/base/ActionBar.ts","../../../src/gui/base/BaseSearchBar.ts","../../../src/gui/base/SegmentControl.ts","../../../src/gui/base/ColorPicker.ts","../../../src/gui/base/NotFoundPage.ts","../../../src/gui/base/PageView.ts","../../../src/gui/base/buttons/BannerButton.ts"],"sourcesContent":["import m, { Children, Component, Vnode } from \"mithril\"\nimport { modal, ModalComponent } from \"./Modal\"\nimport { animations, opacity, transform, TransformEnum } from \"../animation/Animations\"\nimport { ease } from \"../animation/Easing\"\nimport { px, size } from \"../size\"\nimport type { Shortcut } from \"../../misc/KeyManager\"\nimport { focusNext, focusPrevious } from \"../../misc/KeyManager\"\nimport type { ButtonAttrs } from \"./Button.js\"\nimport { lang, TranslationText } from \"../../misc/LanguageViewModel\"\nimport { Keys, TabIndex } from \"../../api/common/TutanotaConstants\"\nimport { getSafeAreaInsetBottom, getSafeAreaInsetTop } from \"../HtmlUtils\"\nimport type { $Promisable, lazy, lazyAsync } from \"@tutao/tutanota-utils\"\nimport { assertNotNull, delay, downcast, filterNull, neverNull, Thunk } from \"@tutao/tutanota-utils\"\nimport { client } from \"../../misc/ClientDetector\"\nimport { pureComponent } from \"./PureComponent\"\nimport type { clickHandler } from \"./GuiUtils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { IconButtonAttrs } from \"./IconButton.js\"\nimport { AllIcons, Icon } from \"./Icon.js\"\nimport { theme } from \"../theme.js\"\n\nassertMainOrNode()\nexport type DropdownInfoAttrs = {\n\tinfo: string\n\tcenter: boolean\n\tbold: boolean\n}\n\n/**\n * Renders small info message inside the dropdown.\n */\nconst DropdownInfo = pureComponent<DropdownInfoAttrs>(({ center, bold, info }) => {\n\treturn m(\".dropdown-info.text-break.selectable\" + (center ? \".center\" : \"\") + (bold ? \".b\" : \"\"), info)\n})\nexport type DropdownChildAttrs = DropdownInfoAttrs | DropdownButtonAttrs\n\nfunction isDropDownInfo(dropdownChild: DropdownChildAttrs): dropdownChild is DropdownInfoAttrs {\n\treturn dropdownChild.hasOwnProperty(\"info\") && dropdownChild.hasOwnProperty(\"center\") && dropdownChild.hasOwnProperty(\"bold\")\n}\n\nexport interface PosRect {\n\treadonly height: number\n\treadonly width: number\n\treadonly top: number\n\treadonly left: number\n\treadonly right: number\n\treadonly bottom: number\n}\n\n// Some Android WebViews still don't support DOMRect so we polyfill that\n// Implemented according to https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly and common sense\nexport class DomRectReadOnlyPolyfilled implements PosRect {\n\tx: number\n\ty: number\n\twidth: number\n\theight: number\n\n\tconstructor(x: number, y: number, width: number, height: number) {\n\t\tthis.x = x\n\t\tthis.y = y\n\t\tthis.width = width\n\t\tthis.height = height\n\t}\n\n\tget top(): number {\n\t\treturn this.height > 0 ? this.y : this.y + this.height\n\t}\n\n\tget bottom(): number {\n\t\treturn this.height > 0 ? this.y + this.height : this.y\n\t}\n\n\tget left(): number {\n\t\treturn this.width > 0 ? this.x : this.x + this.width\n\t}\n\n\tget right(): number {\n\t\treturn this.width > 0 ? this.x + this.width : this.x\n\t}\n}\n\n// TODO: add resize listener like in the old Dropdown\nexport class Dropdown implements ModalComponent {\n\tchildren: ReadonlyArray<DropdownChildAttrs>\n\tprivate _domDropdown: HTMLElement | null = null\n\torigin: PosRect | null = null\n\toninit: ModalComponent[\"oninit\"]\n\tview: ModalComponent[\"view\"]\n\tprivate _width: number\n\tshortcuts: (...args: Array<any>) => any\n\tprivate _filterString: string\n\tprivate _domInput: HTMLInputElement | null = null\n\tprivate _domContents: HTMLElement | null = null\n\tprivate _isFilterable: boolean = false\n\tprivate _maxHeight: number | null = null\n\tprivate closeHandler: Thunk | null = null\n\n\tconstructor(lazyChildren: lazy<ReadonlyArray<DropdownChildAttrs | null>>, width: number) {\n\t\tthis.children = []\n\t\tthis._width = width\n\t\tthis._filterString = \"\"\n\n\t\tthis.oninit = () => {\n\t\t\tthis.children = filterNull(lazyChildren())\n\t\t\tthis._isFilterable = this.children.length > 10\n\t\t\tthis.children.map((child) => {\n\t\t\t\tif (isDropDownInfo(child)) {\n\t\t\t\t\treturn child\n\t\t\t\t}\n\n\t\t\t\tconst buttonChild: DropdownButtonAttrs = child\n\t\t\t\tbuttonChild.click = this.wrapClick(child.click ? child.click : () => null)\n\n\t\t\t\treturn child\n\t\t\t})\n\t\t}\n\n\t\tlet _shortcuts = this._createShortcuts()\n\n\t\tthis.shortcuts = () => {\n\t\t\treturn _shortcuts\n\t\t}\n\n\t\tconst _inputField = () => {\n\t\t\treturn this._isFilterable\n\t\t\t\t? m(\n\t\t\t\t\t\t\"input.dropdown-bar.elevated-bg.doNotClose.pl-l.button-height.abs\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tplaceholder: lang.get(\"typeToFilter_label\"),\n\t\t\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\t\t\tthis._domInput = downcast<HTMLInputElement>(vnode.dom)\n\t\t\t\t\t\t\t\tthis._domInput.value = this._filterString\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toninput: () => {\n\t\t\t\t\t\t\t\tthis._filterString = neverNull(this._domInput).value\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\tpaddingLeft: px(size.hpad_large * 2),\n\t\t\t\t\t\t\t\tpaddingRight: px(size.hpad_small),\n\t\t\t\t\t\t\t\twidth: px(this._width - size.hpad_large),\n\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\theight: px(size.button_height),\n\t\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tthis._filterString,\n\t\t\t\t  )\n\t\t\t\t: null\n\t\t}\n\n\t\tconst _contents = () => {\n\t\t\tconst showingIcons = this.children.some((c) => \"icon\" in c && typeof c.icon !== \"undefined\")\n\t\t\treturn m(\n\t\t\t\t\".dropdown-content.scroll.abs\",\n\t\t\t\t{\n\t\t\t\t\trole: \"menu\",\n\t\t\t\t\ttabindex: TabIndex.Default,\n\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\tthis._domContents = vnode.dom as HTMLElement\n\t\t\t\t\t},\n\t\t\t\t\tonupdate: (vnode) => {\n\t\t\t\t\t\tif (this._maxHeight == null) {\n\t\t\t\t\t\t\tconst children = Array.from(vnode.dom.children) as Array<HTMLElement>\n\t\t\t\t\t\t\tthis._maxHeight = children.reduce((accumulator, children) => accumulator + children.offsetHeight, 0) + size.vpad\n\n\t\t\t\t\t\t\tif (this.origin) {\n\t\t\t\t\t\t\t\t// The dropdown-content element is added to the dom has a hidden element first.\n\t\t\t\t\t\t\t\t// The maxHeight is available after the first onupdate call. Then this promise will resolve and we can safely\n\t\t\t\t\t\t\t\t// show the dropdown.\n\t\t\t\t\t\t\t\t// Modal always schedules redraw in oncreate() of a component so we are guaranteed to have onupdate() call.\n\t\t\t\t\t\t\t\tshowDropdown(this.origin, assertNotNull(this._domDropdown), this._maxHeight, this._width).then(() => {\n\t\t\t\t\t\t\t\t\tif (this._domInput && !client.isMobileDevice()) {\n\t\t\t\t\t\t\t\t\t\tthis._domInput.focus()\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthis._domContents?.focus()\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\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\tonscroll: (ev: EventRedraw<Event>) => {\n\t\t\t\t\t\tconst target = ev.target as HTMLElement\n\t\t\t\t\t\t// needed here to prevent flickering on ios\n\t\t\t\t\t\tev.redraw = this._domContents != null && target.scrollTop < 0 && target.scrollTop + this._domContents.offsetHeight > target.scrollHeight\n\t\t\t\t\t},\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\t// Fixed width for the content of this dropdown is needed to avoid that the elements in the dropdown move during\n\t\t\t\t\t\t// animation.\n\t\t\t\t\t\twidth: px(this._width),\n\t\t\t\t\t\ttop: px(this._getFilterHeight()),\n\t\t\t\t\t\tbottom: 0,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tthis._visibleChildren().map((child) => {\n\t\t\t\t\tif (isDropDownInfo(child)) {\n\t\t\t\t\t\treturn m(DropdownInfo, child)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn m(DropdownButton, { ...child, showingIcons } as InternalDropdownButtonAttrs)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tthis.view = (): Children => {\n\t\t\treturn m(\n\t\t\t\t\".dropdown-panel.elevated-bg.border-radius.dropdown-shadow\",\n\t\t\t\t{\n\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\tthis._domDropdown = vnode.dom as HTMLElement\n\t\t\t\t\t\t// It is important to set initial opacity so that user doesn't see it with full opacity before animating.\n\t\t\t\t\t\tthis._domDropdown.style.opacity = \"0\"\n\t\t\t\t\t},\n\t\t\t\t\tonkeypress: () => {\n\t\t\t\t\t\tif (this._domInput) {\n\t\t\t\t\t\t\tthis._domInput.focus()\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t[_inputField(), _contents()],\n\t\t\t)\n\t\t}\n\t}\n\n\twrapClick(fn: (event: MouseEvent, dom: HTMLElement) => unknown): (event: MouseEvent, dom: HTMLElement) => unknown {\n\t\treturn (e: MouseEvent, dom) => {\n\t\t\tconst r = fn(e, dom)\n\t\t\tthis.close()\n\t\t\treturn r\n\t\t}\n\t}\n\n\tbackgroundClick(e: MouseEvent) {\n\t\tif (\n\t\t\tthis._domDropdown &&\n\t\t\t!(e.target as HTMLElement).classList.contains(\"doNotClose\") &&\n\t\t\t(this._domDropdown.contains(e.target as HTMLElement) || this._domDropdown.parentNode === e.target)\n\t\t) {\n\t\t\tthis.onClose()\n\t\t}\n\t}\n\n\t_createShortcuts(): Array<Shortcut> {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkey: Keys.ESC,\n\t\t\t\texec: () => this.onClose(),\n\t\t\t\thelp: \"close_alt\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: Keys.TAB,\n\t\t\t\tshift: true,\n\t\t\t\texec: () => (this._domDropdown ? focusPrevious(this._domDropdown) : false),\n\t\t\t\thelp: \"selectPrevious_action\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: Keys.TAB,\n\t\t\t\tshift: false,\n\t\t\t\texec: () => (this._domDropdown ? focusNext(this._domDropdown) : false),\n\t\t\t\thelp: \"selectNext_action\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: Keys.UP,\n\t\t\t\texec: () => (this._domDropdown ? focusPrevious(this._domDropdown) : false),\n\t\t\t\thelp: \"selectPrevious_action\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: Keys.DOWN,\n\t\t\t\texec: () => (this._domDropdown ? focusNext(this._domDropdown) : false),\n\t\t\t\thelp: \"selectNext_action\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: Keys.RETURN,\n\t\t\t\texec: () => this.chooseMatch(),\n\t\t\t\thelp: \"ok_action\",\n\t\t\t},\n\t\t]\n\t}\n\n\tsetOrigin(origin: PosRect): this {\n\t\tthis.origin = origin\n\t\treturn this\n\t}\n\n\tclose(): void {\n\t\tmodal.remove(this)\n\t}\n\n\tonClose(): void {\n\t\tif (this.closeHandler) {\n\t\t\tthis.closeHandler()\n\t\t} else {\n\t\t\tthis.close()\n\t\t}\n\t}\n\n\tpopState(e: Event): boolean {\n\t\tthis.onClose()\n\t\treturn false\n\t}\n\n\tchooseMatch: () => boolean = () => {\n\t\tconst filterString = this._filterString.toLowerCase()\n\n\t\tlet visibleElements: Array<ButtonAttrs> = downcast(this._visibleChildren().filter((b) => !isDropDownInfo(b)))\n\t\tlet matchingButton =\n\t\t\tvisibleElements.length === 1 ? visibleElements[0] : visibleElements.find((b) => lang.getMaybeLazy(b.label).toLowerCase() === filterString)\n\n\t\tif (this._domInput && document.activeElement === this._domInput && matchingButton && matchingButton.click) {\n\t\t\tmatchingButton.click(new MouseEvent(\"click\"), this._domInput)\n\t\t\treturn false\n\t\t}\n\n\t\treturn true\n\t}\n\n\t/**\n\t * Is invoked from modal as the two animations (background layer opacity and dropdown) should run in parallel\n\t */\n\thideAnimation(): Promise<void> {\n\t\treturn Promise.resolve()\n\t}\n\n\tsetCloseHandler(handler: Thunk): this {\n\t\tthis.closeHandler = handler\n\t\treturn this\n\t}\n\n\t_visibleChildren(): Array<DropdownChildAttrs> {\n\t\treturn this.children.filter((b) => {\n\t\t\tif (isDropDownInfo(b)) {\n\t\t\t\treturn b.info.includes(this._filterString.toLowerCase())\n\t\t\t} else if (this._isFilterable) {\n\t\t\t\treturn lang.getMaybeLazy(b.label).toLowerCase().includes(this._filterString.toLowerCase())\n\t\t\t} else {\n\t\t\t\treturn true\n\t\t\t}\n\t\t})\n\t}\n\n\t_getFilterHeight(): number {\n\t\treturn this._isFilterable ? size.button_height + size.vpad_xs : 0\n\t}\n}\n\nexport function createDropdown({\n\tlazyButtons,\n\toverrideOrigin,\n\twidth,\n\twithBackground,\n}: {\n\tlazyButtons: lazy<ReadonlyArray<DropdownChildAttrs | null>>\n\toverrideOrigin?: (original: PosRect) => PosRect\n\twidth?: number\n\twithBackground?: boolean\n}): clickHandler {\n\treturn createAsyncDropdown({ lazyButtons: async () => lazyButtons(), overrideOrigin, width, withBackground })\n}\n\nexport function createAsyncDropdown({\n\tlazyButtons,\n\toverrideOrigin,\n\twidth = 200,\n\twithBackground = false,\n}: {\n\tlazyButtons: lazyAsync<ReadonlyArray<DropdownChildAttrs | null>>\n\toverrideOrigin?: (original: PosRect) => PosRect\n\twidth?: number\n\twithBackground?: boolean\n}): clickHandler {\n\t// not all browsers have the actual button as e.currentTarget, but all of them send it as a second argument (see https://github.com/tutao/tutanota/issues/1110)\n\treturn (_, dom) => {\n\t\tconst originalButtons = lazyButtons()\n\t\tlet buttonsResolved = false\n\t\toriginalButtons.then(() => {\n\t\t\tbuttonsResolved = true\n\t\t})\n\t\tlet buttons = originalButtons\n\t\t// If the promise is pending and does not resolve in 100ms, show progress dialog\n\t\tbuttons = Promise.race([\n\t\t\toriginalButtons,\n\t\t\tPromise.all([delay(100), import(\"../dialogs/ProgressDialog.js\")]).then(([_, module]) => {\n\t\t\t\tif (!buttonsResolved) {\n\t\t\t\t\treturn module.showProgressDialog(\"loading_msg\", originalButtons)\n\t\t\t\t} else {\n\t\t\t\t\treturn originalButtons\n\t\t\t\t}\n\t\t\t}),\n\t\t])\n\t\tbuttons.then((buttons) => {\n\t\t\tlet dropdown = new Dropdown(() => buttons, width)\n\n\t\t\tlet buttonRect\n\t\t\tif (overrideOrigin) {\n\t\t\t\tbuttonRect = overrideOrigin(dom.getBoundingClientRect())\n\t\t\t} else {\n\t\t\t\t// When new instance is created and the old DOM is detached we may have incorrect positioning\n\t\t\t\tbuttonRect = dom.getBoundingClientRect()\n\t\t\t}\n\n\t\t\tdropdown.setOrigin(buttonRect)\n\t\t\tmodal.displayUnique(dropdown, withBackground)\n\t\t})\n\t}\n}\n\nexport function showDropdownAtPosition(buttons: ReadonlyArray<DropdownChildAttrs>, xPos: number, yPos: number, width: number = 200) {\n\tconst dropdown = new Dropdown(() => buttons, width)\n\tdropdown.setOrigin(new DomRectReadOnlyPolyfilled(xPos, yPos, 0, 0))\n\tmodal.displayUnique(dropdown, false)\n}\n\ntype AttachDropdownParams = {\n\tmainButtonAttrs: Omit<IconButtonAttrs, \"click\">\n\tchildAttrs: lazy<$Promisable<ReadonlyArray<DropdownChildAttrs | null>>>\n\t/** called to determine if the dropdown actually needs to be shown */\n\tshowDropdown?: lazy<boolean>\n\twidth?: number\n\toverrideOrigin?: (original: PosRect) => PosRect\n}\n\n/**\n *\n * @param mainButtonAttrs the attributes of the main button. if showDropdown returns false, nothing will happen.\n * @param childAttrs the attributes of the children shown in the dropdown\n * @param showDropdown this will be checked before showing the dropdown\n * @param width width of the dropdown\n * @returns {ButtonAttrs} modified mainButtonAttrs that shows a dropdown on click or\n * button doesn't do anything if showDropdown returns false\n */\nexport function attachDropdown({ mainButtonAttrs, childAttrs, showDropdown = () => true, width, overrideOrigin }: AttachDropdownParams): IconButtonAttrs {\n\treturn Object.assign({}, mainButtonAttrs, {\n\t\tclick: (e: MouseEvent, dom: HTMLElement) => {\n\t\t\tif (showDropdown()) {\n\t\t\t\tconst dropDownFn = createAsyncDropdown({ lazyButtons: () => Promise.resolve(childAttrs()), overrideOrigin, width })\n\t\t\t\tdropDownFn(e, dom)\n\t\t\t\te.stopPropagation()\n\t\t\t}\n\t\t},\n\t})\n}\n\nexport const DROPDOWN_MARGIN = 4\n\nexport function showDropdown(origin: PosRect, domDropdown: HTMLElement, contentHeight: number, contentWidth: number): Promise<unknown> {\n\t// |------------------|    |------------------|    |------------------|    |------------------|\n\t// |                  |    |                  |    |                  |    |                  |\n\t// |      |-------|   |    |  |-------|       |    |  |-----------^   |    |  ^-----------|   |\n\t// |      | elem  |   |    |  | elem  |       |    |  | dropdown  |   |    |  | dropdown  |   |\n\t// |      |-------|   |    |  |-------|       |    |  |<----------|   |    |  |---------->|   |\n\t// |  |<----------|   |    |  |---------->|   |    |      |-------|   |    |  |-------|       |\n\t// |  | dropdown  |   |    |  | dropdown  |   |    |      | elem  |   |    |  | elem  |       |\n\t// /  |-----------V   |    |  V-----------|   |    |      |-------|   |    |  |-------|       |\n\t//\n\t// Decide were to open dropdown. We open the dropdown depending on the position of the touched element.\n\t// For that we devide the screen into four parts which are upper/lower and right/left part of the screen.\n\t// If the element is in the upper right part for example we try to open the dropdown below the touched element\n\t// starting from the right edge of the touched element.\n\t// If the element is in the lower left part of the screen we open the dropdown above the element\n\t// starting from the left edge of the touched element.\n\t// If the dropdown width does not fit from its calculated starting position we open it from the edge of the screen.\n\tconst leftEdgeOfElement = origin.left\n\tconst rightEdgeOfElement = origin.right\n\tconst bottomEdgeOfElement = origin.bottom\n\tconst topEdgeOfElement = origin.top\n\tconst upperSpace = origin.top - getSafeAreaInsetTop()\n\tconst lowerSpace = window.innerHeight - origin.bottom - getSafeAreaInsetBottom()\n\tconst leftSpace = origin.left\n\tconst rightSpace = window.innerWidth - origin.right\n\tlet transformOrigin = \"\"\n\tlet maxHeight\n\n\tif (lowerSpace > upperSpace) {\n\t\t// element is in the upper part of the screen, dropdown should be below the element\n\t\ttransformOrigin += \"top\"\n\t\tdomDropdown.style.top = bottomEdgeOfElement + \"px\"\n\t\tdomDropdown.style.bottom = \"\"\n\t\tmaxHeight = Math.min(contentHeight, lowerSpace)\n\t} else {\n\t\t// element is in the lower part of the screen, dropdown should be above the element\n\t\ttransformOrigin += \"bottom\"\n\t\tdomDropdown.style.top = \"\"\n\t\t// position bottom is defined from the bottom edge of the screen\n\t\t// and not like the viewport origin which starts at top/left\n\t\tdomDropdown.style.bottom = px(window.innerHeight - topEdgeOfElement)\n\t\tmaxHeight = Math.min(contentHeight, upperSpace)\n\t}\n\n\tlet width = contentWidth\n\n\tif (leftSpace < rightSpace) {\n\t\t// element is in the left part of the screen, dropdown should extend to the right from the element\n\t\ttransformOrigin += \" left\"\n\t\tconst availableSpaceForDropdown = window.innerWidth - leftEdgeOfElement\n\t\tlet leftEdgeOfDropdown = leftEdgeOfElement\n\n\t\tif (availableSpaceForDropdown < contentWidth) {\n\t\t\t// If the dropdown does not fit, we shift it by the required amount. If it still does not fit, we reduce the width.\n\t\t\tconst shiftForDropdown = contentWidth - availableSpaceForDropdown + DROPDOWN_MARGIN\n\t\t\tleftEdgeOfDropdown = leftEdgeOfElement - shiftForDropdown\n\t\t\twidth = Math.min(width, window.innerWidth - DROPDOWN_MARGIN * 2)\n\t\t}\n\n\t\tdomDropdown.style.left = px(Math.max(DROPDOWN_MARGIN, leftEdgeOfDropdown))\n\t\tdomDropdown.style.right = \"\"\n\t} else {\n\t\t// element is in the right part of the screen, dropdown should extend to the left from the element\n\t\ttransformOrigin += \" right\"\n\t\tconst availableSpaceForDropdown = origin.right\n\t\tlet rightEdgeOfDropdown = rightEdgeOfElement\n\n\t\tif (availableSpaceForDropdown < contentWidth) {\n\t\t\t// If the dropdown does not fit, we shift it by the required amount. If it still does not fit, we reduce the width.\n\t\t\tconst shiftForDropdown = contentWidth - availableSpaceForDropdown + DROPDOWN_MARGIN\n\t\t\trightEdgeOfDropdown = rightEdgeOfElement + shiftForDropdown\n\t\t\twidth = Math.min(width, window.innerWidth - DROPDOWN_MARGIN * 2)\n\t\t}\n\n\t\tdomDropdown.style.left = \"\"\n\t\t// position right is defined from the right edge of the screen\n\t\t// and not like the viewport origin which starts at top/left\n\t\tdomDropdown.style.right = px(Math.max(DROPDOWN_MARGIN, window.innerWidth - rightEdgeOfDropdown))\n\t}\n\n\tdomDropdown.style.width = px(width)\n\tdomDropdown.style.height = px(maxHeight)\n\tdomDropdown.style.transformOrigin = transformOrigin\n\treturn animations.add(domDropdown, [opacity(0, 1, true), transform(TransformEnum.Scale, 0.5, 1)], {\n\t\teasing: ease.out,\n\t})\n}\n\nexport interface DropdownButtonAttrs {\n\tlabel: TranslationText\n\ticon?: AllIcons\n\tclick?: clickHandler\n\tselected?: boolean\n}\n\ninterface InternalDropdownButtonAttrs extends DropdownButtonAttrs {\n\tshowingIcons: boolean\n}\n\nclass DropdownButton implements Component<InternalDropdownButtonAttrs> {\n\tprivate dom: HTMLElement | null = null\n\n\tview({ attrs }: Vnode<InternalDropdownButtonAttrs>): Children {\n\t\tconst color = attrs.selected ? theme.content_button_selected : theme.content_button\n\t\treturn m(\n\t\t\t\"button.flex.dropdown-button.items-center.state-bg\",\n\t\t\t{\n\t\t\t\trole: \"menuitem\",\n\t\t\t\toncreate: (vnode) => (this.dom = vnode.dom as HTMLElement),\n\t\t\t\tonclick: (e: MouseEvent) => attrs.click?.(e, neverNull(this.dom)),\n\t\t\t},\n\t\t\t[\n\t\t\t\tattrs.icon && attrs.showingIcons\n\t\t\t\t\t? m(Icon, {\n\t\t\t\t\t\t\ticon: attrs.icon,\n\t\t\t\t\t\t\tlarge: true,\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\tfill: color,\n\t\t\t\t\t\t\t\t// margin on the sides of the button is 16px, but it actually looks more coherent to have the smaller spacing between the icon and text\n\t\t\t\t\t\t\t\tmarginRight: px(12),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t  })\n\t\t\t\t\t: attrs.showingIcons\n\t\t\t\t\t? m(\".icon-large\", {\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\tmarginRight: px(12),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t  })\n\t\t\t\t\t: null,\n\t\t\t\tm(\n\t\t\t\t\t\".text-ellipsis\",\n\t\t\t\t\t{\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tcolor,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tlang.getMaybeLazy(attrs.label),\n\t\t\t\t),\n\t\t\t],\n\t\t)\n\t}\n}\n","import m, { Component, Vnode } from \"mithril\"\nimport { px, size } from \"../size\"\nimport { DefaultAnimationTime, transform, TransformEnum } from \"../animation/Animations\"\nimport { displayOverlay } from \"./Overlay\"\nimport type { ButtonAttrs } from \"./Button.js\"\nimport { Button, ButtonType } from \"./Button.js\"\nimport { lang, TranslationText } from \"../../misc/LanguageViewModel\"\nimport { styles } from \"../styles\"\nimport { LayerType } from \"../../RootView\"\nimport type { clickHandler } from \"./GuiUtils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { getSafeAreaInsetBottom } from \"../HtmlUtils\"\n\nassertMainOrNode()\nexport const SNACKBAR_SHOW_TIME = 6000\nconst MAX_SNACKBAR_WIDTH = 400\nexport type SnackBarButtonAttrs = {\n\tlabel: TranslationText\n\tclick: clickHandler\n}\ntype SnackBarAttrs = {\n\tmessage: TranslationText\n\tbutton: ButtonAttrs | null\n}\ntype QueueItem = SnackBarAttrs & { onClose: (() => void) | null }\nconst notificationQueue: QueueItem[] = []\nlet currentAnimationTimeout: TimeoutID | null = null\n\nclass SnackBar implements Component<SnackBarAttrs> {\n\tview(vnode: Vnode<SnackBarAttrs>) {\n\t\t// use same padding as MinimizedEditor\n\t\treturn m(\".snackbar-content.flex.flex-space-between.border-radius.plr.pb-xs.pt-xs\", [\n\t\t\tm(\".flex.center-vertically.smaller\", lang.getMaybeLazy(vnode.attrs.message)),\n\t\t\tvnode.attrs.button ? m(\".flex-end.center-vertically.pl\", m(Button, vnode.attrs.button)) : null,\n\t\t])\n\t}\n}\n\nfunction makeButtonAttrsForSnackBar(button: SnackBarButtonAttrs): ButtonAttrs {\n\treturn {\n\t\tlabel: button.label,\n\t\tclick: button.click,\n\t\ttype: ButtonType.Secondary,\n\t}\n}\n\n/**\n * Shows a SnackBar overlay at the bottom for low priority notifications that do not require (but might allow) user interaction and disappear after 6 seconds.\n * @param message The message to be shown. It must be short enough to ensure it is always shown in 2 lines of text at max in any language.\n * @param snackBarButton will close the snackbar if it is clicked (onClose() will be called)\n * @param onClose called when the snackbar is closed (either by timeout or button click)\n */\nexport function showSnackBar(args: { message: TranslationText; button: SnackBarButtonAttrs; onClose?: () => void }) {\n\tconst button = makeButtonAttrsForSnackBar(args.button)\n\tnotificationQueue.push({\n\t\tmessage: args.message,\n\t\tbutton: button,\n\t\tonClose: args.onClose ?? null,\n\t})\n\n\tif (notificationQueue.length > 1) {\n\t\t//Next notification will be shown when closing current notification\n\t\treturn\n\t}\n\n\tshowNextNotification()\n}\n\nfunction getSnackBarPosition() {\n\t// The snackbar will be moved up from off the bottom of the viewport by the transformation animation.\n\tconst snackBarMarginLR = styles.isUsingBottomNavigation() ? size.hpad : size.hpad_medium\n\tconst leftOffset = styles.isDesktopLayout() ? size.drawer_menu_width : 0\n\tconst snackBarWidth = Math.min(window.innerWidth - leftOffset - 2 * snackBarMarginLR, MAX_SNACKBAR_WIDTH)\n\treturn {\n\t\ttop: \"100%\",\n\t\t// The SnackBar is only shown at the right in single column layout\n\t\tleft: styles.isSingleColumnLayout() ? px(window.innerWidth - snackBarMarginLR - snackBarWidth) : px(leftOffset + snackBarMarginLR),\n\t\twidth: px(snackBarWidth),\n\t\tzIndex: LayerType.Overlay,\n\t}\n}\n\nfunction showNextNotification() {\n\tconst { message, button, onClose } = notificationQueue[0] //we shift later because it is still shown\n\n\tcurrentAnimationTimeout = null\n\tconst bottomInset = getSafeAreaInsetBottom()\n\tconst bottomOffset = styles.isUsingBottomNavigation() ? size.bottom_nav_bar + size.hpad + bottomInset : size.hpad_medium\n\tconst closeFunction = displayOverlay(\n\t\t() => getSnackBarPosition(),\n\t\t{\n\t\t\tview: () =>\n\t\t\t\tm(SnackBar, {\n\t\t\t\t\tmessage,\n\t\t\t\t\tbutton,\n\t\t\t\t}),\n\t\t},\n\t\t// it is initially below the container and we move it into it with transform\n\t\t(dom) => transform(TransformEnum.TranslateY, 0, -(bottomOffset + dom.offsetHeight)),\n\t\t// it is initially inside the container, we transform it out of it\n\t\t(dom) => transform(TransformEnum.TranslateY, -(bottomOffset + dom.offsetHeight), 0),\n\t\t\"minimized-shadow\",\n\t)\n\n\tconst closeAndOpenNext = () => {\n\t\tif (currentAnimationTimeout !== null) {\n\t\t\treturn\n\t\t}\n\n\t\tcloseFunction()\n\n\t\tif (onClose) {\n\t\t\tonClose()\n\t\t}\n\n\t\tnotificationQueue.shift()\n\n\t\tif (notificationQueue.length > 0) {\n\t\t\tcurrentAnimationTimeout = setTimeout(showNextNotification, 2 * DefaultAnimationTime)\n\t\t}\n\t}\n\n\t// close the notification by default when pressing the button\n\tif (button) {\n\t\tconst originClickHandler: clickHandler | undefined = button.click\n\n\t\tbutton.click = (e, dom) => {\n\t\t\tclearTimeout(autoRemoveTimer)\n\t\t\toriginClickHandler?.(e, dom)\n\t\t\tcloseAndOpenNext()\n\t\t}\n\t}\n\n\tconst autoRemoveTimer = setTimeout(closeAndOpenNext, SNACKBAR_SHOW_TIME)\n\tm.redraw()\n}\n","import type { Country } from \"../../api/common/CountryList\"\nimport { Countries } from \"../../api/common/CountryList\"\nimport type { InfoLink, TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport type { ButtonAttrs } from \"./Button.js\"\nimport { ButtonColor, ButtonType } from \"./Button.js\"\nimport { Icons } from \"./icons/Icons\"\nimport type { DropdownChildAttrs } from \"./Dropdown.js\"\nimport { createAsyncDropdown } from \"./Dropdown.js\"\nimport type { $Promisable, lazy, MaybeLazy } from \"@tutao/tutanota-utils\"\nimport { assertNotNull, lazyMemoized, resolveMaybeLazy } from \"@tutao/tutanota-utils\"\nimport { Dialog } from \"./Dialog\"\nimport type { AllIcons } from \"./Icon\"\nimport { ProgrammingError } from \"../../api/common/error/ProgrammingError\"\nimport m, { Children } from \"mithril\"\nimport { DropDownSelector } from \"./DropDownSelector.js\"\nimport { IconButtonAttrs } from \"./IconButton.js\"\nimport { LoginController } from \"../../api/main/LoginController.js\"\nimport { client } from \"../../misc/ClientDetector.js\"\n\nexport type dropHandler = (dragData: string) => void\n// not all browsers have the actual button as e.currentTarget, but all of them send it as a second argument (see https://github.com/tutao/tutanota/issues/1110)\nexport type clickHandler = (event: MouseEvent, dom: HTMLElement) => void\n\n// lazy because of global dependencies\nconst dropdownCountries = lazyMemoized(() => Countries.map((c) => ({ value: c, name: c.n })))\n\nexport function renderCountryDropdown(params: {\n\tselectedCountry: Country | null\n\tonSelectionChanged: (country: Country) => void\n\thelpLabel?: lazy<string>\n\tlabel?: TranslationKey | lazy<string>\n}): Children {\n\treturn m(DropDownSelector, {\n\t\tlabel: params.label ?? \"invoiceCountry_label\",\n\t\thelpLabel: params.helpLabel,\n\t\titems: [\n\t\t\t...dropdownCountries(),\n\t\t\t{\n\t\t\t\tvalue: null,\n\t\t\t\tname: lang.get(\"choose_label\"),\n\t\t\t},\n\t\t],\n\t\tselectedValue: params.selectedCountry,\n\t\tselectionChangedHandler: params.onSelectionChanged,\n\t})\n}\n\nexport function createMoreSecondaryButtonAttrs(\n\tlazyChildren: MaybeLazy<$Promisable<ReadonlyArray<DropdownChildAttrs | null>>>,\n\tdropdownWidth?: number,\n): ButtonAttrs {\n\treturn moreButtonAttrsImpl(null, ButtonType.Secondary, lazyChildren, dropdownWidth)\n}\n\nexport function createMoreActionButtonAttrs(\n\tlazyChildren: MaybeLazy<$Promisable<ReadonlyArray<DropdownChildAttrs | null>>>,\n\tdropdownWidth?: number,\n): IconButtonAttrs {\n\treturn {\n\t\ttitle: \"more_label\",\n\t\tcolors: ButtonColor.Nav,\n\t\ticon: Icons.More,\n\t\tclick: createAsyncDropdown({\n\t\t\twidth: dropdownWidth,\n\t\t\tlazyButtons: async () => resolveMaybeLazy(lazyChildren),\n\t\t}),\n\t}\n}\n\nfunction moreButtonAttrsImpl(\n\ticon: lazy<AllIcons> | null,\n\ttype: ButtonType,\n\tlazyChildren: MaybeLazy<$Promisable<ReadonlyArray<DropdownChildAttrs | null>>>,\n\tdropdownWidth?: number,\n): ButtonAttrs {\n\treturn {\n\t\tlabel: \"more_label\",\n\t\tcolors: ButtonColor.Nav,\n\t\ticon,\n\t\ttype,\n\t\tclick: createAsyncDropdown({\n\t\t\twidth: dropdownWidth,\n\t\t\tlazyButtons: async () => resolveMaybeLazy(lazyChildren),\n\t\t}),\n\t}\n}\n\ntype Confirmation = {\n\tconfirmed: (_: () => unknown) => Confirmation\n\tcancelled: (_: () => unknown) => Confirmation\n\tresult: Promise<boolean>\n}\n\n/**\n * Wrapper around Dialog.confirm\n *\n * call getConfirmation(...).confirmed(() => doStuff()) or getConfirmation(...).cancelled(() => doStuff())\n * to handle confirmation or termination\n * @param message\n * @param confirmMessage\n * @returns {Confirmation}\n */\nexport function getConfirmation(message: TranslationKey | lazy<string>, confirmMessage: TranslationKey = \"ok_action\"): Confirmation {\n\tconst confirmationPromise = Dialog.confirm(message, confirmMessage)\n\tconst confirmation: Confirmation = {\n\t\tconfirmed(action) {\n\t\t\tconfirmationPromise.then((ok) => {\n\t\t\t\tif (ok) {\n\t\t\t\t\taction()\n\t\t\t\t}\n\t\t\t})\n\t\t\treturn confirmation\n\t\t},\n\n\t\tcancelled(action) {\n\t\t\tconfirmationPromise.then((ok) => {\n\t\t\t\tif (!ok) {\n\t\t\t\t\taction()\n\t\t\t\t}\n\t\t\t})\n\t\t\treturn confirmation\n\t\t},\n\n\t\tresult: confirmationPromise,\n\t}\n\treturn confirmation\n}\n\n/**\n * Get either the coord of a mouseevent or the coord of the first touch of a touch event\n * @param event\n * @returns {{x: number, y: number}}\n */\nexport function getCoordsOfMouseOrTouchEvent(event: MouseEvent | TouchEvent): {\n\tx: number\n\ty: number\n} {\n\treturn event instanceof MouseEvent\n\t\t? {\n\t\t\t\tx: event.clientX,\n\t\t\t\ty: event.clientY,\n\t\t  }\n\t\t: {\n\t\t\t\t// Why would touches be empty?\n\t\t\t\tx: assertNotNull(event.touches.item(0)).clientX,\n\t\t\t\ty: assertNotNull(event.touches.item(0)).clientY,\n\t\t  }\n}\n\nexport function makeListSelectionChangedScrollHandler(scrollDom: HTMLElement, entryHeight: number, getSelectedEntryIndex: lazy<number>): () => void {\n\treturn function () {\n\t\tscrollListDom(scrollDom, entryHeight, getSelectedEntryIndex())\n\t}\n}\n\nexport function scrollListDom(scrollDom: HTMLElement, entryHeight: number, selectedIndex: number) {\n\tconst scrollWindowHeight = scrollDom.getBoundingClientRect().height\n\tconst scrollOffset = scrollDom.scrollTop\n\t// Actual position in the list\n\tconst selectedTop = entryHeight * selectedIndex\n\tconst selectedBottom = selectedTop + entryHeight\n\t// Relative to the top of the scroll window\n\tconst selectedRelativeTop = selectedTop - scrollOffset\n\tconst selectedRelativeBottom = selectedBottom - scrollOffset\n\n\t// clamp the selected item to stay between the top and bottom of the scroll window\n\tif (selectedRelativeTop < 0) {\n\t\tscrollDom.scrollTop = selectedTop\n\t} else if (selectedRelativeBottom > scrollWindowHeight) {\n\t\tscrollDom.scrollTop = selectedBottom - scrollWindowHeight\n\t}\n}\n\n/**\n * Executes the passed function if the user is allowed to see `tutanota.com` links.\n * @param logins LoginController to ask about login information\n * @param linkId\n * @param render receives the resolved link\n * @returns {Children|null}\n */\nexport function ifAllowedTutanotaLinks(logins: LoginController, linkId: InfoLink, render: (arg0: string) => Children): Children | null {\n\t// this is currently in gui-base, preventing us from accessing logins ourselves.\n\t// may be subject to change\n\tif (canSeeTutanotaLinks(logins)) {\n\t\treturn render(linkId)\n\t}\n\treturn null\n}\n\n/**\n * Check if the user is allowed to see `tutanota.com` links or other major references to Tutanota.\n *\n * If the user is on whitelabel and they are not global admin, information like this should not be shown.\n * @param logins LoginController to ask about login information\n * @returns true if the user should see tutanota links or false if they should not\n */\nexport function canSeeTutanotaLinks(logins: LoginController): boolean {\n\treturn !logins.isWhitelabel() || logins.getUserController().isGlobalAdmin()\n}\n\nexport type MousePosAndBounds = {\n\tx: number\n\ty: number\n\ttargetWidth: number\n\ttargetHeight: number\n}\n\n/**\n * Get the mouse's x and y coordinates relative to the target, and the width and height of the target.\n * The currentTarget must be a HTMLElement or this throws an error\n * @param mouseEvent\n */\nexport function getPosAndBoundsFromMouseEvent({ currentTarget, x, y }: MouseEvent): MousePosAndBounds {\n\tif (currentTarget instanceof HTMLElement) {\n\t\tconst { height, width, left, top } = currentTarget.getBoundingClientRect()\n\t\treturn {\n\t\t\ttargetHeight: height,\n\t\t\ttargetWidth: width,\n\t\t\tx: x - left,\n\t\t\ty: y - top,\n\t\t}\n\t} else {\n\t\tthrow new ProgrammingError(\"Target is not a HTMLElement\")\n\t}\n}\n\n/** render two children either next to each other (on desktop devices) or above each other (mobile) */\nexport function renderTwoColumnsIfFits(left: Children, right: Children): Children {\n\tif (client.isMobileDevice()) {\n\t\treturn m(\".flex.col\", [m(\".flex\", left), m(\".flex\", right)])\n\t} else {\n\t\treturn m(\".flex\", [m(\".flex.flex-half.pr-s\", left), m(\".flex.flex-half.pl-s\", right)])\n\t}\n}\n","import m, { Children, Component, Vnode, VnodeDOM } from \"mithril\"\nimport { Dialog } from \"./Dialog\"\nimport type { ButtonAttrs } from \"./Button.js\"\nimport { ButtonType } from \"./Button.js\"\nimport { Icons } from \"./icons/Icons\"\nimport { Icon } from \"./Icon\"\nimport { getContentButtonIconBackground, theme } from \"../theme\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport type { DialogHeaderBarAttrs } from \"./DialogHeaderBar\"\nimport { Keys, TabIndex } from \"../../api/common/TutanotaConstants\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { $Promisable } from \"@tutao/tutanota-utils\"\nimport { windowFacade } from \"../../misc/WindowFacade.js\"\n\nassertMainOrNode()\n\nexport interface WizardPageAttrs<T> {\n\t/** Title of the page that is shown in the header bar of the WizardDialog*/\n\theaderTitle(): string\n\n\t/** Action that needs to be executed before switching to the next page.\n\t * @return true if the action was successful and the next page can be shown, false otherwise.\n\t **/\n\tnextAction(showErrorDialog: boolean): Promise<boolean>\n\n\t/**\n\t * Checks if the page can be skipped.\n\t */\n\tisSkipAvailable(): boolean\n\n\t/**\n\t * Checks if the page is enabled and can be displayed.\n\t */\n\tisEnabled(): boolean\n\n\t/**\n\t * The actual data, which is the same for the entire wizard needs to be also accessible to each page\n\t */\n\treadonly data: T\n\n\t/**\n\t * Indicates that it should not be possible to select any earlier stage than this one, once reached. If not set or false, it is possible to go back\n\t */\n\treadonly preventGoBack?: boolean\n\n\t/**\n\t * if set to true, all paging buttons will be hidden for this page\n\t */\n\treadonly hideAllPagingButtons?: boolean\n\n\t/**\n\t * if this is true the paging button (button with the number) is hidden for this specific wizard page\n\t */\n\treadonly hidePagingButtonForPage?: boolean\n}\n\nexport type WizardPageN<T> = Component<WizardPageAttrs<T>>\n\nexport const enum WizardEventType {\n\tSHOWNEXTPAGE = \"showNextWizardDialogPage\",\n\tCLOSEDIALOG = \"closeWizardDialog\",\n}\n\n// A WizardPage dispatches this event to inform the parent WizardDialogN to close the dialog\nexport function emitWizardEvent(dom: HTMLElement | null, eventType: WizardEventType) {\n\tif (dom) {\n\t\tconst event = new Event(eventType, {\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t})\n\t\tdom.dispatchEvent(event)\n\t}\n}\n\nclass WizardDialog<T> implements Component<WizardDialogAttrs<T>> {\n\tprivate _closeWizardDialogListener!: EventListener\n\tprivate _showNextWizardDialogPageListener!: EventListener\n\n\toncreate(vnode: VnodeDOM<WizardDialogAttrs<T>>) {\n\t\t// We listen for events triggered by the child WizardPages to close the dialog or show the next page\n\t\tconst dom: HTMLElement = vnode.dom as HTMLElement\n\n\t\tthis._closeWizardDialogListener = (e: Event) => {\n\t\t\te.stopPropagation()\n\t\t\tvnode.attrs.closeAction()\n\t\t}\n\n\t\tthis._showNextWizardDialogPageListener = (e: Event) => {\n\t\t\te.stopPropagation()\n\n\t\t\tif (vnode.attrs.currentPage) {\n\t\t\t\tvnode.attrs.currentPage.attrs.nextAction(true).then((ready) => {\n\t\t\t\t\tif (ready) vnode.attrs.goToNextPageOrCloseWizard()\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tdom.addEventListener(WizardEventType.CLOSEDIALOG, this._closeWizardDialogListener)\n\t\tdom.addEventListener(WizardEventType.SHOWNEXTPAGE, this._showNextWizardDialogPageListener)\n\t}\n\n\tonremove(vnode: VnodeDOM<WizardDialogAttrs<T>>) {\n\t\tconst dom: HTMLElement = vnode.dom as HTMLElement\n\t\tif (this._closeWizardDialogListener) dom.removeEventListener(WizardEventType.CLOSEDIALOG, this._closeWizardDialogListener)\n\t\tif (this._showNextWizardDialogPageListener) dom.removeEventListener(WizardEventType.SHOWNEXTPAGE, this._showNextWizardDialogPageListener)\n\t}\n\n\tview(vnode: Vnode<WizardDialogAttrs<T>>) {\n\t\tconst a = vnode.attrs\n\t\tconst selectedIndex = a.currentPage ? a._getEnabledPages().indexOf(a.currentPage) : -1\n\t\treturn m(\"#wizardDialogContent.pt\", [\n\t\t\ta.currentPage && a.currentPage.attrs.hideAllPagingButtons\n\t\t\t\t? null\n\t\t\t\t: m(\n\t\t\t\t\t\t\"#wizard-paging.flex-space-around.border-top\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\theight: \"22px\",\n\t\t\t\t\t\t\t\tmarginTop: \"22px\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\ta\n\t\t\t\t\t\t\t._getEnabledPages()\n\t\t\t\t\t\t\t.filter((page) => !page.attrs.hidePagingButtonForPage)\n\t\t\t\t\t\t\t.map((p, index) =>\n\t\t\t\t\t\t\t\tm(WizardPagingButton, {\n\t\t\t\t\t\t\t\t\tpageIndex: index,\n\t\t\t\t\t\t\t\t\tgetSelectedPageIndex: () => selectedIndex,\n\t\t\t\t\t\t\t\t\tisClickable: () => a.allowedToVisitPage(index, selectedIndex),\n\t\t\t\t\t\t\t\t\tnavigateBackHandler: (index) => a._goToPageAction(index),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t  ),\n\t\t\ta.currentPage ? a.currentPage.view() : null,\n\t\t])\n\t}\n}\n\n/**\n * Pair of attrs and component for those attrs\n * We care about these properties:\n * It has WizardPageAttrs for T\n * A is consistent with the component\n *\n * When we use the wrapper we don't care about specific type of attrs or component.\n */\n\nexport interface WizardPageWrapper<T> {\n\treadonly attrs: WizardPageAttrs<T>\n\treadonly view: () => Children\n}\n\nexport function wizardPageWrapper<T, A extends WizardPageAttrs<T>>(component: Class<Component<A>>, attributes: A): WizardPageWrapper<T> {\n\treturn {\n\t\tattrs: attributes,\n\t\tview: () => m(component, attributes),\n\t}\n}\n\nclass WizardDialogAttrs<T> {\n\treadonly data: T\n\tpages: ReadonlyArray<WizardPageWrapper<T>>\n\tcurrentPage: WizardPageWrapper<T> | null\n\tcloseAction: () => Promise<void>\n\tprivate _headerBarAttrs: DialogHeaderBarAttrs = {}\n\n\tget headerBarAttrs(): DialogHeaderBarAttrs {\n\t\treturn this._headerBarAttrs\n\t}\n\n\tconstructor(data: T, pages: ReadonlyArray<WizardPageWrapper<T>>, closeAction?: () => Promise<void>) {\n\t\tthis.data = data\n\t\tthis.pages = pages\n\t\tthis.currentPage = pages.find((p) => p.attrs.isEnabled()) ?? null\n\t\tthis.closeAction = closeAction\n\t\t\t? () => closeAction()\n\t\t\t: () => {\n\t\t\t\t\treturn Promise.resolve()\n\t\t\t  }\n\t\tthis.updateHeaderBarAttrs()\n\t}\n\n\tgoToPreviousPageOrClose(): void {\n\t\tlet currentPageIndex = this.currentPage ? this._getEnabledPages().indexOf(this.currentPage) : -1\n\n\t\tif (!this.allowedToVisitPage(currentPageIndex - 1, currentPageIndex)) return\n\n\t\tif (currentPageIndex > 0) {\n\t\t\tthis._goToPageAction(currentPageIndex - 1)\n\n\t\t\tm.redraw()\n\t\t} else {\n\t\t\tthis.closeAction()\n\t\t}\n\t}\n\n\tupdateHeaderBarAttrs<T>(): void {\n\t\tlet currentPageIndex = this.currentPage ? this._getEnabledPages().indexOf(this.currentPage) : -1\n\n\t\tconst backButtonAttrs: ButtonAttrs = {\n\t\t\tlabel: () => (currentPageIndex === 0 ? lang.get(\"cancel_action\") : lang.get(\"back_action\")),\n\t\t\tclick: () => this.goToPreviousPageOrClose(),\n\t\t\ttype: ButtonType.Secondary,\n\t\t}\n\t\tconst skipButtonAttrs: ButtonAttrs = {\n\t\t\tlabel: \"skip_action\",\n\t\t\tclick: () => this.goToNextPageOrCloseWizard(),\n\t\t\ttype: ButtonType.Secondary,\n\t\t}\n\n\t\t// the wizard dialog has a reference to this._headerBarAttrs -> changing this object changes the dialog\n\t\tObject.assign(this._headerBarAttrs, {\n\t\t\tleft: currentPageIndex >= 0 && this.allowedToVisitPage(currentPageIndex - 1, currentPageIndex) ? [backButtonAttrs] : [],\n\t\t\tright: () =>\n\t\t\t\tthis.currentPage &&\n\t\t\t\tthis.currentPage.attrs.isSkipAvailable() &&\n\t\t\t\tthis._getEnabledPages().indexOf(this.currentPage) !== this._getEnabledPages().length - 1\n\t\t\t\t\t? [skipButtonAttrs]\n\t\t\t\t\t: [],\n\t\t\tmiddle: () => (this.currentPage ? this.currentPage.attrs.headerTitle() : \"\"),\n\t\t})\n\t}\n\n\t_getEnabledPages(): Array<WizardPageWrapper<T>> {\n\t\treturn this.pages.filter((p) => p.attrs.isEnabled())\n\t}\n\n\t_goToPageAction(targetIndex: number): void {\n\t\tconst pages = this._getEnabledPages()\n\n\t\tthis.currentPage = pages[targetIndex]\n\t\tthis.updateHeaderBarAttrs()\n\t}\n\n\tgoToNextPageOrCloseWizard() {\n\t\tconst pages = this._getEnabledPages()\n\n\t\tconst currentIndex = this.currentPage ? pages.indexOf(this.currentPage) : -1\n\t\tconst lastIndex = pages.length - 1\n\t\tlet finalAction = currentIndex === lastIndex\n\n\t\tif (finalAction) {\n\t\t\tthis.closeAction()\n\t\t} else {\n\t\t\tthis._goToPageAction(currentIndex < lastIndex ? currentIndex + 1 : lastIndex)\n\t\t}\n\t}\n\n\t/** returns whether it is allowed to visit the page specified by pageIndex depending on selectedPageIndex */\n\tallowedToVisitPage(pageIndex: number, selectedPageIndex: number): boolean {\n\t\tif (pageIndex < 0 || selectedPageIndex < 0) {\n\t\t\treturn true // invalid values -> should not restrict here\n\t\t}\n\t\tconst enabledPages = this._getEnabledPages()\n\t\t// page is only allowed to be visited if it was already visited and there is no later page that was already visited and does not allow to go back\n\t\treturn (\n\t\t\tpageIndex < selectedPageIndex &&\n\t\t\t!enabledPages\n\t\t\t\t.filter((page, index) => {\n\t\t\t\t\treturn index > pageIndex && index <= selectedPageIndex\n\t\t\t\t})\n\t\t\t\t.some((page) => page.attrs.preventGoBack)\n\t\t)\n\t}\n}\n\ntype WizardPagingButtonAttrs = {\n\tpageIndex: number\n\tgetSelectedPageIndex: () => number\n\tisClickable: () => boolean\n\tnavigateBackHandler: (pageIndex: number) => void\n}\n\n//exported for old-style WizardDialog.js\nexport class WizardPagingButton {\n\tview(vnode: Vnode<WizardPagingButtonAttrs>): Children {\n\t\tconst selectedPageIndex = vnode.attrs.getSelectedPageIndex()\n\t\tconst pageIndex = vnode.attrs.pageIndex\n\t\tconst filledBg = getContentButtonIconBackground()\n\t\tconst isClickable = vnode.attrs.isClickable()\n\t\treturn m(\n\t\t\t\".button-content.flex-center.items-center\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\tmarginTop: \"-22px\",\n\t\t\t\t\tcursor: isClickable ? \"pointer\" : \"auto\",\n\t\t\t\t},\n\t\t\t\tonclick: () => {\n\t\t\t\t\tif (isClickable) {\n\t\t\t\t\t\tvnode.attrs.navigateBackHandler(pageIndex)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t\tm(\n\t\t\t\t\"button.button-icon.flex-center.items-center.no-hover\",\n\t\t\t\t{\n\t\t\t\t\ttabIndex: isClickable ? TabIndex.Default : TabIndex.Programmatic,\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tborder: selectedPageIndex === pageIndex ? `2px solid ${theme.content_accent}` : `1px solid ${filledBg}`,\n\t\t\t\t\t\tcolor: selectedPageIndex === pageIndex ? theme.content_accent : \"inherit\",\n\t\t\t\t\t\t\"background-color\": pageIndex < selectedPageIndex ? filledBg : theme.content_bg,\n\t\t\t\t\t\tcursor: isClickable ? \"pointer\" : \"auto\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpageIndex < selectedPageIndex\n\t\t\t\t\t? m(Icon, {\n\t\t\t\t\t\t\ticon: Icons.Checkmark,\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\tfill: theme.content_button_icon,\n\t\t\t\t\t\t\t\t\"background-color\": filledBg,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t  })\n\t\t\t\t\t: \"\" + (pageIndex + 1),\n\t\t\t),\n\t\t)\n\t}\n}\n\nexport type WizardDialogAttrsBuilder<T> = {\n\tdialog: Dialog\n\tattrs: WizardDialogAttrs<T>\n}\n\n// Use to generate a new wizard\nexport function createWizardDialog<T>(data: T, pages: ReadonlyArray<WizardPageWrapper<T>>, closeAction?: () => $Promisable<void>): WizardDialogAttrsBuilder<T> {\n\t// We need the close action of the dialog before we can create the proper attributes\n\n\tlet view: () => Children = () => null\n\n\tconst child: Component = {\n\t\tview: () => view(),\n\t}\n\tconst unregisterCloseListener = windowFacade.addWindowCloseListener(() => {})\n\tconst closeActionWrapper = async () => {\n\t\tif (closeAction) {\n\t\t\tawait closeAction()\n\t\t}\n\t\twizardDialog.close()\n\t\tunregisterCloseListener()\n\t}\n\tconst wizardDialogAttrs = new WizardDialogAttrs(data, pages, closeActionWrapper)\n\tconst wizardDialog = Dialog.largeDialog(wizardDialogAttrs.headerBarAttrs, child)\n\n\tview = () => m(WizardDialog, wizardDialogAttrs)\n\twizardDialog\n\t\t.addShortcut({\n\t\t\tkey: Keys.ESC,\n\t\t\texec: () => {\n\t\t\t\tconfirmThenCleanup(() => wizardDialogAttrs.closeAction())\n\t\t\t},\n\t\t\thelp: \"close_alt\",\n\t\t})\n\t\t.setCloseHandler(() => {\n\t\t\t// the dialogs popState handler will return false which prevents the wizard from being closed\n\t\t\t// we then close the wizard manually if the user confirms\n\t\t\tconfirmThenCleanup(() => wizardDialogAttrs.closeAction())\n\t\t})\n\n\treturn {\n\t\tdialog: wizardDialog,\n\t\tattrs: wizardDialogAttrs,\n\t}\n}\n\nasync function confirmThenCleanup(closeAction: () => Promise<void>) {\n\tconst confirmed = await Dialog.confirm(() => lang.get(\"closeWindowConfirmation_msg\"))\n\tif (confirmed) {\n\t\tcloseAction()\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport { progressIcon } from \"./Icon\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { downcast, neverNull } from \"@tutao/tutanota-utils\"\nimport { createDropdown, DropdownButtonAttrs } from \"./Dropdown.js\"\nimport { Icons } from \"./icons/Icons\"\nimport type { clickHandler } from \"./GuiUtils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { IconButton, IconButtonAttrs } from \"./IconButton.js\"\nimport { ButtonSize } from \"./ButtonSize.js\"\nimport { px, size } from \"../size.js\"\n\nassertMainOrNode()\n\nexport const enum ColumnWidth {\n\t// the column has a fixed small width\n\tSmall = \".column-width-small\",\n\t// all Largest columns equally share the rest of the available width\n\tLargest = \".column-width-largest\",\n}\n\n/**\n * @param columnHeading The texts that shall appear as headers of each column. Either a textId or function that returns the translation\n * @param columnWidths The sizes of the columns in px. If 0 is specified the column shares the remaining space with all other '0' width columns.\n * @param showActionButtonColumn True if addButton is specified or the table lines may contain action buttons.\n * @param addButton If set, this button appears beside the expander button.\n * @param lines the lines of the table\n */\nexport type TableAttrs = {\n\tcolumnHeading?: Array<lazy<string> | TranslationKey>\n\tcolumnWidths: ReadonlyArray<ColumnWidth>\n\tcolumnAlignments?: Array<boolean>\n\tverticalColumnHeadings?: boolean\n\tshowActionButtonColumn: boolean\n\taddButtonAttrs?: IconButtonAttrs | null\n\tlines: ReadonlyArray<TableLineAttrs> | null\n}\nexport type CellTextData = {\n\tmain: string\n\tinfo?: string[]\n\tclick?: clickHandler\n\tmainStyle?: string\n}\nexport type TableLineAttrs = {\n\tcells: string[] | (() => CellTextData[])\n\tactionButtonAttrs?: IconButtonAttrs | null\n}\n\n/**\n * Shows a table of TableLine entries. The last column of the table may show action buttons for each TableLine and/or an add button.\n * The table shows a loading spinner until updateEntries() is called the first time.\n */\nexport class Table implements Component<TableAttrs> {\n\tview(vnode: Vnode<TableAttrs>): Children {\n\t\tconst a = vnode.attrs\n\t\tconst loading = !a.lines\n\t\tconst alignments = a.columnAlignments || []\n\t\tconst lineAttrs = a.lines\n\t\t\t? a.lines.map((lineAttrs) => this._createLine(lineAttrs, a.showActionButtonColumn, a.columnWidths, false, alignments, false))\n\t\t\t: []\n\t\treturn m(\"\", [\n\t\t\tm(`table.table${a.columnHeading ? \".table-header-border\" : \"\"}`, [\n\t\t\t\t(a.columnHeading\n\t\t\t\t\t? [\n\t\t\t\t\t\t\tthis._createLine(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcells: a.columnHeading.map((textIdOrFunction) => lang.getMaybeLazy(textIdOrFunction)),\n\t\t\t\t\t\t\t\t\tactionButtonAttrs: loading ? null : a.addButtonAttrs,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ta.showActionButtonColumn,\n\t\t\t\t\t\t\t\ta.columnWidths,\n\t\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t\talignments,\n\t\t\t\t\t\t\t\ta.verticalColumnHeadings ?? false,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t  ]\n\t\t\t\t\t: []\n\t\t\t\t).concat(lineAttrs),\n\t\t\t]),\n\t\t\tloading ? m(\".flex-center.items-center.button-height\", progressIcon()) : null,\n\t\t\t!loading && neverNull(a.lines).length === 0 ? m(\".flex-center.items-center.button-height\", lang.get(\"noEntries_msg\")) : null,\n\t\t])\n\t}\n\n\t_createLine(\n\t\tlineAttrs: TableLineAttrs,\n\t\tshowActionButtonColumn: boolean,\n\t\tcolumnWidths: ReadonlyArray<ColumnWidth>,\n\t\tbold: boolean,\n\t\tcolumnAlignments: Array<boolean>,\n\t\tverticalText: boolean,\n\t): Children {\n\t\tlet cells\n\n\t\tif (typeof lineAttrs.cells == \"function\") {\n\t\t\tcells = lineAttrs.cells().map((cellTextData, index) =>\n\t\t\t\tm(\"td\", [\n\t\t\t\t\tm(\n\t\t\t\t\t\t\".text-ellipsis.pr.pt-s\" +\n\t\t\t\t\t\t\tcolumnWidths[index] +\n\t\t\t\t\t\t\t(bold ? \".b\" : \"\") +\n\t\t\t\t\t\t\t(cellTextData.click ? \".click\" : \"\" + (cellTextData.mainStyle ? cellTextData.mainStyle : \"\")) +\n\t\t\t\t\t\t\t(columnAlignments[index] ? \".right\" : \"\"),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttitle: cellTextData.main,\n\t\t\t\t\t\t\t// show the text as tooltip, so ellipsed lines can be shown\n\t\t\t\t\t\t\tonclick: (event: MouseEvent) => {\n\t\t\t\t\t\t\t\tconst dom = downcast(event.target)\n\t\t\t\t\t\t\t\tcellTextData.click ? cellTextData.click(event, dom) : null\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tverticalText ? m(\"span.vertical-text\", cellTextData.main) : cellTextData.main,\n\t\t\t\t\t),\n\t\t\t\t\tm(\n\t\t\t\t\t\t\".small.text-ellipsis.pr\" + (cellTextData.click ? \".click\" : \"\"),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tonclick: (event: MouseEvent) => {\n\t\t\t\t\t\t\t\tconst dom = downcast(event.target)\n\t\t\t\t\t\t\t\tcellTextData.click ? cellTextData.click(event, dom) : null\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcellTextData.info ? cellTextData.info.map((line) => m(\"\", line)) : null,\n\t\t\t\t\t),\n\t\t\t\t]),\n\t\t\t)\n\t\t} else {\n\t\t\tcells = lineAttrs.cells.map((text, index) =>\n\t\t\t\tm(\n\t\t\t\t\t\"td.text-ellipsis.pr.pt-s.pb-s.\" + columnWidths[index] + (bold ? \".b\" : \"\") + (columnAlignments[index] ? \".right\" : \"\"),\n\t\t\t\t\t{\n\t\t\t\t\t\ttitle: text, // show the text as tooltip, so ellipsed lines can be shown\n\t\t\t\t\t},\n\t\t\t\t\tverticalText ? m(\"span.vertical-text\", text) : text,\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\n\t\tif (showActionButtonColumn) {\n\t\t\tcells.push(\n\t\t\t\tm(\n\t\t\t\t\t\"td\",\n\t\t\t\t\t{\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\twidth: px(size.button_height_compact),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tlineAttrs.actionButtonAttrs ? m(IconButton, lineAttrs.actionButtonAttrs) : [],\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\n\t\treturn m(\"tr.selectable\", cells)\n\t}\n}\n\ninterface UpdateableInstanceWithArray<T> {\n\tgetArray: () => Array<T>\n\tupdateInstance: () => Promise<void>\n}\n\nexport function createRowActions<T>(\n\tinstance: UpdateableInstanceWithArray<T>,\n\tcurrentElement: T,\n\tindexOfElement: number,\n\tprefixActions: ReadonlyArray<DropdownButtonAttrs> = [],\n): IconButtonAttrs {\n\tconst elements = instance.getArray()\n\tconst makeButtonAttrs: () => ReadonlyArray<DropdownButtonAttrs | null> = () => [\n\t\t...prefixActions,\n\t\tindexOfElement > 1\n\t\t\t? {\n\t\t\t\t\tlabel: \"moveToTop_action\",\n\t\t\t\t\tclick: () => {\n\t\t\t\t\t\telements.splice(indexOfElement, 1)\n\t\t\t\t\t\telements.unshift(currentElement)\n\t\t\t\t\t\tinstance.updateInstance()\n\t\t\t\t\t},\n\t\t\t  }\n\t\t\t: null,\n\t\tindexOfElement > 0\n\t\t\t? {\n\t\t\t\t\tlabel: \"moveUp_action\",\n\t\t\t\t\tclick: () => {\n\t\t\t\t\t\tlet prev = elements[indexOfElement - 1]\n\t\t\t\t\t\telements[indexOfElement - 1] = currentElement\n\t\t\t\t\t\telements[indexOfElement] = prev\n\t\t\t\t\t\tinstance.updateInstance()\n\t\t\t\t\t},\n\t\t\t  }\n\t\t\t: null,\n\t\tindexOfElement < instance.getArray().length - 1\n\t\t\t? {\n\t\t\t\t\tlabel: \"moveDown_action\",\n\t\t\t\t\tclick: () => {\n\t\t\t\t\t\tlet next = elements[indexOfElement + 1]\n\t\t\t\t\t\telements[indexOfElement + 1] = currentElement\n\t\t\t\t\t\telements[indexOfElement] = next\n\t\t\t\t\t\tinstance.updateInstance()\n\t\t\t\t\t},\n\t\t\t  }\n\t\t\t: null,\n\t\tindexOfElement < instance.getArray().length - 2\n\t\t\t? {\n\t\t\t\t\tlabel: \"moveToBottom_action\",\n\t\t\t\t\tclick: () => {\n\t\t\t\t\t\telements.splice(indexOfElement, 1)\n\t\t\t\t\t\telements.push(currentElement)\n\t\t\t\t\t\tinstance.updateInstance()\n\t\t\t\t\t},\n\t\t\t  }\n\t\t\t: null,\n\t\t{\n\t\t\tlabel: \"delete_action\",\n\t\t\tclick: () => {\n\t\t\t\telements.splice(indexOfElement, 1)\n\t\t\t\tinstance.updateInstance()\n\t\t\t},\n\t\t},\n\t]\n\treturn {\n\t\ttitle: \"edit_action\",\n\t\tclick: createDropdown({ lazyButtons: makeButtonAttrs, width: 260 }),\n\t\ticon: Icons.More,\n\t\tsize: ButtonSize.Compact,\n\t}\n}\n","import { ListElement } from \"../../api/common/utils/EntityUtils.js\"\nimport { ListModel } from \"../../misc/ListModel.js\"\nimport { Shortcut } from \"../../misc/KeyManager.js\"\nimport { Keys } from \"../../api/common/TutanotaConstants.js\"\nimport { mapLazily } from \"@tutao/tutanota-utils\"\nimport { ListState, MultiselectMode } from \"./List.js\"\nimport { Children } from \"mithril\"\n\nexport const ACTION_DISTANCE = 150\nexport const PageSize = 100\n\n/**\n * 1:1 mapping to DOM elements. Displays a single list entry.\n */\nexport interface VirtualRow<ElementType> {\n\trender(): Children\n\n\tupdate(listEntry: ElementType, selected: boolean, isInMultiSelect: boolean): void\n\n\tentity: ElementType | null\n\ttop: number\n\tdomElement: HTMLElement | null\n}\n\nexport interface ListFetchResult<ElementType> {\n\titems: Array<ElementType>\n\t/** Complete means that we loaded the whole list and additional requests will not yield any results. */\n\tcomplete: boolean\n}\n\nexport function listSelectionKeyboardShortcuts<T extends ListElement>(multiselectMode: MultiselectMode, list: () => ListModel<T> | null): Array<Shortcut> {\n\tconst multiselectionEnabled = multiselectMode == MultiselectMode.Enabled ? () => true : () => false\n\treturn [\n\t\t{\n\t\t\tkey: Keys.UP,\n\t\t\texec: mapLazily(list, (list) => list?.selectPrevious(false)),\n\t\t\thelp: \"selectPrevious_action\",\n\t\t},\n\t\t{\n\t\t\tkey: Keys.K,\n\t\t\texec: mapLazily(list, (list) => list?.selectPrevious(false)),\n\t\t\thelp: \"selectPrevious_action\",\n\t\t},\n\t\t{\n\t\t\tkey: Keys.UP,\n\t\t\tshift: true,\n\t\t\texec: mapLazily(list, (list) => list?.selectPrevious(true)),\n\t\t\thelp: \"addPrevious_action\",\n\t\t\tenabled: multiselectionEnabled,\n\t\t},\n\t\t{\n\t\t\tkey: Keys.K,\n\t\t\tshift: true,\n\t\t\texec: mapLazily(list, (list) => list?.selectPrevious(true)),\n\t\t\thelp: \"addPrevious_action\",\n\t\t\tenabled: multiselectionEnabled,\n\t\t},\n\t\t{\n\t\t\tkey: Keys.DOWN,\n\t\t\texec: mapLazily(list, (list) => list?.selectNext(false)),\n\t\t\thelp: \"selectNext_action\",\n\t\t},\n\t\t{\n\t\t\tkey: Keys.J,\n\t\t\texec: mapLazily(list, (list) => list?.selectNext(false)),\n\t\t\thelp: \"selectNext_action\",\n\t\t},\n\t\t{\n\t\t\tkey: Keys.DOWN,\n\t\t\tshift: true,\n\t\t\texec: mapLazily(list, (list) => list?.selectNext(true)),\n\t\t\thelp: \"addNext_action\",\n\t\t\tenabled: multiselectionEnabled,\n\t\t},\n\t\t{\n\t\t\tkey: Keys.J,\n\t\t\tshift: true,\n\t\t\texec: mapLazily(list, (list) => list?.selectNext(true)),\n\t\t\thelp: \"addNext_action\",\n\t\t\tenabled: multiselectionEnabled,\n\t\t},\n\t\t{\n\t\t\tkey: Keys.A,\n\t\t\tctrl: true,\n\t\t\tshift: true,\n\t\t\texec: mapLazily(list, (list) => (list?.areAllSelected() ? list.selectNone() : list?.selectAll())),\n\t\t\thelp: \"selectAllLoaded_action\",\n\t\t\tenabled: multiselectionEnabled,\n\t\t},\n\t]\n}\n\nexport function onlySingleSelection<T>(state: ListState<T>): T | null {\n\tif (state.selectedItems.size === 1) {\n\t\treturn state.selectedItems.values().next().value\n\t} else {\n\t\treturn null\n\t}\n}\n","export const enum Icons {\n\tAdd = \"Add\",\n\tAlignLeft = \"AlignLeft\",\n\tAlignRight = \"AlignRight\",\n\tAlignCenter = \"AlignCenter\",\n\tAlignJustified = \"AlignJustified\",\n\tArrowBackward = \"ArrowBackward\",\n\tArrowForward = \"ArrowForward\",\n\tAttachment = \"Attachment\",\n\tBold = \"Bold\",\n\tBook = \"Book\",\n\tCall = \"Call\",\n\tCancel = \"Cancel\",\n\tCheckmark = \"Checkmark\",\n\tCode = \"Code\",\n\tContactImport = \"ContactImport\",\n\tDesktop = \"Desktop\",\n\tDownload = \"Download\",\n\tEdit = \"Edit\",\n\tItalic = \"Italic\",\n\tLink = \"Link\",\n\tListUnordered = \"ListUnordered\",\n\tListOrdered = \"ListOrdered\",\n\tLogin = \"Login\",\n\tLock = \"Lock\",\n\tMatchCase = \"MatchCase\",\n\tMobile = \"Mobile\",\n\tMore = \"More\",\n\tNewWindow = \"NewWindow\",\n\tPin = \"Pin\",\n\tTrash = \"Trash\",\n\tTrashEmpty = \"TrashEmpty\",\n\tUnderline = \"Underline\",\n\tUnlock = \"Unlock\",\n\tWarning = \"Warning\",\n\tWarningOutline = \"WarningOutline\",\n\tNoEye = \"NoEye\",\n\tEye = \"Eye\",\n\tPeople = \"People\",\n\tPrint = \"Print\",\n\tChat = \"Chat\",\n\tCopy = \"Copy\",\n\tClose = \"Close\",\n\tPicture = \"Picture\",\n\tFontSize = \"FontSize\",\n\tTable = \"Table\",\n\tTableColumns = \"TableColumns\",\n\tTableSingle = \"TableSingle\",\n\tLanguage = \"Language\",\n\tListAlt = \"ListAlt\",\n\tNotifications = \"Notifications\",\n\tArrowDropLeft = \"ArrowDropLeft\",\n\tArrowDropRight = \"ArrowDropRight\",\n\tPower = \"Power\",\n\tPalette = \"Palette\",\n\tImport = \"Import\",\n\tExport = \"Export\",\n\tPencilSquare = \"PencilSquare\",\n\tTime = \"Time\",\n\tCircleCheckmark = \"CircleCheckmark\",\n\tCircleReject = \"CircleReject\",\n\tCircleHelp = \"CircleHelp\",\n\tCircleEmpty = \"CircleEmpty\",\n\tGift = \"Gift\",\n\tClipboard = \"Clipboard\",\n\tQuestionMark = \"QuestionMark\",\n\tFormatClear = \"FormatClear\",\n\tAddCheckCirle = \"AddCheckCirle\",\n\tReply = \"Reply\",\n\tInbox = \"Inbox\",\n\tArchive = \"Archive\",\n\tDraft = \"Draft\",\n\tSend = \"Send\",\n\tFolder = \"Folder\",\n\tSpam = \"Spam\",\n\tTrashBin = \"TrashBin\",\n\tBulb = \"Bulb\",\n\tCreditCard = \"CreditCard\",\n\tWand = \"Wand\",\n\tFilter = \"Filter\",\n\tReplyAll = \"ReplyAll\",\n\tForward = \"Forward\",\n}\n\nexport const IconsSvg: Record<Icons, string> = Object.freeze({\n\tAdd: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M416 277.333H277.333V416h-42.666V277.333H96v-42.666h138.667V96h42.666v138.667H416v42.666z\"/></svg>`,\n\tAlignLeft: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 42v-3h36v3Zm0-8.25v-3h23.6v3Zm0-8.25v-3h36v3Zm0-8.25v-3h23.6v3ZM6 9V6h36v3Z\"/></svg>`,\n\tAlignRight: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 42v-3h36v3Zm12.45-8.25v-3H42v3ZM6 25.5v-3h36v3Zm12.45-8.25v-3H42v3ZM6 9V6h36v3Z\"/></svg>`,\n\tAlignCenter: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 42v-3h36v3Zm8.2-8.25v-3h19.65v3ZM6 25.5v-3h36v3Zm8.2-8.25v-3h19.65v3ZM6 9V6h36v3Z\"/></svg>`,\n\tAlignJustified: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 42v-3h36v3Zm0-8.25v-3h36v3Zm0-8.25v-3h36v3Zm0-8.25v-3h36v3ZM6 9V6h36v3Z\"/></svg>`,\n\tArrowBackward: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M352 128.4 319.7 96 160 256l159.7 160 32.3-32.4L224.7 256z\"/></svg>`,\n\tArrowForward: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M287.3 256 160 383.6l32.3 32.4L352 256 192.3 96 160 128.4z\"/></svg>`,\n\tAttachment: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M341.334 128v234.666C341.334 409.604 302.938 448 256 448c-46.937 0-85.333-38.396-85.333-85.334V117.334C170.667 87.47 194.135 64 224 64c29.864 0 53.333 23.47 53.333 53.334v245.333c0 11.73-9.605 21.333-21.334 21.333-11.73 0-21.334-9.604-21.334-21.333V160h-32v202.667C202.666 392.53 226.136 416 256 416c29.865 0 53.334-23.47 53.334-53.333V117.334C309.334 70.4 270.938 32 224 32s-85.334 38.4-85.334 85.334v245.332C138.666 427.73 190.938 480 256 480c65.062 0 117.334-52.27 117.334-117.334V128h-32z\"/></svg>`,\n\tBold: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.15 37.85V7.3H26.7q3.65 0 6.325 2.4 2.675 2.4 2.675 6 0 1.95-1 3.65t-2.75 2.5V22q2.2.8 3.45 2.775 1.25 1.975 1.25 4.375 0 3.75-2.875 6.225Q30.9 37.85 27.05 37.85Zm6.15-18.1h7.35q1.55 0 2.65-1.075 1.1-1.075 1.1-2.625t-1.1-2.625q-1.1-1.075-2.65-1.075H18.3Zm0 13h7.75q1.7 0 2.925-1.15 1.225-1.15 1.225-2.85 0-1.7-1.225-2.875T26.05 24.7H18.3Z\"/></svg>`,\n\tBook: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M164.466 64C109.266 64 64 89.98 64 143v283h22.14c12.86-26.334 44.24-42 78.326-42 40.224 0 73.877 27.528 81.616 64H248V95.346C230.76 73.95 198.98 64 164.466 64zm183.154 0c-34.33 0-66.712 9.85-83.62 31.01V448h1.797c7.74-36.472 41.495-64 81.722-64 34.084 0 61.148 11.666 78.428 42H448V143c0-53.02-45.177-79-100.38-79z\"/></svg>`,\n\tCall: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M426.666 330.667c-26.666 0-52.27-4.27-75.73-11.73-7.468-2.135-16-1.072-21.33 5.334l-46.94 46.93c-60.802-30.93-109.864-80-140.802-140.804l46.94-46.927c5.33-5.334 7.46-13.865 5.33-21.334-8.536-24.53-12.8-50.136-12.8-76.803 0-11.73-9.6-21.333-21.334-21.333H85.333C73.6 64 64 73.604 64 85.333 64 285.863 226.136 448 426.666 448c11.73 0 21.334-9.604 21.334-21.333V352c0-11.73-9.604-21.333-21.334-21.333z\"/></svg>`,\n\tCancel: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M405 136.798 375.202 107 256 226.202 136.798 107 107 136.798 226.202 256 107 375.202 136.798 405 256 285.798 375.202 405 405 375.202 285.798 256z\"/></svg>`,\n\tCheckmark: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M186.3 339.893 96 249.46l-32 30.51L186.3 402 448 140.506 416 110z\"/></svg>`,\n\tCode: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M190.4 354.1 91.9 256l98.4-98.1-30-29.9L32 256l128.4 128 30-29.9zm131.2 0L420 256l-98.4-98.1 30-29.9L480 256 351.6 384l-30-29.9z\"/></svg>`,\n\tContactImport: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M304 256c52.805 0 96-43.2 96-96s-43.195-96-96-96-96 43.2-96 96 43.195 96 96 96zm0 48c-63.598 0-192 32.402-192 96v48h384v-48c0-63.598-128.402-96-192-96zm-192-80v-64H80v64H16v32h64v64h32v-64h64v-32h-64z\"/></svg>`,\n\tDesktop: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M496 384V96H16v288h175v16h-64v16h257v-16h-64v-16h176zM32 112h448v256H32V112z\"/><path d=\"M48 128h416v224H48z\"/></svg>`,\n\tDownload: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M416 199.5h-91.4V64H187.4v135.5H96l160 158.1 160-158.1zM96 402.8V448h320v-45.2H96z\"/></svg>`,\n\tEdit: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M64 368v80h80l235.727-235.73-80-79.997L64 368zm377.602-217.602c8.53-8.53 8.53-21.334 0-29.865l-50.135-50.135c-8.53-8.53-21.334-8.53-29.865 0l-39.468 39.47 80 79.997 39.468-39.467z\"/></svg>`,\n\tItalic: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 40v-5h6.85l8.9-22H18V8h20v5h-6.85l-8.9 22H30v5Z\"/></svg>`,\n\tLink: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M22.35 34.3H14q-4.3 0-7.3-3t-3-7.3q0-4.3 3-7.3t7.3-3h8.35v3.4H14q-2.9 0-4.9 2-2 2-2 4.9 0 2.85 2 4.875T14 30.9h8.35Zm-6.3-8.75v-3.1h15.9v3.1Zm9.6 8.75v-3.4H34q2.9 0 4.9-2 2-2 2-4.9 0-2.85-2-4.875T34 17.1h-8.35v-3.4H34q4.3 0 7.3 3t3 7.3q0 4.3-3 7.3t-7.3 3Z\"/></svg>`,\n\tListUnordered: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8.3 39.2q-1.1 0-1.9-.775-.8-.775-.8-1.875 0-1.15.8-1.95t1.95-.8q1.1 0 1.875.8.775.8.775 1.95 0 1.1-.775 1.875-.775.775-1.925.775Zm7.7-1v-3.4h26.4v3.4ZM8.3 26.7q-1.1 0-1.9-.8-.8-.8-.8-1.9 0-1.15.8-1.925.8-.775 1.95-.775 1.1 0 1.875.8.775.8.775 1.9 0 1.1-.775 1.9-.775.8-1.925.8Zm7.7-1v-3.4h26.4v3.4ZM8.3 14.2q-1.15 0-1.925-.8-.775-.8-.775-1.9 0-1.15.775-1.925Q7.15 8.8 8.3 8.8t1.925.8q.775.8.775 1.9 0 1.15-.8 1.925-.8.775-1.9.775Zm7.7-1V9.8h26.4v3.4Z\"/></svg>`,\n\tListOrdered: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.9 40v-1.7h4.2V37H8v-1.7h2.1V34H5.9v-1.7h6V40Zm10.35-2.25v-3.4h26v3.4Zm-10.5-9.9v-1.6L9.4 22H5.75v-1.85h6.15v1.6L8.25 26h3.65v1.85Zm10.5-2.25v-3.4h26v3.4ZM8 15.8V9.85H5.9V8h3.9v7.8Zm8.25-2.35v-3.4h26v3.4Z\"/></svg>`,\n\tLogin: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 48c-42.9 0-84.2 13-119.2 37.5-34.2 24-60.2 57.2-75.1 96.1L58 192h45.7l1.9-5c8.2-17.8 19.4-33.9 33.5-48 31.2-31.2 72.7-48.4 116.9-48.4s85.7 17.2 116.9 48.4c31.2 31.2 48.4 72.7 48.4 116.9 0 44.1-17.2 85.7-48.4 116.9-31.2 31.2-72.7 48.4-116.9 48.4-44.1 0-85.6-17.2-116.9-48.4-14-14-25.3-30.1-33.5-47.9l-1.9-5H58l3.6 10.4c14.9 38.9 40.9 72.1 75.1 96.1C171.8 451.1 213 464 256 464c114.7 0 208-93.3 208-208S370.7 48 256 48z\"/><path d=\"M48 277.4h189.7l-43.6 44.7L224 352l96-96-96-96-31 29.9 44.7 44.7H48v42.8z\"/></svg>`,\n\tLock: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M376 186h-20v-40c0-55-45-100-100-100S156 91 156 146v40h-20c-22.002 0-40 17.998-40 40v200c0 22.002 17.998 40 40 40h240c22.002 0 40-17.998 40-40V226c0-22.002-17.998-40-40-40zM256 368c-22.002 0-40-17.998-40-40s17.998-40 40-40 40 17.998 40 40-17.998 40-40 40zm62.002-182H193.998v-40c0-34.004 28.003-62.002 62.002-62.002 34.004 0 62.002 27.998 62.002 62.002v40z\"/></svg>`,\n\tMatchCase: `<svg xml:space=\"preserve\" viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><g style=\"font-style:normal;font-weight:400;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0;word-spacing:0;fill-opacity:1;stroke:none\" aria-label=\"Aa\"><path d=\"M145.05 93.731 88.808 311.588h112.688zm-23.4-58.349h47.004l116.794 437.766h-43.105l-27.916-112.3H76.287l-27.915 112.3H4.652ZM432.824 308.07q-45.773 0-63.425 14.953-17.652 14.954-17.652 51.02 0 28.734 13.136 45.74 13.342 16.713 36.126 16.713 31.405 0 50.289-31.667 19.089-31.96 19.089-84.738V308.07zm75.33-22.285v187.363h-37.767v-49.846q-12.931 29.908-32.226 44.275-19.294 14.074-47.21 14.074-35.304 0-56.241-28.148-20.731-28.442-20.731-75.942 0-55.417 25.863-83.566 26.068-28.148 77.588-28.148h52.957v-5.278q0-37.238-17.242-57.47-17.036-20.524-48.03-20.524-19.706 0-38.384 6.743-18.68 6.744-35.92 20.232v-49.846q20.73-11.435 40.23-17.006 19.5-5.864 37.973-5.864 49.878 0 74.51 36.944 24.63 36.945 24.63 112.007z\"/></g></svg>`,\n\tMobile: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M335.7 32H177.1C158.8 32 144 46.6 144 64.9v381c0 18.4 14.8 34.1 33.1 34.1h158.5c18.3 0 32.3-15.7 32.3-34.1v-381C368 46.6 354 32 335.7 32zM241 55h30c2.2 0 4 1.8 4 4s-1.8 4-4 4h-30c-2.2 0-4-1.8-4-4s1.8-4 4-4zm15.5 414c-9.6 0-17.4-7.8-17.4-17.4 0-9.6 7.8-17.4 17.4-17.4 9.6 0 17.4 7.8 17.4 17.4 0 9.6-7.8 17.4-17.4 17.4zm95.5-45H160V83h192v341z\"/><path d=\"M256.5 441.6c-5.5 0-10 4.5-10 9.9 0 5.5 4.5 10 10 10s10-4.5 10-10c-.1-5.4-4.5-9.9-10-9.9z\"/></svg>`,\n\tMore: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 224c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm-127.6 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.4-32-32-32zm255.6 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32z\"/></svg>`,\n\tNewWindow: `<svg width=\"512\" height=\"512\" viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M184 112c-39.764 0-72 32.236-72 72v224c0 39.764 32.236 72 72 72h224c39.764 0 72-32.236 72-72V184c0-39.764-32.236-72-72-72zm17.295 67.705h190.928c25.298 0 45.664 20.366 45.664 45.664v168.262c0 25.298-20.366 45.664-45.664 45.664H201.295c-25.298 0-45.666-20.366-45.666-45.664V225.369c0-25.298 20.368-45.664 45.666-45.664z\"/><path d=\"M160 80h235.88A72.12 72.12 0 0 0 328 32H104a72 72 0 0 0-72 72v224a72.12 72.12 0 0 0 48 67.88V160a80 80 0 0 1 80-80Z\"/><g aria-label=\"+\" style=\"font-style:normal;font-weight:400;font-size:25.94447517px;line-height:1.25;font-family:sans-serif;letter-spacing:0;word-spacing:0;fill-opacity:1;stroke:#000;stroke-width:28.21417236;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1\"><path style=\"color:#000;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:259.44476318px;line-height:1.25;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;letter-spacing:0;word-spacing:0;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000;solid-opacity:1;vector-effect:none;fill-opacity:1;fill-rule:nonzero;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none\" d=\"M279.336 225.113a14.108 14.108 0 0 0-14.107 14.108v56.455h-56.456a14.108 14.108 0 0 0-14.107 14.105v21.537a14.108 14.108 0 0 0 14.107 14.108h56.456v56.453a14.108 14.108 0 0 0 14.107 14.107h21.283a14.108 14.108 0 0 0 14.106-14.107v-56.453h56.455a14.108 14.108 0 0 0 14.107-14.108v-21.537a14.108 14.108 0 0 0-14.107-14.105h-56.455V239.22a14.108 14.108 0 0 0-14.106-14.108zm10.635 93.91a14.108 14.108 0 0 0 1.547 1.518 14.108 14.108 0 0 0-1.536 1.535 14.108 14.108 0 0 0-1.546-1.517 14.108 14.108 0 0 0 1.535-1.536z\" stroke=\"none\" transform=\"translate(4 -6)\"/></g></svg>`,\n\tPin: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 48c-79.5 0-144 59.9-144 133.7 0 104 144 282.3 144 282.3s144-178.3 144-282.3C400 107.9 335.5 48 256 48zm0 190.9c-25.9 0-46.9-21-46.9-46.9s21-46.9 46.9-46.9 46.9 21 46.9 46.9-21 46.9-46.9 46.9z\"/></svg>`,\n\tTrash: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M128 405.43c0 23.416 19.198 42.57 42.667 42.57h170.667C364.802 448 384 428.846 384 405.43V160H128v245.43zM416 96h-80l-26.785-32h-106.43L176 96H96v32h320V96z\"/></svg>`,\n\tTrashEmpty: `<svg xml:space=\"preserve\" viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><g><path d=\"M18.397 253.302C-.698 266.856-5.205 293.598 8.38 312.736l98.787 139.17c13.584 19.138 40.315 23.706 59.41 10.152l200.136-142.06-148.18-208.757zm493.146-70.445-73.959-30.498-12.563-39.794-98.392-40.573-36.962 19.372-73.959-30.498L203.51 90.45l295.835 121.99Z\"/></g></svg>`,\n\tUnderline: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.8 42.35v-3.4h28.4v3.4Zm14.2-8.3q-5.15 0-8.675-3.5-3.525-3.5-3.525-8.6V5.65h4.4v16.4q0 3.2 2.25 5.4t5.55 2.2q3.3 0 5.55-2.2t2.25-5.4V5.65h4.4v16.3q0 5.1-3.525 8.6T24 34.05Z\"/></svg>`,\n\tUnlock: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M376 186h-20v-40c0-55-45-100-100-100S156 91 156 146h37.998c0-34.004 28.003-62.002 62.002-62.002 34.004 0 62.002 27.998 62.002 62.002H318v40H136c-22.002 0-40 17.998-40 40v200c0 22.002 17.998 40 40 40h240c22.002 0 40-17.998 40-40V226c0-22.002-17.998-40-40-40zM256 368c-22.002 0-40-17.998-40-40s17.998-40 40-40 40 17.998 40 40-17.998 40-40 40z\"/></svg>`,\n\tWarning: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M32 464h448L256 48 32 464zm248-64h-48v-48h48v48zm0-80h-48v-96h48v96z\"/></svg>`,\n\tWarningOutline: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 368c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-11.8-94.3V208h24v65.7l-6 70.3h-12l-6-70.3z\"/><path d=\"M256 97.5 437.2 432H74.8L256 97.5m0-33.5L48 448h416L256 64z\"/></svg>`,\n\tNoEye: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256.1 144.8c56.2 0 101.9 45.3 101.9 101.1 0 13.1-2.6 25.5-7.3 37l59.5 59c30.8-25.5 55-58.4 69.9-96-35.3-88.7-122.3-151.6-224.2-151.6-28.5 0-55.8 5.1-81.1 14.1l44 43.7c11.6-4.6 24.1-7.3 37.3-7.3zM52.4 89.7l46.5 46.1 9.4 9.3c-33.9 26-60.4 60.8-76.3 100.8 35.2 88.7 122.2 151.6 224.1 151.6 31.6 0 61.7-6.1 89.2-17l8.6 8.5 59.7 59 25.9-25.7L78.2 64 52.4 89.7zM165 201.4l31.6 31.3c-1 4.2-1.6 8.7-1.6 13.1 0 33.5 27.3 60.6 61.1 60.6 4.5 0 9-.6 13.2-1.6l31.6 31.3c-13.6 6.7-28.7 10.7-44.8 10.7-56.2 0-101.9-45.3-101.9-101.1 0-15.8 4.1-30.7 10.8-44.3zm87.8-15.7 64.2 63.7.4-3.2c0-33.5-27.3-60.6-61.1-60.6l-3.5.1z\"/></svg>`,\n\tEye: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 105c-101.8 0-188.4 62.4-224 151 35.6 88.6 122.2 151 224 151s188.4-62.4 224-151c-35.6-88.6-122.2-151-224-151zm0 251.7c-56 0-101.8-45.3-101.8-100.7S200 155.3 256 155.3 357.8 200.6 357.8 256 312 356.7 256 356.7zm0-161.1c-33.6 0-61.1 27.2-61.1 60.4s27.5 60.4 61.1 60.4 61.1-27.2 61.1-60.4-27.5-60.4-61.1-60.4z\"/></svg>`,\n\tPeople: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M337.454 232c33.6 0 61.092-27.002 61.092-60 0-32.997-27.493-60-61.092-60s-61.09 27.003-61.09 60c0 32.998 27.49 60 61.09 60zm-162.908 0c33.6 0 61.09-27.002 61.09-60 0-32.997-27.49-60-61.09-60s-61.092 27.003-61.092 60c0 32.998 27.493 60 61.092 60zm0 44C126.688 276 32 298.998 32 346v54h288v-54c0-47.002-97.6-70-145.454-70zm162.908 11.003c-6.105 0-10.325 0-17.454.997 23.426 17.002 32 28 32 58v54h128v-54c0-47.002-94.688-58.997-142.546-58.997z\"/></svg>`,\n\tPrint: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M399.95 160h-287.9C76.824 160 48 188.803 48 224v138.667h79.9V448h256.2v-85.333H464V224c0-35.197-28.825-64-64.05-64zM352 416H160V288h192v128zm32.1-352H127.9v80h256.2V64z\"/></svg>`,\n\tChat: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M336 48H48v224h112V160h176z\"/><path d=\"M176 176v224h162.6l64 64H416v-64h48V176H176z\"/></svg>`,\n\tCopy: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M144 416V112h-32v336h240v-32H160z\"/><path d=\"M325.3 64H160v336h240V139l-74.7-75zM368 176h-80V96h16v64h64v16z\"/></svg>`,\n\tClose: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m340.2 160-84.4 84.3-84-83.9-11.8 11.8 84 83.8-84 83.9 11.8 11.7 84-83.8 84.4 84.2 11.8-11.7-84.4-84.3 84.4-84.2z\" class=\"st0\"/></svg>`,\n\tPicture: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M174.9 166.48c0 27.719-22.489 50.208-50.208 50.208-27.719 0-50.208-22.489-50.208-50.208 0-27.719 22.489-50.208 50.208-50.208 27.719 0 50.208 22.489 50.208 50.208zM442.67 266.9v117.15H74.48v-50.208l83.68-83.68 41.84 41.84 133.89-133.89zm25.104-184.1h-418.4c-4.446 0-8.368 3.922-8.368 8.368v317.98c0 4.446 3.922 8.368 8.368 8.368h418.4c4.445 0 8.368-3.922 8.368-8.368V91.168c0-4.446-3.923-8.368-8.368-8.368zm41.84 8.368v317.98c0 23.012-18.828 41.84-41.84 41.84h-418.4c-23.012 0-41.84-18.828-41.84-41.84V91.168c0-23.012 18.828-41.84 41.84-41.84h418.4c23.012 0 41.84 18.828 41.84 41.84z\"/></svg>`,\n\tFontSize: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M28.5 40V13H18V8h26v5H33.5v27Zm-18 0V23H4v-5h18v5h-6.5v17Z\"/></svg>`,\n\tTable: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" height=\"512\" width=\"512\"><path d=\"M162.56 414.84v-56.061c0-5.256-4.088-9.344-9.344-9.344H59.781c-5.255 0-9.343 4.088-9.343 9.344v56.061c0 5.256 4.088 9.344 9.343 9.344h93.435c5.256 0 9.344-4.088 9.344-9.344zm0-112.12v-56.061c0-5.256-4.088-9.344-9.344-9.344H59.781c-5.255 0-9.343 4.088-9.343 9.344v56.061c0 5.256 4.088 9.343 9.343 9.343h93.435c5.256 0 9.344-4.087 9.344-9.343zm149.5 112.12v-56.061c0-5.256-4.088-9.344-9.344-9.344h-93.435c-5.255 0-9.343 4.088-9.343 9.344v56.061c0 5.256 4.088 9.344 9.343 9.344h93.435c5.256 0 9.344-4.088 9.344-9.344zm-149.5-224.25v-56.061c0-5.256-4.088-9.344-9.344-9.344H59.781c-5.255 0-9.343 4.088-9.343 9.344v56.061c0 5.256 4.088 9.343 9.343 9.343h93.435c5.256 0 9.344-4.087 9.344-9.343zm149.5 112.12v-56.061c0-5.256-4.088-9.344-9.344-9.344h-93.435c-5.255 0-9.343 4.088-9.343 9.344v56.061c0 5.256 4.088 9.344 9.343 9.344h93.435c5.256 0 9.344-4.088 9.344-9.344zm149.5 112.12v-56.061c0-5.256-4.088-9.344-9.344-9.344h-93.435c-5.255 0-9.343 4.088-9.343 9.344v56.061c0 5.256 4.088 9.344 9.343 9.344h93.435c5.256 0 9.344-4.088 9.344-9.344zm-149.5-224.25v-56.061c0-5.256-4.088-9.344-9.344-9.344h-93.435c-5.255 0-9.343 4.088-9.343 9.344v56.061c0 5.256 4.088 9.343 9.343 9.343h93.435c5.256 0 9.344-4.087 9.344-9.343zm149.5 112.12v-56.061c0-5.256-4.088-9.344-9.344-9.344h-93.435c-5.255 0-9.343 4.088-9.343 9.344V302.7c0 5.256 4.088 9.344 9.343 9.344h93.435c5.256 0 9.344-4.088 9.344-9.344zm0-112.12v-56.061c0-5.256-4.088-9.344-9.344-9.344h-93.435c-5.255 0-9.343 4.088-9.343 9.344v56.061c0 5.256 4.088 9.343 9.343 9.343h93.435c5.256 0 9.344-4.087 9.344-9.343zm37.374-93.436v317.68c0 25.695-21.023 46.718-46.718 46.718H59.786c-25.695 0-46.718-21.023-46.718-46.718V97.144c0-25.695 21.023-46.718 46.718-46.718h392.43c25.695 0 46.718 21.023 46.718 46.718z\"/></svg>`,\n\tTableColumns: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M59.785 50.426c-25.695 0-46.717 21.024-46.717 46.719v317.68c0 25.694 21.022 46.718 46.717 46.718h392.432c25.695 0 46.717-21.024 46.717-46.719V97.144c0-25.694-21.022-46.718-46.717-46.718H59.785zm149.496 74.75h93.436c5.256 0 9.344 4.088 9.344 9.344v280.32c0 5.256-4.088 9.344-9.344 9.344H209.28c-5.255 0-9.344-4.088-9.344-9.344V134.52c0-5.256 4.09-9.344 9.344-9.344zm149.5 0h93.436c5.256 0 9.344 4.088 9.344 9.344v280.31c0 5.256-4.088 9.344-9.344 9.344H358.78c-5.255 0-9.343-4.088-9.343-9.344V134.52c0-5.256 4.088-9.344 9.343-9.344zm-299 .01h93.436c5.256 0 9.344 4.088 9.344 9.344v280.31c0 5.256-4.088 9.344-9.344 9.344H59.78c-5.255 0-9.343-4.088-9.343-9.344V134.53c0-5.256 4.088-9.344 9.343-9.344z\"/></svg>`,\n\tTableSingle: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M59.785 50.426c-25.695 0-46.717 21.024-46.717 46.719v317.68c0 25.694 21.022 46.718 46.717 46.718h392.432c25.695 0 46.717-21.024 46.717-46.719V97.144c0-25.694-21.022-46.718-46.717-46.718zm392.432 74.75c5.256 0 9.344 4.088 9.344 9.344v280.31c0 5.256-4.088 9.344-9.344 9.344l-392.436.01c-5.255 0-9.343-4.088-9.343-9.344V134.53c0-5.257 4.088-9.344 9.343-9.344l392.436-.01z\"/></svg>`,\n\tLanguage: `<svg viewBox=\"0 0 20 20\" height=\"20\" width=\"20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M20 18h-1.44a.61.61 0 0 1-.4-.12.81.81 0 0 1-.23-.31L17 15h-5l-1 2.54a.77.77 0 0 1-.22.3.59.59 0 0 1-.4.14H9l4.55-11.47h1.89zm-3.53-4.31L14.89 9.5a11.62 11.62 0 0 1-.39-1.24q-.09.37-.19.69l-.19.56-1.58 4.19zm-6.3-1.58a13.43 13.43 0 0 1-2.91-1.41 11.46 11.46 0 0 0 2.81-5.37H12V4H7.31a4 4 0 0 0-.2-.56C6.87 2.79 6.6 2 6.6 2l-1.47.5s.4.89.6 1.5H0v1.33h2.15A11.23 11.23 0 0 0 5 10.7a17.19 17.19 0 0 1-5 2.1q.56.82.87 1.38a23.28 23.28 0 0 0 5.22-2.51 15.64 15.64 0 0 0 3.56 1.77zM3.63 5.33h4.91a8.11 8.11 0 0 1-2.45 4.45 9.11 9.11 0 0 1-2.46-4.45z\"/></svg>`,\n\tListAlt: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" height=\"512\" width=\"512\"><path d=\"M116.63 351.81v17.421c0 4.627-4.083 8.71-8.71 8.71H90.499c-4.628 0-8.71-4.083-8.71-8.71V351.81c0-4.627 4.082-8.71 8.71-8.71h17.42c4.628 0 8.711 4.083 8.711 8.71zm0-69.683v17.421c0 4.627-4.083 8.71-8.71 8.71H90.499c-4.628 0-8.71-4.083-8.71-8.71v-17.421c0-4.627 4.082-8.71 8.71-8.71h17.42c4.628 0 8.711 4.083 8.711 8.71zm0-69.683v17.421c0 4.627-4.083 8.71-8.71 8.71H90.499c-4.628 0-8.71-4.083-8.71-8.71v-17.421c0-4.627 4.082-8.71 8.71-8.71h17.42c4.628 0 8.711 4.083 8.711 8.71zm313.57 139.37v17.421c0 4.627-4.083 8.71-8.71 8.71H160.18c-4.628 0-8.71-4.083-8.71-8.71v-17.421c0-4.627 4.082-8.71 8.71-8.71h261.31c4.627 0 8.71 4.083 8.71 8.71zm0-69.683v17.421c0 4.627-4.083 8.71-8.71 8.71H160.18c-4.628 0-8.71-4.083-8.71-8.71v-17.421c0-4.627 4.082-8.71 8.71-8.71h261.31c4.627 0 8.71 4.083 8.71 8.71zm0-69.683v17.421c0 4.627-4.083 8.71-8.71 8.71H160.18c-4.628 0-8.71-4.083-8.71-8.71v-17.421c0-4.627 4.082-8.71 8.71-8.71h261.31c4.627 0 8.71 4.083 8.71 8.71zm34.842 191.63v-226.47c0-4.627-4.083-8.71-8.71-8.71H55.652c-4.628 0-8.71 4.083-8.71 8.71v226.47c0 4.627 4.082 8.71 8.71 8.71h400.68c4.627 0 8.71-4.083 8.71-8.71zm34.842-296.15v296.15c0 23.954-19.598 43.552-43.552 43.552H55.652c-23.954 0-43.552-19.598-43.552-43.552v-296.15c0-23.954 19.598-43.552 43.552-43.552h400.68c23.954 0 43.552 19.598 43.552 43.552z\"/></svg>`,\n\tNotifications: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 464c22.78 0 41.41-18.72 41.41-41.6h-82.82c0 22.88 18.633 41.6 41.412 41.6zm134.59-124.8V224.8c0-63.44-44.517-117.518-103.53-131.04V79.2C287.06 61.518 273.6 48 256 48s-31.06 13.518-31.06 31.2v14.56c-59.014 13.522-103.53 67.6-103.53 131.04v114.4L80 380.8v20.8h352v-20.8l-41.41-41.6z\"/></svg>`,\n\tArrowDropLeft: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M320 128 192 256l128 128z\"/></svg>`,\n\tArrowDropRight: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m192 128 128 128-128 128z\"/></svg>`,\n\tPower: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M279.1 48h-46.2v231.1h46.2V48zm111.6 50.2L357.9 131c36.5 29.4 59.9 74.4 59.9 125 0 89.4-72.3 161.8-161.8 161.8S94.2 345.4 94.2 256c0-50.6 23.3-95.7 59.6-125.3l-32.6-32.6C76.4 136.3 48 192.7 48 256c0 114.9 93.1 208 208 208s208-93.1 208-208c0-63.3-28.4-119.7-73.3-157.8z\"/></svg>`,\n\tPalette: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M430.1 347.9c-6.6-6.1-16.3-7.6-24.6-9-11.5-1.9-15.9-4-22.6-10-14.3-12.7-14.3-31.1 0-43.8l30.3-26.9c46.4-41 46.4-108.2 0-149.2-34.2-30.1-80.1-45-127.8-45-55.7 0-113.9 20.3-158.8 60.1-83.5 73.8-83.5 194.7 0 268.5 41.5 36.7 97.5 55 152.9 55.4h1.7c55.4 0 110-17.9 148.8-52.4 14.4-12.7 12-36.6.1-47.7zM120 216c0-17.7 14.3-32 32-32s32 14.3 32 32-14.3 32-32 32-32-14.3-32-32zm40 126c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm64-161c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm72 219c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm24-208c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z\"/></svg>`,\n\tImport: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M403.002 217C388.998 148.003 328.998 96 256 96c-57.998 0-107.998 32.998-132.998 81C63.002 183.003 16 234 16 296c0 65.996 54 120 120 120h260c55 0 100-45 100-100 0-52.998-40.996-96-92.998-99zM288 276v76h-64v-76h-68l100-100 100 100h-68z\"/></svg>`,\n\tExport: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M403.002 217C388.998 148.003 328.998 96 256 96c-57.998 0-107.998 32.998-132.998 81C63.002 183.003 16 234 16 296c0 65.996 54 120 120 120h260c55 0 100-45 100-100 0-52.998-40.996-96-92.998-99zM224 268v-76h64v76h68L256 368 156 268h68z\"/></svg>`,\n\tPencilSquare: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"m255.03 344.31 29.101-29.101-38.133-38.133-29.101 29.101v14.049h24.084v24.084zm130.45-31.61v47.666c0 39.889-32.363 72.252-72.252 72.252h-208.73c-39.889 0-72.252-32.363-72.252-72.252v-208.73c0-39.889 32.363-72.252 72.252-72.252h208.73c10.035 0 20.07 2.007 29.352 6.272 2.258 1.003 4.014 3.261 4.516 5.77.501 2.76-.251 5.268-2.258 7.275l-12.293 12.293c-2.258 2.258-5.269 3.01-8.028 2.007-3.763-1.003-7.526-1.505-11.29-1.505h-208.73c-22.076 0-40.14 18.063-40.14 40.14v208.73c0 22.077 18.064 40.14 40.14 40.14h208.73c22.078 0 40.14-18.063 40.14-40.14v-31.61c0-2.007.753-4.014 2.259-5.52l16.056-16.055c2.508-2.509 5.77-3.01 8.78-1.756 3.01 1.254 5.018 4.014 5.018 7.275zm-24.084-185.14 72.252 72.252-168.59 168.59h-72.252V296.15zm111.39 33.115-23.08 23.08-72.252-72.252 23.08-23.08c9.282-9.282 24.837-9.282 34.119 0l38.133 38.133c9.282 9.282 9.282 24.837 0 34.119z\"/></svg>`,\n\tTime: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-opacity=\".9\"><path d=\"M255.8 48C141 48 48 141.2 48 256s93 208 207.8 208c115 0 208.2-93.2 208.2-208S370.8 48 255.8 48zm.2 374.4c-91.9 0-166.4-74.5-166.4-166.4S164.1 89.6 256 89.6 422.4 164.1 422.4 256 347.9 422.4 256 422.4z\"/><path d=\"M266.4 152h-31.2v124.8l109.2 65.5 15.6-25.6-93.6-55.5V152z\"/></g></svg>`,\n\tCircleCheckmark: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M340.1 177.3 215.3 303l-47.2-47.2-17.8 17.8 56 56c2.5 2.5 5.9 4.5 8.9 4.5s6.3-2 8.8-4.4l133.7-134.4-17.6-18z\"/><path d=\"M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm0 398.7c-105.1 0-190.7-85.5-190.7-190.7 0-105.1 85.5-190.7 190.7-190.7 105.1 0 190.7 85.5 190.7 190.7 0 105.1-85.6 190.7-190.7 190.7z\"/></svg>`,\n\tCircleReject: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\" id=\"Layer_1\"><style></style><path d=\"M403.1 108.9c-81.2-81.2-212.9-81.2-294.2 0s-81.2 212.9 0 294.2c81.2 81.2 212.9 81.2 294.2 0s81.2-213 0-294.2zm-12.3 281.9c-74.3 74.3-195.3 74.3-269.6 0-74.3-74.3-74.3-195.3 0-269.6s195.3-74.3 269.6 0c74.4 74.3 74.4 195.3 0 269.6z\" class=\"st0\"/><path d=\"m340.2 160-84.4 84.2-84-83.8-11.8 11.8 84 83.8-84 83.8 11.8 11.8 84-83.8 84.4 84.2 11.8-11.8-84.4-84.2 84.4-84.2z\" class=\"st0\"/></svg>`,\n\tCircleHelp: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm0 398.7c-105.1 0-190.7-85.5-190.7-190.7 0-105.1 85.5-190.7 190.7-190.7 105.1 0 190.7 85.5 190.7 190.7 0 105.1-85.6 190.7-190.7 190.7z\"/><path d=\"M259.6 146c-43.2 0-67.3 20.3-67.6 62.2h18.8c-.6-30.4 15.5-46.5 47.9-46.5 23.2 0 42.6 16.2 42.6 39.8 0 15.3-8.3 27.7-19.4 38.1-22.6 20.8-29 36-30.1 64.5h19c1.1-25.8.5-30.7 23.3-53.3 15.2-14.2 25.9-28.3 25.9-50.2 0-34.2-27.4-54.6-60.4-54.6zm.7 186.3c-9.4 0-17 7.5-17 16.8s7.6 16.9 17 16.9 17-7.5 17-16.9c0-9.3-7.6-16.8-17-16.8z\"/></svg>`,\n\tCircleEmpty: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 48C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48zm0 398.7c-105.1 0-190.7-85.5-190.7-190.7 0-105.1 85.5-190.7 190.7-190.7 105.1 0 190.7 85.5 190.7 190.7 0 105.1-85.6 190.7-190.7 190.7z\"/></svg>`,\n\tGift: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" d=\"M346 110a34 34 0 0 0-68 0v34h34a34 34 0 0 0 34-34zm-112 0a34 34 0 1 0-34 34h34z\"/><path d=\"M234 144h44v112h164a22 22 0 0 0 22-22v-68a22 22 0 0 0-22-22h-59.82A77.95 77.95 0 0 0 256 55.79 78 78 0 0 0 129.81 144H70a22 22 0 0 0-22 22v68a22 22 0 0 0 22 22h164zm44-34a34 34 0 1 1 34 34h-34zm-112 0a34 34 0 1 1 68 0v34h-34a34 34 0 0 1-34-34zm112 370h132a22 22 0 0 0 22-22V288H278zM80 458a22 22 0 0 0 22 22h132V288H80z\"/></svg>`,\n\tClipboard: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M405.333 80h-87.35C310.88 52.396 285.82 32 256 32s-54.88 20.396-61.983 48h-87.35C83.197 80 64 99.198 64 122.667v314.665C64 460.802 83.198 480 106.667 480h298.666c23.47 0 42.667-19.2 42.667-42.668V122.667C448 99.197 428.802 80 405.333 80zM256 80c11.73 0 21.333 9.6 21.333 21.333S267.73 122.667 256 122.667s-21.333-9.6-21.333-21.334S244.27 80 256 80zm152 360H104V120h40v72h224v-72h40v320z\"/></svg>`,\n\tQuestionMark: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M289 448h-66v-65h66v65zm-1-98h-64c0-101 96-95.1 96-159 0-35.2-28.8-63.4-64-63.4S192 158 192 192h-64c0-71 57.3-128 128-128s128 56.4 128 127c0 79.9-96 89-96 159z\"/></svg>`,\n\tFormatClear: `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.35 21.8 21.5 18l1.2-2.8h-3.95l-5.2-5.2H40v5H28.25ZM40.3 45.2 22.85 27.7 18.45 38H13l6-14.1L2.8 7.7l2.1-2.1 37.5 37.5Z\"/></svg>`,\n\tAddCheckCirle: `<svg width=\"48\" viewBox=\"0 96 960 960\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m562 817 184-185-42-42-142 142-56-57-43 43 99 99ZM290 696h100v-70H290v70Zm0-130h260v-60H290v60Zm0-120h260v-60H290v60Zm190 530q-82 0-155-31.5t-127.5-86Q143 804 111.5 731T80 576q0-83 31.5-156t86-127Q252 239 325 207.5T480 176q83 0 156 31.5T763 293q54 54 85.5 127T880 576q0 82-31.5 155T763 858.5q-54 54.5-127 86T480 976Zm0-60q142 0 241-99.5T820 576q0-142-99-241t-241-99q-141 0-240.5 99T140 576q0 141 99.5 240.5T480 916Zm0-340Z\"/></svg>`,\n\tReply: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M448 440a16 16 0 0 1-12.61-6.15c-22.86-29.27-44.07-51.86-73.32-67C335 352.88 301 345.59 256 344.23V424a16 16 0 0 1-27 11.57l-176-168a16 16 0 0 1 0-23.14l176-168A16 16 0 0 1 256 88v80.36c74.14 3.41 129.38 30.91 164.35 81.87C449.32 292.44 464 350.9 464 424a16 16 0 0 1-16 16z\"/></svg>`,\n\tInbox: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m479.66 268.7-32-151.81C441.48 83.77 417.68 64 384 64H128c-16.8 0-31 4.69-42.1 13.94s-18.37 22.31-21.58 38.89l-32 151.87A16.65 16.65 0 0 0 32 272v112a64 64 0 0 0 64 64h320a64 64 0 0 0 64-64V272a16.65 16.65 0 0 0-.34-3.3zm-384-145.4v-.28c3.55-18.43 13.81-27 32.29-27H384c18.61 0 28.87 8.55 32.27 26.91 0 .13.05.26.07.39l26.93 127.88a4 4 0 0 1-3.92 4.82H320a15.92 15.92 0 0 0-16 15.82 48 48 0 1 1-96 0A15.92 15.92 0 0 0 192 256H72.65a4 4 0 0 1-3.92-4.82z\"/></svg>`,\n\tArchive: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M64 164v244a56 56 0 0 0 56 56h272a56 56 0 0 0 56-56V164a4 4 0 0 0-4-4H68a4 4 0 0 0-4 4zm267 151.63-63.69 63.68a16 16 0 0 1-22.62 0L181 315.63c-6.09-6.09-6.65-16-.85-22.38a16 16 0 0 1 23.16-.56L240 329.37V224.45c0-8.61 6.62-16 15.23-16.43A16 16 0 0 1 272 224v105.37l36.69-36.68a16 16 0 0 1 23.16.56c5.8 6.37 5.24 16.29-.85 22.38z\"/><rect ry=\"32\" rx=\"32\" height=\"80\" width=\"448\" y=\"48\" x=\"32\"/></svg>`,\n\tDraft: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M368 32H144a64.07 64.07 0 0 0-64 64v320a64.07 64.07 0 0 0 64 64h224a64.07 64.07 0 0 0 64-64V96a64.07 64.07 0 0 0-64-64zM256 304h-80a16 16 0 0 1 0-32h80a16 16 0 0 1 0 32zm80-80H176a16 16 0 0 1 0-32h160a16 16 0 0 1 0 32zm0-80H176a16 16 0 0 1 0-32h160a16 16 0 0 1 0 32z\"/></svg>`,\n\tSend: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M473 39.05a24 24 0 0 0-25.5-5.46L47.47 185h-.08a24 24 0 0 0 1 45.16l.41.13 137.3 58.63a16 16 0 0 0 15.54-3.59L422 80a7.07 7.07 0 0 1 10 10L226.66 310.26a16 16 0 0 0-3.59 15.54l58.65 137.38c.06.2.12.38.19.57 3.2 9.27 11.3 15.81 21.09 16.25h1a24.63 24.63 0 0 0 23-15.46L478.39 64.62A24 24 0 0 0 473 39.05z\"/></svg>`,\n\tFolder: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M408 96H252.11a23.89 23.89 0 0 1-13.31-4L211 73.41A55.77 55.77 0 0 0 179.89 64H104a56.06 56.06 0 0 0-56 56v24h416c0-30.88-25.12-48-56-48zm15.75 352H88.25a56 56 0 0 1-55.93-55.15L16.18 228.11v-.28A48 48 0 0 1 64 176h384.1a48 48 0 0 1 47.8 51.83v.28l-16.22 164.74A56 56 0 0 1 423.75 448zm56.15-221.45z\"/></svg>`,\n\tSpam: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M463.55 272.13H400v-48.2q0-4.32-.27-8.47c29.57-27.88 32.25-64.63 32.27-103 0-8.61-6.64-16-15.25-16.41A16 16 0 0 0 400 112c0 28-1.86 48.15-9.9 63.84-19.22-41.15-65.78-63.91-134.1-63.91-39.8 0-74.19 9.13-99.43 26.39-14.9 10.19-26.2 22.91-33.7 37.72C114 160.65 112 141 112 112.46c0-8.61-6.6-16-15.2-16.44A16 16 0 0 0 80 112c0 37.63 2.61 73.73 32.44 101.63q-.43 5.06-.44 10.3v48.2H48.45c-8.61 0-16 6.62-16.43 15.23a16 16 0 0 0 16 16.77h64V320a143.32 143.32 0 0 0 10.39 53.69C96.74 396.64 80.18 422 80 463.34c0 8.74 6.62 16.3 15.36 16.65A16 16 0 0 0 112 464c0-27.66 9.1-44.71 26.17-61.32A144.37 144.37 0 0 0 220 459.42a16 16 0 0 0 20-15.49V192.45c0-8.61 6.62-16 15.23-16.43A16 16 0 0 1 272 192v251.93a16 16 0 0 0 20 15.49 144.4 144.4 0 0 0 81.82-56.74c17 16.54 26.09 33.52 26.17 60.95a16.27 16.27 0 0 0 15.1 16.37A16 16 0 0 0 432 464c0-41.68-16.6-67.23-42.39-90.31A143.32 143.32 0 0 0 400 320v-15.87h64a16 16 0 0 0 16-16.77c-.42-8.61-7.84-15.23-16.45-15.23z\"/><path d=\"m321.39 104 .32.09c13.57 3.8 25.07-10.55 18.2-22.85A95.86 95.86 0 0 0 256.21 32h-.42a95.87 95.87 0 0 0-84.19 50.13c-6.84 12.58 5.14 27 18.84 22.86 19.71-6 41.79-9.06 65.56-9.06 24.09 0 46.09 2.72 65.39 8.07z\"/></svg>`,\n\tTrashBin: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" d=\"M296 64h-80a7.91 7.91 0 0 0-8 8v24h96V72a7.91 7.91 0 0 0-8-8z\"/><path d=\"M432 96h-96V72a40 40 0 0 0-40-40h-80a40 40 0 0 0-40 40v24H80a16 16 0 0 0 0 32h17l19 304.92c1.42 26.85 22 47.08 48 47.08h184c26.13 0 46.3-19.78 48-47l19-305h17a16 16 0 0 0 0-32zM192.57 416H192a16 16 0 0 1-16-15.43l-8-224a16 16 0 1 1 32-1.14l8 224A16 16 0 0 1 192.57 416zM272 400a16 16 0 0 1-32 0V176a16 16 0 0 1 32 0zm32-304h-96V72a7.91 7.91 0 0 1 8-8h80a7.91 7.91 0 0 1 8 8zm32 304.57A16 16 0 0 1 320 416h-.58A16 16 0 0 1 304 399.43l8-224a16 16 0 1 1 32 1.14z\"/></svg>`,\n\tBulb: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M288 464h-64a16 16 0 0 0 0 32h64a16 16 0 0 0 0-32zm16-48h-96a16 16 0 0 0 0 32h96a16 16 0 0 0 0-32zm65.42-353.31C339.35 32.58 299.07 16 256 16A159.62 159.62 0 0 0 96 176c0 46.62 17.87 90.23 49 119.64l4.36 4.09C167.37 316.57 192 339.64 192 360v24a16 16 0 0 0 16 16h24a8 8 0 0 0 8-8V274.82a8 8 0 0 0-5.13-7.47A130.73 130.73 0 0 1 208.71 253a16 16 0 1 1 18.58-26c7.4 5.24 21.65 13 28.71 13s21.31-7.78 28.73-13a16 16 0 0 1 18.56 26 130.73 130.73 0 0 1-26.16 14.32 8 8 0 0 0-5.13 7.47V392a8 8 0 0 0 8 8h24a16 16 0 0 0 16-16v-24c0-19.88 24.36-42.93 42.15-59.77l4.91-4.66C399.08 265 416 223.61 416 176a159.16 159.16 0 0 0-46.58-113.31z\"/></svg>`,\n\tCreditCard: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M32 376a56 56 0 0 0 56 56h336a56 56 0 0 0 56-56V222H32zm66-76a30 30 0 0 1 30-30h48a30 30 0 0 1 30 30v20a30 30 0 0 1-30 30h-48a30 30 0 0 1-30-30zM424 80H88a56 56 0 0 0-56 56v26h448v-26a56 56 0 0 0-56-56z\"/></svg>`,\n\tWand: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M96 208H48c-8.8 0-16-7.2-16-16s7.2-16 16-16h48c8.8 0 16 7.2 16 16s-7.2 16-16 16zm28.1-67.9c-4.2 0-8.3-1.7-11.3-4.7l-33.9-33.9c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l33.9 33.9c6.3 6.2 6.3 16.4 0 22.6-3 3-7 4.7-11.3 4.7zM192 112c-8.8 0-16-7.2-16-16V48c0-8.8 7.2-16 16-16s16 7.2 16 16v48c0 8.8-7.2 16-16 16zm67.9 28.1c-8.8 0-16-7.2-16-16 0-4.2 1.7-8.3 4.7-11.3l33.9-33.9c6.2-6.2 16.4-6.2 22.6 0 6.2 6.2 6.2 16.4 0 22.6l-33.9 33.9c-3 3-7.1 4.7-11.3 4.7zM90.2 309.8c-8.8 0-16-7.2-16-16 0-4.2 1.7-8.3 4.7-11.3l33.9-33.9c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6l-33.9 33.9c-3 3-7.1 4.7-11.3 4.7zm144-142.8c-18.4-18.7-48.5-19-67.2-.7s-19 48.5-.7 67.2l.7.7 39.5 39.5c3.1 3.1 8.2 3.1 11.3 0l55.9-55.9c3.1-3.1 3.1-8.2 0-11.3L234.2 167zM457 389.8 307.6 240.4c-3.1-3.1-8.2-3.1-11.3 0l-55.9 55.9c-3.1 3.1-3.1 8.2 0 11.3L389.8 457c18.4 18.7 48.5 19 67.2.7 18.7-18.4 19-48.5.7-67.2-.2-.2-.4-.5-.7-.7z\"/></svg>`,\n\tFilter: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M32 144h448M112 256h288M208 368h96\" stroke-width=\"32\" stroke-linejoin=\"round\" stroke-linecap=\"round\" stroke=\"currentColor\" fill=\"none\"/></svg>`,\n\tReplyAll: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path style=\"-inkscape-stroke:none\" fill-opacity=\".986\" color=\"#000\" d=\"M191.85 70.455a18 18 0 0 0-8.176 4.467L7.404 243.032a18 18 0 0 0-.603 25.449 18 18 0 0 0 25.449.603l176.27-168.11a18 18 0 0 0 .603-25.449 18 18 0 0 0-17.27-5.068zM24.06 238.565a18 18 0 0 0-17.271 5.074 18 18 0 0 0 .61 25.45l176.24 167.99a18 18 0 0 0 25.448-.61 18 18 0 0 0-.609-25.45L32.238 243.03a18 18 0 0 0-8.178-4.464zm470.12 201.41a16 16 0 0 1-12.61-6.15c-22.86-29.27-44.07-51.86-73.32-67-27.07-13.97-61.07-21.26-106.07-22.62v79.77a16 16 0 0 1-27 11.57l-176-168a16 16 0 0 1 0-23.14l176-168a16 16 0 0 1 27 11.57v80.36c74.14 3.41 129.38 30.91 164.35 81.87 28.97 42.21 43.65 100.67 43.65 173.77a16 16 0 0 1-16 16z\"/></svg>`,\n\tForward: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"ionicon\"><path d=\"M80.001 168.4c31.312.072 102.64.19 160-.041v-80.36c.001-14.077 16.87-21.292 27.05-11.57l176 168c6.598 6.302 6.598 16.838 0 23.14l-176 168c-10.18 9.721-32.049 2.506-32.05-11.57v-79.77c-62.998-.008-120.66-.002-155 0-8.837 0-16-7.164-16-16V184.36c0-8.836 7.163-15.979 16-15.959z\"/></svg>`,\n} as const)\n\nexport const SecondFactorImage =\n\t\"data:image/png;base64,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\"\nexport const NotificationIcon =\n\t\"data:image/png;base64,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\"\nexport const HabReminderImage =\n\t\"data:image/png;base64,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\"\nexport const VisSignupImage =\n\t\"data:image/png;base64,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\"\nexport const PayPalLogo =\n\t\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAFRWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS41LWMwMTIgMS4xNDk2MDIsIDIwMTIvMTAvMTAtMTg6MTA6MjQgICAgICAgICI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpkYW09Imh0dHA6Ly93d3cuZGF5LmNvbS9kYW0vMS4wIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczpQYXlQYWw9Ind3dy5wYXlwYWwuY29tL2Jhc2UvdjEiCiAgIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIgogICBkYzptb2RpZmllZD0iMjAxNC0wNy0yM1QxMzozNTo1My44LTA3OjAwIgogICBkYW06c2l6ZT0iMTQxNyIKICAgZGFtOlBoeXNpY2Fsd2lkdGhpbmluY2hlcz0iLTEuMCIKICAgZGFtOmV4dHJhY3RlZD0iMjAxNC0wNy0yM1QxMzozNTo1MC4xMDMtMDc6MDAiCiAgIGRhbTpzaGExPSI5YjE2YjMxZDY3ZjYxYmQ5MTdlMjU0Y2I4YzM3YzI1YmZkOTA1ZGUyIgogICBkYW06TnVtYmVyb2Z0ZXh0dWFsY29tbWVudHM9IjAiCiAgIGRhbTpGaWxlZm9ybWF0PSJQTkciCiAgIGRhbTpQcm9ncmVzc2l2ZT0ibm8iCiAgIGRhbTpQaHlzaWNhbGhlaWdodGluZHBpPSItMSIKICAgZGFtOk1JTUV0eXBlPSJpbWFnZS9wbmciCiAgIGRhbTpOdW1iZXJvZmltYWdlcz0i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\"\nexport const ReplacementImage =\n\t'<svg version=\"1.1\" viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\">    <rect width=\"512\" height=\"512\" fill=\"#f8f8f8\"/>    <path d=\"m220 212c0 12.029-9.7597 21.789-21.789 21.789-12.029 0-21.789-9.7597-21.789-21.789s9.7597-21.789 21.789-21.789c12.029 0 21.789 9.7597 21.789 21.789zm116.21 43.578v50.841h-159.79v-21.789l36.315-36.315 18.158 18.158 58.104-58.104zm10.895-79.893h-181.58c-1.9292 0-3.6315 1.7023-3.6315 3.6315v138c0 1.9292 1.7023 3.6315 3.6315 3.6315h181.58c1.9292 0 3.6315-1.7023 3.6315-3.6315v-138c0-1.9292-1.7023-3.6315-3.6315-3.6315zm18.158 3.6315v138c0 9.9867-8.1709 18.158-18.158 18.158h-181.58c-9.9867 0-18.158-8.1709-18.158-18.158v-138c0-9.9867 8.1709-18.158 18.158-18.158h181.58c9.9867 0 18.158 8.1709 18.158 18.158z\"          fill=\"#b4b4b4\" stroke-width=\".11348\"/></svg>'\n","import { assertMainOrNode } from \"../../../api/common/Env\"\n\nassertMainOrNode()\n\nexport const enum BootIcons {\n\tAndroid = \"Android\",\n\tFDroid = \"FDroid\",\n\tApple = \"Apple\",\n\tBack = \"Back\",\n\tCheckbox = \"Checkbox\",\n\tCheckboxSelected = \"CheckboxSelected\",\n\tContacts = \"Contacts\",\n\tExpand = \"Expand\",\n\tHelp = \"Help\",\n\tLogout = \"Logout\",\n\tMoreVertical = \"MoreVertical\",\n\tPremium = \"Premium\",\n\tProgress = \"Progress\",\n\tSearch = \"Search\",\n\tSettings = \"Settings\",\n\tShare = \"Share\",\n\tCalendar = \"Calendar\",\n\tHeart = \"Heart\",\n\tMail = \"Mail\",\n}\n\nexport const BootIconsSvg: Record<BootIcons, string> = Object.freeze({\n\tAndroid: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M144 268.4V358c0 6.9 4.5 14 11.4 14H184v52c0 13.3 10.7 24 24 24s24-10.7 24-24v-52h49v52c0 7.5 3.4 14.2 8.8 18.6 3.9 3.4 9.1 5.4 14.7 5.4h.5c13.3 0 24-10.7 24-24v-52h27.6c7 0 11.4-7.1 11.4-13.9V192H144v76.4zM408 176c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24s24-10.7 24-24v-96c0-13.3-10.7-24-24-24zm-304 0c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24s24-10.7 24-24v-96c0-13.3-10.7-24-24-24z\"/><g><path d=\"m311.2 89.1 18.5-21.9c.4-.5-.2-1.6-1.3-2.5-1.1-.8-2.4-1-2.7-.4l-19.2 22.8c-13.6-5.4-30.2-8.8-50.6-8.8-20.5-.1-37.2 3.2-50.8 8.5l-19-22.4c-.4-.5-1.6-.4-2.7.4s-1.7 1.8-1.3 2.5l18.3 21.6c-48.2 20.9-55.4 72.2-56.4 87.2h223.6c-.9-15.1-8-65.7-56.4-87zm-104.4 49.8c-7.4 0-13.5-6-13.5-13.3 0-7.3 6-13.3 13.5-13.3 7.4 0 13.5 6 13.5 13.3 0 7.3-6 13.3-13.5 13.3zm98.4 0c-7.4 0-13.5-6-13.5-13.3 0-7.3 6-13.3 13.5-13.3 7.4 0 13.5 6 13.5 13.3 0 7.3-6.1 13.3-13.5 13.3z\"/></g></svg>`,\n\tFDroid: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M81.402 73.255c-10.06-.624-13.96 13.19-6.346 19.024a522009.74 522009.74 0 0 0 27.453 35.526c-3.262 15.417-.905 31.532-1.621 47.255.325 13.533-2.84 30.495 10.771 38.942 12.66 7.21 27.859 3.064 41.77 4.171 78.494-.201 156.995.201 235.482-.201 15.67-1.047 24.156-17.337 21.964-31.625-.5-18.825 1.071-37.841-.927-56.53-.183-6.273 7.618-11.187 10.748-16.895 6.367-9.417 15.344-17.437 19.99-27.786 2.464-10.674-13.64-16.624-18.851-7.054l-27.31 35.343c-16.655-2.837-33.854-.725-50.746-1.369-73.51.202-147.026-.2-220.534.202-8.765 4.35-11.363-7.982-16.815-12.697-7.22-8.23-12.522-18.54-21.071-25.346a10.73 10.73 0 0 0-3.957-.926zm95.964 69.458c22.49-1.167 36.44 28.817 21.057 45.268-13.6 17.962-45.512 9.304-48.189-13.056-3.219-16.292 10.515-32.62 27.132-32.212zm159.07 0c22.49-1.167 36.44 28.817 21.058 45.268-13.6 17.962-45.512 9.304-48.189-13.056-3.219-16.292 10.515-32.62 27.132-32.212zM125.362 226.33c-16.083-.563-26.925 15.783-24.473 30.707.082 53.14-.167 106.29.127 159.423 1.047 15.67 17.336 24.155 31.624 21.964 85.423-.201 170.855.202 256.273-.201 15.67-1.046 24.156-17.336 21.964-31.622-.082-52.794.167-105.598-.127-158.383-1.047-15.67-17.337-24.156-31.624-21.962H125.361zm130.52 28.143c50.52-1.911 91.125 53.273 74.425 100.926-13.105 48.8-77.81 71.37-118.413 41.274-42.763-26.942-45.186-95.422-4.436-125.32 13.63-10.873 30.991-16.924 48.423-16.88zm0 26.92c-22.48-.342-43.719 16.164-49.215 37.935h26.209c9.87-20.115 42.902-16.457 48.338 5.11 7.02 19.26-13.568 40.224-32.971 33.353-11.96-4.099-15.538-18.264-29.773-13.99-12.56-2.928-14.18 3.948-6.736 13.887 14.28 26.842 53.683 34.275 76.518 13.983 24.563-18.828 24.564-59.762 0-78.59-9.008-7.492-20.645-11.732-32.37-11.688z\"/></svg>`,\n\tApple: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M333.6 153.9c-33.6 0-47.8 16.5-71.2 16.5-24 0-42.3-16.4-71.4-16.4-28.5 0-58.9 17.9-78.2 48.4-27.1 43-22.5 124 21.4 193 15.7 24.7 36.7 52.4 64.2 52.7h.5c23.9 0 31-16.1 63.9-16.3h.5c32.4 0 38.9 16.2 62.7 16.2h.5c27.5-.3 49.6-31 65.3-55.6 11.3-17.7 15.5-26.6 24.2-46.6-63.5-24.8-73.7-117.4-10.9-152.9-19.2-24.7-46.1-39-71.5-39z\"/><path d=\"M326.2 64c-20 1.4-43.3 14.5-57 31.6-12.4 15.5-22.6 38.5-18.6 60.8h1.6c21.3 0 43.1-13.2 55.8-30.1 12.3-16.1 21.6-38.9 18.2-62.3z\"/></svg>`,\n\tBack: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M352 128.4 319.7 96 160 256l159.7 160 32.3-32.4L224.7 256z\"/></svg>`,\n\tCheckbox: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M216 357c.4 0 .4-.1 0-.2-.4.1-.5.2 0 .2z\"/><path d=\"M432 80v352H80V80h352m16-16H64v384h384V64z\"/></svg>`,\n\tCheckboxSelected: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M216 357c.4 0 .4-.1 0-.2-.4.1-.5.2 0 .2zm124.1-179.7L215.3 303l-47.2-47.2-17.9 17.8 65.1 65 142.3-143.2z\"/><path d=\"M432 80v352H80V80h352m16-16H64v384h384V64z\"/></svg>`,\n\tContacts: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 256c52.805 0 96-43.2 96-96s-43.195-96-96-96-96 43.2-96 96 43.195 96 96 96zm0 48c-63.598 0-192 32.402-192 96v48h384v-48c0-63.598-128.402-96-192-96z\"/></svg>`,\n\tExpand: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m128 192 128 128 128-128z\"/></svg>`,\n\tHelp: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M256 48C141.2 48 48 141.2 48 256s93.2 208 208 208 208-93.2 208-208S370.8 48 256 48zm21 333h-42v-42h42v42zm-.2-63h-41.6c0-67 62.4-62.2 62.4-103.8 0-22.9-18.7-41.7-41.6-41.7S214.4 192 214.4 214h-41.6c0-46 37.2-83 83.2-83s83.2 37.1 83.2 83.1c0 52-62.4 57.9-62.4 103.9z\"/></svg>`,\n\tLogout: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M192 277.4h189.7l-43.6 44.7L368 352l96-96-96-96-31 29.9 44.7 44.7H192v42.8z\"/><path d=\"M255.7 421.3c-44.1 0-85.5-17.2-116.7-48.4-31.2-31.2-48.3-72.7-48.3-116.9 0-44.1 17.2-85.7 48.3-116.9 31.2-31.2 72.6-48.4 116.7-48.4 44 0 85.3 17.1 116.5 48.2l30.3-30.3c-8.5-8.4-17.8-16.2-27.7-23.2C339.7 61 298.6 48 255.7 48 141.2 48 48 141.3 48 256s93.2 208 207.7 208c42.9 0 84-13 119-37.5 10-7 19.2-14.7 27.7-23.2l-30.2-30.2c-31.1 31.1-72.5 48.2-116.5 48.2zm192.304-164.453-.85-.848.85-.85.848.85z\"/></svg>`,\n\tMoreVertical: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M64 384h384v-42.666H64V384zm0-106.666h384v-42.667H64v42.667zM64 128v42.665h384V128H64z\"/></svg>`,\n\tPremium: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M392 105c.9-27 .2-56 .1-57H119.3c0 1-.8 30 .1 57H48c0 68 9.9 102.3 21 126.7S95.4 277 127.7 302c30.1 23.3 95.5 53.6 104.3 57.6v28.3c-4.6 10-23.5 28.2-83.3 28.2H128v48h256v-48h-25.7c-60.7 0-75-19.1-78.3-28.2v-28.3c9.3-4.6 80.9-40.3 104.4-57.5 25.2-18.4 50.9-51.5 58.7-70.3S464 167 464 105h-72zM109.6 211.9c-8.8-18.2-14-37.9-15.7-61.9h28.7c.7 6 1.4 11.3 2.3 16.3 6.6 39.2 14.8 70.2 25.7 96.5-17.3-13.5-31.3-30.8-41-50.9zm292.8 0c-9.9 20.3-24 37.7-41.6 51.3 11-26.2 19-56.8 25.8-96.9.8-5 1.6-10.3 2.3-16.3h29.3c-1.8 24-6.9 43.7-15.8 61.9z\"/></svg>`,\n\tProgress: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m493.4 256-31.8 31.8c9.7-63-9.8-130.2-58.5-178.9-81.2-81.2-213-81.3-294.2 0-16.3 16.3-29.3 34.5-39 54l15.5 7.8c8.9-17.9 20.8-34.7 35.7-49.6 74.3-74.3 195.3-74.3 269.7.1 45.6 45.6 63.2 108.6 52.9 168L409.6 256l-10.8 10.8L452 320l52.7-52.7-11.3-11.3zM390.8 390.8c-74.3 74.3-195.3 74.4-269.7 0C75.6 345.2 58 281.9 68.3 222.9l33.1 33.1 11.3-11.3L60 192 7.3 244.7 18.6 256l31.8-31.8c-9.8 63.4 9.7 130.2 58.4 178.9 81.2 81.2 213 81.2 294.2 0 16.3-16.3 29.3-34.6 39-54l-15.5-7.8c-8.9 17.9-20.8 34.6-35.7 49.5z\"/></svg>`,\n\tSearch: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M344.5 298c15-23.6 23.8-51.6 23.8-81.7 0-84.1-68.1-152.3-152.1-152.3C132.1 64 64 132.2 64 216.3c0 84.1 68.1 152.3 152.1 152.3 30.5 0 58.9-9 82.7-24.4l6.9-4.8L414.3 448l33.7-34.3-108.5-108.6 5-7.1zm-43.1-166.8c22.7 22.7 35.2 52.9 35.2 85s-12.5 62.3-35.2 85c-22.7 22.7-52.9 35.2-85 35.2s-62.3-12.5-85-35.2c-22.7-22.7-35.2-52.9-35.2-85s12.5-62.3 35.2-85c22.7-22.7 52.9-35.2 85-35.2s62.3 12.5 85 35.2z\"/></svg>`,\n\tSettings: `<svg viewBox=\"0 0 512 512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M411.1 256c0-23.9 14.8-42.8 36.9-55.8-4-13.3-9.3-26.2-15.8-38.2-24.9 6.5-45-3.2-62-20.2-16.9-16.9-22.1-37.1-15.6-62-12-6.5-24.8-11.8-38.2-15.8-13 22.2-36.4 36.9-60.4 36.9-23.9 0-47.4-14.7-60.4-36.9-13.4 4-26.2 9.3-38.2 15.8 6.5 24.9 1.3 45-15.6 62-16.9 16.9-37.1 26.7-61.9 20.2-6.6 12-11.9 24.8-15.9 38.2 22.2 13 37 31.9 37 55.8s-14.8 47.4-37 60.4c4 13.4 9.3 26.2 15.8 38.2 24.9-6.5 45-1.3 61.9 15.6 17 16.9 22.1 37.1 15.6 62 12.1 6.5 24.8 11.8 38.2 15.8 13-22.2 36.5-36.9 60.4-36.9s47.4 14.7 60.4 36.9c13.4-4 26.2-9.3 38.2-15.8-6.5-24.9-1.3-45 15.6-62 16.9-16.9 37.1-26.7 62-20.2 6.5-12.1 11.8-24.9 15.8-38.2-22.1-13-36.8-31.9-36.8-55.8zM256 352c-52.9 0-96-43-96-96s43-96 96-96 96 43 96 96-43 96-96 96z\"/></svg>`,\n\tShare: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M383.822 344.427c-16.045 0-31.024 5.326-41.72 15.98l-152.958-88.42c1.07-5.33 2.142-9.594 2.142-14.92 0-5.328-1.07-9.593-2.142-14.92l150.826-87.35c11.762 10.654 26.74 17.042 43.852 17.042 35.295 0 64.178-28.767 64.178-63.92C448 72.766 419.117 44 383.822 44c-35.297 0-64.18 28.767-64.18 63.92 0 5.327 1.066 9.593 2.143 14.92l-150.82 87.35c-11.768-10.655-26.742-17.042-43.857-17.042-35.296 0-63.108 28.766-63.108 63.92 0 35.153 28.877 63.92 64.178 63.92 17.115 0 32.09-6.39 43.856-17.042l151.89 88.42c-1.075 4.256-2.14 8.522-2.14 13.848 0 34.094 27.806 61.787 62.037 61.787 34.23 0 62.037-27.692 62.037-61.786s-27.805-61.787-62.035-61.787z\"/></svg>`,\n\tCalendar: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M368.005 272h-96v96h96v-96zm-32-208v32h-160V64h-48v32h-24.01c-22.002 0-40 17.998-40 40v272c0 22.002 17.998 40 40 40h304.01c22.002 0 40-17.998 40-40V136c0-22.002-17.998-40-40-40h-24V64h-48zm72 344h-304.01V196h304.01v212z\"/></svg>`,\n\tHeart: `<svg viewBox=\"0 0 512 512\" height=\"512\" width=\"512\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m256 448-30.164-27.21C118.718 322.44 48 258.61 48 179.094 48 114.22 97.918 64 162.4 64c36.4 0 70.717 16.742 93.6 43.947C278.882 80.742 313.2 64 349.6 64 414.082 64 464 114.22 464 179.095c0 79.516-70.72 143.348-177.836 241.694L256 448z\"/></svg>`,\n\tMail: `<svg viewBox=\"0 0 512 512\" class=\"ionicon\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M424 80H88a56.06 56.06 0 0 0-56 56v240a56.06 56.06 0 0 0 56 56h336a56.06 56.06 0 0 0 56-56V136a56.06 56.06 0 0 0-56-56zm-14.18 92.63-144 112a16 16 0 0 1-19.64 0l-144-112a16 16 0 1 1 19.64-25.26L256 251.73l134.18-104.36a16 16 0 0 1 19.64 25.26z\"/></svg>`,\n} as const)\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { theme } from \"../theme\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { BootIcons, BootIconsSvg } from \"./icons/BootIcons\"\nimport { Icons } from \"./icons/Icons\"\n\nassertMainOrNode()\n\nexport type AllIcons = BootIcons | Icons\n\nexport type IconAttrs = {\n\ticon: AllIcons\n\tclass?: string\n\tlarge?: boolean\n\tstyle?: Record<string, any>\n\thoverText?: string | null\n\tcontainer?: \"span\" | \"div\" // defaults to \"span\"\n}\n\nexport type lazyIcon = lazy<AllIcons>\n\nlet IconsSvg = {}\n\nimport(\"./icons/Icons.js\").then((IconsModule) => {\n\tIconsSvg = IconsModule.IconsSvg\n})\n\nexport class Icon implements Component<IconAttrs> {\n\tview(vnode: Vnode<IconAttrs>): Children {\n\t\t// @ts-ignore\n\t\tconst icon = BootIconsSvg[vnode.attrs.icon] ?? IconsSvg[vnode.attrs.icon]\n\t\tconst containerClasses = this.getContainerClasses(vnode.attrs)\n\n\t\treturn m(\n\t\t\tcontainerClasses,\n\t\t\t{\n\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\tclass: this.getClass(vnode.attrs),\n\t\t\t\tstyle: this.getStyle(vnode.attrs.style ?? null),\n\t\t\t},\n\t\t\tm.trust(icon),\n\t\t\tvnode.attrs.hoverText ? m(\"span.tooltiptext.no-wrap\", vnode.attrs.hoverText) : null,\n\t\t) // icon is typed, so we may not embed untrusted data\n\t}\n\n\tgetStyle(style: Record<string, any> | null): {\n\t\tfill: string\n\t} {\n\t\tstyle = style ? style : {}\n\n\t\tif (!style.fill) {\n\t\t\tstyle.fill = theme.content_accent\n\t\t}\n\n\t\treturn style as { fill: string }\n\t}\n\n\tgetClass(attrs: IconAttrs): string {\n\t\tlet cls = \"\"\n\t\tif (attrs.large) {\n\t\t\tcls += \"icon-large \"\n\t\t}\n\t\tif (attrs.class) {\n\t\t\tcls += attrs.class\n\t\t}\n\t\treturn cls\n\t}\n\n\tgetContainerClasses(attrs: IconAttrs): string {\n\t\tconst container = attrs.container || \"span\"\n\t\tlet classes = container + \".icon\"\n\t\tif (attrs.hoverText) {\n\t\t\tclasses += \".tooltip\"\n\t\t}\n\t\treturn classes\n\t}\n}\n\nexport function progressIcon(): Vnode<IconAttrs> {\n\treturn m(Icon, {\n\t\ticon: BootIcons.Progress,\n\t\tclass: \"icon-large icon-progress\",\n\t})\n}\n","import m, { Children, ClassComponent, CVnode } from \"mithril\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport { addFlash, removeFlash } from \"./Flash\"\nimport type { lazyIcon } from \"./Icon\"\nimport { Icon } from \"./Icon\"\nimport { getContentButtonIconBackground, getElevatedBackground, getNavButtonIconBackground, getNavigationMenuIcon, theme } from \"../theme\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { assertNotNull } from \"@tutao/tutanota-utils\"\nimport type { clickHandler } from \"./GuiUtils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { px, size } from \"../size.js\"\n\nassertMainOrNode()\n\nexport const enum ButtonType {\n\tAction = \"action\",\n\tActionLarge = \"action-large\",\n\t// action button with large icon\n\tPrimary = \"primary\",\n\tSecondary = \"secondary\",\n\tLogin = \"login\",\n\tBubble = \"bubble\",\n\tTextBubble = \"textBubble\",\n\tFolderColumnHeader = \"folderColumnHeader\",\n}\n\nexport const enum ButtonColor {\n\tHeader = \"header\",\n\tNav = \"nav\",\n\tContent = \"content\",\n\tElevated = \"elevated\",\n\tDrawerNav = \"drawernav\",\n}\n\nexport function getColors(buttonColors: ButtonColor | null | undefined): {\n\tborder: string\n\tbutton: string\n\tbutton_icon_bg: string\n\tbutton_selected: string\n\ticon: string\n\ticon_selected: string\n} {\n\tswitch (buttonColors) {\n\t\tcase ButtonColor.Nav:\n\t\t\treturn {\n\t\t\t\tbutton: theme.navigation_button,\n\t\t\t\tbutton_selected: theme.navigation_button_selected,\n\t\t\t\tbutton_icon_bg: getNavButtonIconBackground(),\n\t\t\t\ticon: theme.navigation_button_icon,\n\t\t\t\ticon_selected: theme.navigation_button_icon_selected,\n\t\t\t\tborder: theme.navigation_bg,\n\t\t\t}\n\n\t\tcase ButtonColor.DrawerNav:\n\t\t\treturn {\n\t\t\t\tbutton: theme.content_button,\n\t\t\t\tbutton_selected: theme.content_button_selected,\n\t\t\t\tbutton_icon_bg: \"transparent\",\n\t\t\t\ticon: getNavigationMenuIcon(),\n\t\t\t\ticon_selected: theme.content_button_icon_selected,\n\t\t\t\tborder: getElevatedBackground(),\n\t\t\t}\n\n\t\tcase ButtonColor.Elevated:\n\t\t\treturn {\n\t\t\t\tbutton: theme.content_button,\n\t\t\t\tbutton_selected: theme.content_button_selected,\n\t\t\t\tbutton_icon_bg: getContentButtonIconBackground(),\n\t\t\t\ticon: theme.content_button_icon,\n\t\t\t\ticon_selected: theme.content_button_icon_selected,\n\t\t\t\tborder: getElevatedBackground(),\n\t\t\t}\n\n\t\tcase ButtonColor.Header:\n\t\t\treturn {\n\t\t\t\tbutton: theme.content_button,\n\t\t\t\tbutton_selected: theme.content_button_selected,\n\t\t\t\tbutton_icon_bg: \"transparent\",\n\t\t\t\ticon: theme.header_button_selected,\n\t\t\t\ticon_selected: theme.content_button_icon_selected,\n\t\t\t\tborder: theme.content_bg,\n\t\t\t}\n\n\t\tcase ButtonColor.Content:\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tbutton: theme.content_button,\n\t\t\t\tbutton_selected: theme.content_button_selected,\n\t\t\t\tbutton_icon_bg: getContentButtonIconBackground(),\n\t\t\t\ticon: theme.content_button_icon,\n\t\t\t\ticon_selected: theme.content_button_icon_selected,\n\t\t\t\tborder: theme.content_bg,\n\t\t\t}\n\t}\n}\n\nexport interface ButtonAttrs {\n\tlabel: TranslationKey | lazy<string>\n\ttitle?: TranslationKey | lazy<string>\n\tclick?: clickHandler\n\ticon?: lazyIcon | null\n\ttype?: ButtonType\n\tcolors?: ButtonColor\n\tisSelected?: lazy<boolean>\n\tnoBubble?: boolean\n\tstaticRightText?: string\n}\n\n/**\n * A button.\n */\nexport class Button implements ClassComponent<ButtonAttrs> {\n\tprivate _domButton: HTMLElement | null = null\n\n\tview(vnode: CVnode<ButtonAttrs>): Children {\n\t\tconst a = vnode.attrs\n\t\tconst type = this.getType(a.type)\n\t\tconst title = a.title !== undefined ? this.getTitle(a.title) : lang.getMaybeLazy(a.label)\n\t\treturn m(\n\t\t\t\"button.limit-width.noselect\",\n\t\t\t{\n\t\t\t\tclass: this.getButtonClasses(a).join(\" \"),\n\t\t\t\tstyle: this._getStyle(a),\n\t\t\t\tonclick: (event: MouseEvent) => this.click(event, a, assertNotNull(this._domButton)),\n\t\t\t\ttitle: type === ButtonType.Action || type === ButtonType.Login ? lang.getMaybeLazy(a.label) : title,\n\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\tthis._domButton = vnode.dom as HTMLButtonElement\n\t\t\t\t},\n\t\t\t\tonremove: (vnode) => removeFlash(vnode.dom),\n\t\t\t},\n\t\t\tm(\n\t\t\t\t\"\",\n\t\t\t\t{\n\t\t\t\t\t// additional wrapper for flex box styling as safari does not support flex box on buttons.\n\t\t\t\t\tclass: this.getWrapperClasses(a).join(\" \"),\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tborderColor: getColors(a.colors).border,\n\t\t\t\t\t},\n\t\t\t\t\toncreate: (vnode) => addFlash(vnode.dom),\n\t\t\t\t\tonremove: (vnode) => removeFlash(vnode.dom),\n\t\t\t\t},\n\t\t\t\t[\n\t\t\t\t\tthis.getIcon(a),\n\t\t\t\t\tthis._getLabelElement(a),\n\t\t\t\t\ta.staticRightText\n\t\t\t\t\t\t? m(\n\t\t\t\t\t\t\t\t\"span\",\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tstyle: this._getLabelStyle(a),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ta.staticRightText,\n\t\t\t\t\t\t  )\n\t\t\t\t\t\t: null,\n\t\t\t\t],\n\t\t\t),\n\t\t)\n\t}\n\n\t_getStyle(a: ButtonAttrs): {} {\n\t\treturn a.type === ButtonType.Login\n\t\t\t? {\n\t\t\t\t\t\"border-radius\": px(size.border_radius),\n\t\t\t\t\t\"background-color\": theme.content_accent,\n\t\t\t  }\n\t\t\t: {}\n\t}\n\n\tgetTitle(title: TranslationKey | lazy<string>): string {\n\t\treturn lang.getMaybeLazy(title)\n\t}\n\n\tgetType(type: ButtonType | null | undefined): ButtonType {\n\t\treturn type ? type : ButtonType.Action\n\t}\n\n\tgetIcon(a: ButtonAttrs): Children {\n\t\tconst icon = a.icon?.()\n\t\treturn icon\n\t\t\t? m(Icon, {\n\t\t\t\t\ticon,\n\t\t\t\t\tclass: this.getIconClass(a),\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tfill: this.getIconColor(a),\n\t\t\t\t\t\t\"background-color\": this.getIconBackgroundColor(a),\n\t\t\t\t\t},\n\t\t\t  })\n\t\t\t: null\n\t}\n\n\tgetIconColor(a: ButtonAttrs): string {\n\t\tconst type = this.getType(a.type)\n\n\t\tif (type === ButtonType.Bubble) {\n\t\t\treturn theme.button_bubble_fg\n\t\t} else if (type === ButtonType.Login) {\n\t\t\treturn theme.content_button_icon_selected\n\t\t} else if (a.isSelected?.()) {\n\t\t\treturn getColors(a.colors).icon_selected\n\t\t} else {\n\t\t\treturn getColors(a.colors).icon\n\t\t}\n\t}\n\n\tgetIconBackgroundColor(a: ButtonAttrs): string {\n\t\tconst type = this.getType(a.type)\n\n\t\tif ([ButtonType.Bubble, ButtonType.Login].includes(type)) {\n\t\t\treturn \"initial\"\n\t\t} else if (a.isSelected?.()) {\n\t\t\treturn getColors(a.colors).button_selected\n\t\t} else if (type === ButtonType.Action || type === ButtonType.ActionLarge) {\n\t\t\treturn getColors(a.colors).button_icon_bg\n\t\t} else {\n\t\t\treturn getColors(a.colors).button\n\t\t}\n\t}\n\n\tgetIconClass(a: ButtonAttrs): string {\n\t\tconst type = this.getType(a.type)\n\n\t\tif (type === ButtonType.Login) {\n\t\t\treturn \"flex-center items-center button-icon icon-xl pr-s\"\n\t\t}\n\n\t\tif (type === ButtonType.ActionLarge) {\n\t\t\treturn \"flex-center items-center button-icon icon-large\"\n\t\t} else if (a.colors === ButtonColor.Header) {\n\t\t\treturn \"flex-end items-center button-icon icon-xl\"\n\t\t} else if (a.colors === ButtonColor.DrawerNav) {\n\t\t\treturn \"flex-end items-end button-icon\"\n\t\t} else if (type === ButtonType.Bubble) {\n\t\t\treturn \"pr-s\"\n\t\t} else {\n\t\t\treturn \"flex-center items-center button-icon\"\n\t\t}\n\t}\n\n\tgetButtonClasses(a: ButtonAttrs): Array<string> {\n\t\tconst type = this.getType(a.type)\n\t\tlet buttonClasses = [\"bg-transparent\"]\n\n\t\tif ([ButtonType.Action, ButtonType.ActionLarge].includes(type)) {\n\t\t\tbuttonClasses.push(\"button-width-fixed\") // set the button width for firefox browser\n\n\t\t\tbuttonClasses.push(\"button-height\") // set the button height for firefox browser\n\t\t} else {\n\t\t\tbuttonClasses.push(\"button-height\") // set the button height for firefox browser\n\t\t}\n\n\t\tif (type === ButtonType.Login) {\n\t\t\tbuttonClasses.push(\"full-width\")\n\t\t}\n\n\t\treturn buttonClasses\n\t}\n\n\tgetWrapperClasses(a: ButtonAttrs): Array<string> {\n\t\tconst type = this.getType(a.type)\n\t\tlet wrapperClasses = [\"button-content\", \"flex\", \"items-center\", type]\n\n\t\tif (![ButtonType.TextBubble].includes(type)) {\n\t\t\twrapperClasses.push(\"plr-button\")\n\t\t}\n\n\t\tif (ButtonType.Bubble === type) {\n\t\t\twrapperClasses.push(\"smaller\")\n\t\t}\n\n\t\twrapperClasses.push(\"justify-center\")\n\n\t\treturn wrapperClasses\n\t}\n\n\t_getLabelElement(a: ButtonAttrs): Children {\n\t\tconst type = this.getType(a.type)\n\t\tconst label = lang.getMaybeLazy(a.label)\n\n\t\tif (label.trim() === \"\" || [ButtonType.Action].includes(type)) {\n\t\t\treturn null\n\t\t}\n\n\t\tlet classes = [\"text-ellipsis\"]\n\n\t\treturn m(\n\t\t\t\"\",\n\t\t\t{\n\t\t\t\tclass: classes.join(\" \"),\n\t\t\t\tstyle: this._getLabelStyle(a),\n\t\t\t},\n\t\t\tlabel,\n\t\t)\n\t}\n\n\t_getLabelStyle(a: ButtonAttrs): {} {\n\t\tconst type = this.getType(a.type)\n\t\tlet color\n\n\t\tswitch (type) {\n\t\t\tcase ButtonType.Primary:\n\t\t\tcase ButtonType.Secondary:\n\t\t\t\tcolor = theme.content_accent\n\t\t\t\tbreak\n\n\t\t\tcase ButtonType.Login:\n\t\t\t\tcolor = theme.content_button_icon_selected\n\t\t\t\tbreak\n\n\t\t\tcase ButtonType.Bubble:\n\t\t\tcase ButtonType.TextBubble:\n\t\t\t\tcolor = theme.content_fg\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\tcolor = a.isSelected?.() ? getColors(a.colors).button_selected : getColors(a.colors).button\n\t\t}\n\n\t\treturn {\n\t\t\tcolor,\n\t\t\t\"font-weight\": type === ButtonType.Primary ? \"bold\" : \"normal\",\n\t\t}\n\t}\n\n\tclick(event: MouseEvent, a: ButtonAttrs, dom: HTMLElement) {\n\t\ta.click?.(event, dom)\n\n\t\tif (a.noBubble) {\n\t\t\tevent.stopPropagation()\n\t\t}\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { ButtonAttrs } from \"./Button.js\"\nimport { Button } from \"./Button.js\"\nimport type { lazy, MaybeLazy } from \"@tutao/tutanota-utils\"\nimport { resolveMaybeLazy } from \"@tutao/tutanota-utils\"\n\nexport type DialogHeaderBarAttrs = {\n\tleft?: MaybeLazy<Array<ButtonAttrs>>\n\tright?: MaybeLazy<Array<ButtonAttrs>>\n\tmiddle?: lazy<string>\n\tcreate?: (dom: HTMLElement) => void\n\tremove?: () => void\n\tnoHeader?: boolean\n}\n\n/**\n * An action bar is a bar that contains buttons (either on the left or on the right).\n */\nexport class DialogHeaderBar implements Component<DialogHeaderBarAttrs> {\n\tview(vnode: Vnode<DialogHeaderBarAttrs>): Children {\n\t\tconst a = Object.assign(\n\t\t\t{},\n\t\t\t{\n\t\t\t\tleft: [],\n\t\t\t\tright: [],\n\t\t\t},\n\t\t\tvnode.attrs,\n\t\t)\n\t\tlet columnClass = a.middle ? \".flex-third.overflow-hidden\" : \".flex-half.overflow-hidden\"\n\t\treturn m(\n\t\t\t\".flex-space-between.dialog-header-line-height\",\n\t\t\t{\n\t\t\t\toncreate: ({ dom }) => {\n\t\t\t\t\tif (a.create) a.create(dom as HTMLElement)\n\t\t\t\t},\n\t\t\t\tonremove: () => {\n\t\t\t\t\tif (a.remove) a.remove()\n\t\t\t\t},\n\t\t\t},\n\t\t\t[\n\t\t\t\tm(\n\t\t\t\t\tcolumnClass + \".ml-negative-s\",\n\t\t\t\t\tresolveMaybeLazy(a.left).map((a) => m(Button, a)),\n\t\t\t\t), // ellipsis is not working if the text is directly in the flex element, so create a child div for it\n\t\t\t\ta.middle ? m(\"#dialog-title.flex-third-middle.overflow-hidden.flex.justify-center.items-center.b\", [m(\".text-ellipsis\", a.middle())]) : null,\n\t\t\t\tm(\n\t\t\t\t\tcolumnClass + \".mr-negative-s.flex.justify-end\",\n\t\t\t\t\tresolveMaybeLazy(a.right).map((a) => m(Button, a)),\n\t\t\t\t),\n\t\t\t],\n\t\t)\n\t}\n}\n","import m, { Children, ClassComponent, CVnode } from \"mithril\"\nimport { px, size } from \"../size\"\nimport { DefaultAnimationTime } from \"../animation/Animations\"\nimport { theme } from \"../theme\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport type { keyHandler } from \"../../misc/KeyManager\"\nimport { TabIndex } from \"../../api/common/TutanotaConstants\"\nimport type { clickHandler } from \"./GuiUtils\"\n\nexport type TextFieldAttrs = {\n\tid?: string\n\tlabel: TranslationKey | lazy<string>\n\tvalue: string\n\tautocompleteAs?: Autocomplete\n\ttype?: TextFieldType\n\thelpLabel?: lazy<Children> | null\n\talignRight?: boolean\n\tinjectionsLeft?: lazy<Children>\n\t// only used by the BubbleTextField (-> uses old TextField) to display bubbles and out of office notification\n\tinjectionsRight?: lazy<Children>\n\tkeyHandler?: keyHandler\n\tonDomInputCreated?: (dom: HTMLInputElement) => void\n\t// interceptor used by the BubbleTextField to react on certain keys\n\tonfocus?: (dom: HTMLElement, input: HTMLInputElement) => unknown\n\tonblur?: (...args: Array<any>) => any\n\tmaxWidth?: number\n\tclass?: string\n\tdisabled?: boolean\n\toninput?: (value: string, input: HTMLInputElement) => unknown\n\tonclick?: clickHandler\n\tdoShowBorder?: boolean | null\n\tfontSize?: string\n}\n\nexport const enum TextFieldType {\n\tText = \"text\",\n\tEmail = \"email\",\n\tPassword = \"password\",\n\tArea = \"area\",\n\tNumber = \"number\",\n\tTime = \"time\",\n}\n\n// relevant subset of possible values for the autocomplete html field\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete\nexport const enum Autocomplete {\n\toff = \"off\",\n\temail = \"email\",\n\tusername = \"username\",\n\tnewPassword = \"new-password\",\n\tcurrentPassword = \"current-password\",\n\toneTimeCode = \"one-time-code\",\n\tccNumber = \"cc-number\",\n\tccCsc = \"cc-csc\",\n\tccExp = \"cc-exp\",\n}\n\nexport const inputLineHeight: number = size.font_size_base + 8\nconst inputMarginTop = size.font_size_small + size.hpad_small + 3\n\n// this is not always correct because font size can be biggger/smaller and we ideally should take that into account\nconst baseLabelPosition = 21\n// it should fit\n// compact button + 1 px border + 1 px padding to keep things centered = 32\n// 24px line-height + 12px label + some space between them = 36 + ?\nconst minInputHeight = 46\n\nexport class TextField implements ClassComponent<TextFieldAttrs> {\n\tactive: boolean\n\tonblur: EventListener | null = null\n\tdomInput!: HTMLInputElement\n\t_domWrapper!: HTMLElement\n\tprivate _domLabel!: HTMLElement\n\tprivate _domInputWrapper!: HTMLElement\n\tprivate _didAutofill!: boolean\n\n\tconstructor() {\n\t\tthis.active = false\n\t}\n\n\tview(vnode: CVnode<TextFieldAttrs>): Children {\n\t\tconst a = vnode.attrs\n\t\tconst maxWidth = a.maxWidth\n\t\tconst labelBase = !this.active && a.value === \"\" && !a.disabled && !this._didAutofill && !a.injectionsLeft\n\t\tconst labelTransitionSpeed = DefaultAnimationTime / 2\n\t\tconst doShowBorder = a.doShowBorder !== false\n\t\tconst borderWidth = this.active ? \"2px\" : \"1px\"\n\t\tconst borderColor = this.active ? theme.content_accent : theme.content_border\n\t\treturn m(\n\t\t\t\".text-field.rel.overflow-hidden\",\n\t\t\t{\n\t\t\t\tid: vnode.attrs.id,\n\t\t\t\toncreate: (vnode) => (this._domWrapper = vnode.dom as HTMLElement),\n\t\t\t\tonclick: (e: MouseEvent) => (a.onclick ? a.onclick(e, this._domInputWrapper) : this.focus(e, a)),\n\t\t\t\tclass: a.class != null ? a.class : \"text pt\",\n\t\t\t\tstyle: maxWidth\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tmaxWidth: px(maxWidth),\n\t\t\t\t\t  }\n\t\t\t\t\t: {},\n\t\t\t},\n\t\t\t[\n\t\t\t\tm(\n\t\t\t\t\t\"label.abs.text-ellipsis.noselect.z1.i.pr-s.text\",\n\t\t\t\t\t{\n\t\t\t\t\t\tclass: this.active ? \"content-accent-fg\" : \"\",\n\t\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\t\tthis._domLabel = vnode.dom as HTMLElement\n\t\t\t\t\t\t},\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tfontSize: `${labelBase ? size.font_size_base : size.font_size_small}px`,\n\t\t\t\t\t\t\ttransform: `translateY(${labelBase ? baseLabelPosition : 0}px)`,\n\t\t\t\t\t\t\ttransition: `transform ${labelTransitionSpeed}ms ease-out, font-size ${labelTransitionSpeed}ms  ease-out`,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tlang.getMaybeLazy(a.label),\n\t\t\t\t),\n\t\t\t\tm(\".flex.flex-column\", [\n\t\t\t\t\t// another wrapper to fix IE 11 min-height bug https://github.com/philipwalton/flexbugs#3-min-height-on-a-flex-container-wont-apply-to-its-flex-items\n\t\t\t\t\tm(\n\t\t\t\t\t\t\".flex.items-end.flex-wrap\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// .flex-wrap\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\"min-height\": px(minInputHeight),\n\t\t\t\t\t\t\t\t// 2 px border\n\t\t\t\t\t\t\t\t\"padding-bottom\": this.active ? px(0) : px(1),\n\t\t\t\t\t\t\t\t\"border-bottom\": doShowBorder ? `${borderWidth} solid ${borderColor}` : \"\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\ta.injectionsLeft ? a.injectionsLeft() : null, // additional wrapper element for bubble input field. input field should always be in one line with right injections\n\t\t\t\t\t\t\tm(\n\t\t\t\t\t\t\t\t\".inputWrapper.flex-space-between.items-end\",\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\tminHeight: px(minInputHeight - 2), // minus padding\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\toncreate: (vnode) => (this._domInputWrapper = vnode.dom as HTMLElement),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\ta.type !== TextFieldType.Area ? this._getInputField(a) : this._getTextArea(a),\n\t\t\t\t\t\t\t\t\ta.injectionsRight\n\t\t\t\t\t\t\t\t\t\t? m(\n\t\t\t\t\t\t\t\t\t\t\t\t\".flex-end.items-center\",\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tstyle: { minHeight: px(minInputHeight - 2) },\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\ta.injectionsRight(),\n\t\t\t\t\t\t\t\t\t\t  )\n\t\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t\t],\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]),\n\t\t\t\ta.helpLabel\n\t\t\t\t\t? m(\n\t\t\t\t\t\t\t\"small.noselect\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tonclick: (e: MouseEvent) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ta.helpLabel(),\n\t\t\t\t\t  )\n\t\t\t\t\t: [],\n\t\t\t],\n\t\t)\n\t}\n\n\t_getInputField(a: TextFieldAttrs): Children {\n\t\tif (a.disabled) {\n\t\t\treturn m(\n\t\t\t\t\".text-break.selectable\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tmarginTop: px(inputMarginTop),\n\t\t\t\t\t\tlineHeight: px(inputLineHeight),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ta.value,\n\t\t\t)\n\t\t} else {\n\t\t\t// Due to modern browser's 'smart' password managers that try to autofill everything\n\t\t\t// that remotely resembles a password field, we prepend invisible inputs to password fields\n\t\t\t// that shouldn't be autofilled.\n\t\t\t// since the autofill algorithm looks at inputs that come before and after the password field we need\n\t\t\t// three dummies.\n\t\t\tconst autofillGuard: Children =\n\t\t\t\ta.autocompleteAs === Autocomplete.off\n\t\t\t\t\t? [\n\t\t\t\t\t\t\tm(\"input.abs\", {\n\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\topacity: \"0\",\n\t\t\t\t\t\t\t\t\theight: \"0\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttabIndex: TabIndex.Programmatic,\n\t\t\t\t\t\t\t\ttype: TextFieldType.Text,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tm(\"input.abs\", {\n\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\topacity: \"0\",\n\t\t\t\t\t\t\t\t\theight: \"0\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttabIndex: TabIndex.Programmatic,\n\t\t\t\t\t\t\t\ttype: TextFieldType.Password,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tm(\"input.abs\", {\n\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\topacity: \"0\",\n\t\t\t\t\t\t\t\t\theight: \"0\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttabIndex: TabIndex.Programmatic,\n\t\t\t\t\t\t\t\ttype: TextFieldType.Text,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t  ]\n\t\t\t\t\t: []\n\t\t\treturn m(\n\t\t\t\t\".flex-grow.rel\",\n\t\t\t\tautofillGuard.concat([\n\t\t\t\t\tm(\"input.input\" + (a.alignRight ? \".right\" : \"\"), {\n\t\t\t\t\t\tautocomplete: a.autocompleteAs ?? \"\",\n\t\t\t\t\t\ttype: a.type,\n\t\t\t\t\t\t\"aria-label\": lang.getMaybeLazy(a.label),\n\t\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\t\tthis.domInput = vnode.dom as HTMLInputElement\n\t\t\t\t\t\t\ta.onDomInputCreated?.(this.domInput)\n\t\t\t\t\t\t\tthis.domInput.value = a.value\n\t\t\t\t\t\t\tif (a.type !== TextFieldType.Area) {\n\t\t\t\t\t\t\t\t;(vnode.dom as HTMLElement).addEventListener(\"animationstart\", (e: AnimationEvent) => {\n\t\t\t\t\t\t\t\t\tif (e.animationName === \"onAutoFillStart\") {\n\t\t\t\t\t\t\t\t\t\tthis._didAutofill = true\n\t\t\t\t\t\t\t\t\t\tm.redraw()\n\t\t\t\t\t\t\t\t\t} else if (e.animationName === \"onAutoFillCancel\") {\n\t\t\t\t\t\t\t\t\t\tthis._didAutofill = false\n\t\t\t\t\t\t\t\t\t\tm.redraw()\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonfocus: (e: FocusEvent) => {\n\t\t\t\t\t\t\tthis.focus(e, a)\n\t\t\t\t\t\t\ta.onfocus && a.onfocus(this._domWrapper, this.domInput)\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonblur: (e: FocusEvent) => this.blur(e, a),\n\t\t\t\t\t\tonkeydown: (e: KeyboardEvent) => {\n\t\t\t\t\t\t\t// keydown is used to cancel certain keypresses of the user (mainly needed for the BubbleTextField)\n\t\t\t\t\t\t\tlet key = {\n\t\t\t\t\t\t\t\tkeyCode: e.which,\n\t\t\t\t\t\t\t\tkey: e.key,\n\t\t\t\t\t\t\t\tctrl: e.ctrlKey,\n\t\t\t\t\t\t\t\tshift: e.shiftKey,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn a.keyHandler != null ? a.keyHandler(key) : true\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonupdate: () => {\n\t\t\t\t\t\t\t// only change the value if the value has changed otherwise the cursor in Safari and in the iOS App cannot be positioned.\n\t\t\t\t\t\t\tif (this.domInput.value !== a.value) {\n\t\t\t\t\t\t\t\tthis.domInput.value = a.value\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\toninput: () => {\n\t\t\t\t\t\t\ta.oninput && a.oninput(this.domInput.value, this.domInput)\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonremove: () => {\n\t\t\t\t\t\t\t// We clean up any value that might still be in DOM e.g. password\n\t\t\t\t\t\t\tif (this.domInput) this.domInput.value = \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tmaxWidth: a.maxWidth,\n\t\t\t\t\t\t\tminWidth: px(20),\n\t\t\t\t\t\t\t// fix for edge browser. buttons are cut off in small windows otherwise\n\t\t\t\t\t\t\tlineHeight: px(inputLineHeight),\n\t\t\t\t\t\t\tfontSize: a.fontSize,\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\t}\n\n\t_getTextArea(a: TextFieldAttrs): Children {\n\t\tif (a.disabled) {\n\t\t\treturn m(\n\t\t\t\t\".text-prewrap.text-break.selectable\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tmarginTop: px(inputMarginTop),\n\t\t\t\t\t\tlineHeight: px(inputLineHeight),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ta.value,\n\t\t\t)\n\t\t} else {\n\t\t\treturn m(\"textarea.input-area.text-pre\", {\n\t\t\t\t\"aria-label\": lang.getMaybeLazy(a.label),\n\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\tthis.domInput = vnode.dom as HTMLInputElement\n\t\t\t\t\tthis.domInput.value = a.value\n\t\t\t\t\tthis.domInput.style.height = px(Math.max(a.value.split(\"\\n\").length, 1) * inputLineHeight) // display all lines on creation of text area\n\t\t\t\t},\n\t\t\t\tonfocus: (e: FocusEvent) => this.focus(e, a),\n\t\t\t\tonblur: (e: FocusEvent) => this.blur(e, a),\n\t\t\t\tonkeydown: (e: KeyboardEvent) => {\n\t\t\t\t\tlet key = {\n\t\t\t\t\t\tkeyCode: e.which,\n\t\t\t\t\t\tkey: e.key,\n\t\t\t\t\t\tctrl: e.ctrlKey,\n\t\t\t\t\t\tshift: e.shiftKey,\n\t\t\t\t\t}\n\t\t\t\t\treturn a.keyHandler != null ? a.keyHandler(key) : true\n\t\t\t\t},\n\t\t\t\toninput: () => {\n\t\t\t\t\tthis.domInput.style.height = \"0px\"\n\t\t\t\t\tthis.domInput.style.height = px(this.domInput.scrollHeight)\n\t\t\t\t\ta.oninput && a.oninput(this.domInput.value, this.domInput)\n\t\t\t\t},\n\t\t\t\tonupdate: () => {\n\t\t\t\t\t// only change the value if the value has changed otherwise the cursor in Safari and in the iOS App cannot be positioned.\n\t\t\t\t\tif (this.domInput.value !== a.value) {\n\t\t\t\t\t\tthis.domInput.value = a.value\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tstyle: {\n\t\t\t\t\tmarginTop: px(inputMarginTop),\n\t\t\t\t\tlineHeight: px(inputLineHeight),\n\t\t\t\t\tminWidth: px(20), // fix for edge browser. buttons are cut off in small windows otherwise\n\t\t\t\t\tfontSize: a.fontSize,\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}\n\n\tfocus(e: Event, a: TextFieldAttrs) {\n\t\tif (!this.active && !a.disabled) {\n\t\t\tthis.active = true\n\t\t\tthis.domInput.focus()\n\n\t\t\tthis._domWrapper.classList.add(\"active\")\n\t\t}\n\t}\n\n\tblur(e: Event, a: TextFieldAttrs) {\n\t\tthis._domWrapper.classList.remove(\"active\")\n\t\tthis.active = false\n\t\tif (a.onblur instanceof Function) a.onblur(e)\n\t}\n\n\tisEmpty(value: string): boolean {\n\t\treturn value === \"\"\n\t}\n}\n","import { Children, Component, Vnode } from \"mithril\"\n\n/**\n * Little helper to create your components from pure functions. No need to return objects, no need to define classes, no fear of shooting\n * yourself in the foot with object components.\n */\nexport function pureComponent<T>(factory: (attrs: T, children: Children) => Children): Component<T> {\n\treturn {\n\t\tview(vnode: Vnode<T>): Children {\n\t\t\treturn factory(vnode.attrs, vnode.children)\n\t\t},\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { TranslationText } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport type { AllIcons } from \"./Icon\"\nimport { Icon } from \"./Icon\"\nimport type { clickHandler } from \"./GuiUtils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { ButtonColor, getColors } from \"./Button.js\"\nimport { assertNotNull } from \"@tutao/tutanota-utils\"\nimport { ButtonSize } from \"./ButtonSize.js\"\n\nassertMainOrNode()\n\nexport interface IconButtonAttrs {\n\ticon: AllIcons\n\ttitle: TranslationText\n\tclick: clickHandler\n\tcolors?: ButtonColor\n\tsize?: ButtonSize\n\tonblur?: () => unknown\n}\n\nexport class IconButton implements Component<IconButtonAttrs> {\n\tprivate dom: HTMLElement | null = null\n\n\tview(vnode: Vnode<IconButtonAttrs>): Children {\n\t\tconst { attrs } = vnode\n\t\treturn m(\n\t\t\t\"button.icon-button.state-bg\",\n\t\t\t{\n\t\t\t\toncreate: ({ dom }) => {\n\t\t\t\t\tthis.dom = dom as HTMLElement\n\t\t\t\t},\n\t\t\t\tonclick: (e: MouseEvent) => {\n\t\t\t\t\tattrs.click(e, assertNotNull(this.dom))\n\t\t\t\t\t// It doesn't make sense to propagate click events if we are the button\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t},\n\t\t\t\tonblur: attrs.onblur,\n\t\t\t\ttitle: lang.getMaybeLazy(attrs.title),\n\t\t\t\tclass: attrs.size === ButtonSize.Compact ? \"compact\" : \"\",\n\t\t\t},\n\t\t\tm(Icon, {\n\t\t\t\ticon: attrs.icon,\n\t\t\t\tcontainer: \"div\",\n\t\t\t\tclass: \"center-h\",\n\t\t\t\tlarge: true,\n\t\t\t\tstyle: {\n\t\t\t\t\tfill: getColors(attrs.colors ?? ButtonColor.Content).button,\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\t}\n}\n","import m, { Children, ClassComponent, Vnode } from \"mithril\"\nimport { TextField } from \"./TextField.js\"\nimport { createDropdown } from \"./Dropdown.js\"\nimport type { AllIcons } from \"./Icon\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { lazyStringValue, noOp } from \"@tutao/tutanota-utils\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { BootIcons } from \"./icons/BootIcons\"\nimport type { clickHandler } from \"./GuiUtils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { IconButton } from \"./IconButton.js\"\nimport { ButtonSize } from \"./ButtonSize.js\"\n\nassertMainOrNode()\nexport type SelectorItem<T> = {\n\tname: string\n\tvalue: T\n\tselectable?: boolean\n\ticon?: AllIcons\n\tindentationLevel?: number\n}\nexport type SelectorItemList<T> = ReadonlyArray<SelectorItem<T>>\n\nexport interface DropDownSelectorAttrs<T> {\n\tlabel: TranslationKey | lazy<string>\n\titems: SelectorItemList<T>\n\tselectedValue: T | null\n\t/** Override what is displayed for the selected value in the text field (but not in the dropdown) */\n\tselectedValueDisplay?: string\n\t/**\n\t * The handler is invoked with the new selected value. The displayed selected value is not changed automatically,\n\t * but the handler is responsible for updating this DropDownSelector. The value is updated immediately, if no selectionChangedHandler is provided\n\t */\n\tselectionChangedHandler?: ((newValue: T) => unknown) | null\n\thelpLabel?: lazy<Children>\n\tdropdownWidth?: number\n\ticon?: AllIcons\n\tdisabled?: boolean\n\tclass?: string\n\tdoShowBorder?: boolean | null\n}\n\nexport class DropDownSelector<T> implements ClassComponent<DropDownSelectorAttrs<T>> {\n\tview(vnode: Vnode<DropDownSelectorAttrs<T>>): Children {\n\t\tconst a = vnode.attrs\n\t\treturn m(TextField, {\n\t\t\tlabel: a.label,\n\t\t\tvalue: this.valueToText(a, a.selectedValue) || \"\",\n\t\t\thelpLabel: a.helpLabel,\n\t\t\tdisabled: true,\n\t\t\tonclick: a.disabled ? noOp : this.createDropdown(a),\n\t\t\tclass: \"click \" + (a.class == null ? \"mt\" : a.class),\n\t\t\tinjectionsRight: () =>\n\t\t\t\ta.disabled\n\t\t\t\t\t? null\n\t\t\t\t\t: // This whole thing with the button is not ideal. We shouldn't have a proper button with its own state layer, we should have the whole\n\t\t\t\t\t  // selector be interactive. Just putting an icon here doesn't work either because the selector disappears from tabindex even if you set it\n\t\t\t\t\t  // explicitly (at least in FF).\n\t\t\t\t\t  // Ideally we should also set correct role (\"option\") and highlight only parts of what is not text field (without help text in the bottom.\n\t\t\t\t\t  // We could hack some of this in here, but we should probably redo it from scratch with the right HTML structure.\n\t\t\t\t\t  m(\n\t\t\t\t\t\t\t\".flex.items-center.justify-center\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\twidth: \"30px\",\n\t\t\t\t\t\t\t\t\theight: \"30px\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tm(IconButton, {\n\t\t\t\t\t\t\t\ticon: a.icon ? a.icon : BootIcons.Expand,\n\t\t\t\t\t\t\t\ttitle: \"show_action\",\n\t\t\t\t\t\t\t\tclick: a.disabled ? noOp : this.createDropdown(a),\n\t\t\t\t\t\t\t\tsize: ButtonSize.Compact,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t  ),\n\t\t\tdoShowBorder: a.doShowBorder,\n\t\t})\n\t}\n\n\tcreateDropdown(a: DropDownSelectorAttrs<T>): clickHandler {\n\t\treturn createDropdown({\n\t\t\tlazyButtons: () => {\n\t\t\t\treturn a.items\n\t\t\t\t\t.filter((item) => item.selectable !== false)\n\t\t\t\t\t.map((item) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tlabel: () => item.name,\n\t\t\t\t\t\t\tclick: () => {\n\t\t\t\t\t\t\t\ta.selectionChangedHandler?.(item.value)\n\t\t\t\t\t\t\t\tm.redraw()\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tselected: a.selectedValue === item.value,\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t},\n\t\t\twidth: a.dropdownWidth,\n\t\t})\n\t}\n\n\tvalueToText(a: DropDownSelectorAttrs<T>, value: T | null): string | null {\n\t\tif (a.selectedValueDisplay) {\n\t\t\treturn a.selectedValueDisplay\n\t\t}\n\n\t\tconst selectedItem = a.items.find((item) => item.value === a.selectedValue)\n\t\tif (selectedItem) {\n\t\t\treturn selectedItem.name\n\t\t} else {\n\t\t\tconsole.log(`Dropdown ${lazyStringValue(a.label)} couldn't find element for value: ${String(JSON.stringify(value))}`)\n\t\t\treturn null\n\t\t}\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { DialogHeaderBarAttrs } from \"./DialogHeaderBar\"\nimport { DialogHeaderBar } from \"./DialogHeaderBar\"\nimport { px } from \"../size\"\nimport type { MaybeLazy } from \"@tutao/tutanota-utils\"\nimport { resolveMaybeLazy } from \"@tutao/tutanota-utils\"\nimport Stream from \"mithril/stream\"\n\nexport type DialogInjectionRightAttrs<T extends {}> = {\n\tvisible: Stream<boolean>\n\theaderAttrs: MaybeLazy<DialogHeaderBarAttrs>\n\tcomponent: Class<Component<T>>\n\tcomponentAttrs: T\n}\n\n/**\n * injects additional content on the right of a dialog\n */\nexport class DialogInjectionRight<T extends {}> implements Component<DialogInjectionRightAttrs<T>> {\n\tview({ attrs }: Vnode<DialogInjectionRightAttrs<T>>): Children {\n\t\tconst { component, componentAttrs } = attrs\n\n\t\tif (attrs.visible()) {\n\t\t\treturn m(\".flex-grow-shrink-auto.flex-transition.ml-s.rel.dialog.dialog-width-m.elevated-bg.dropdown-shadow.border-radius\", [\n\t\t\t\tm(\".dialog-header.plr-l\", m(DialogHeaderBar, resolveMaybeLazy(attrs.headerAttrs))),\n\t\t\t\tm(\".dialog-container.scroll.plr-l\", m(component, componentAttrs)),\n\t\t\t])\n\t\t} else {\n\t\t\treturn m(\".flex-hide.flex-transition.rel\", {\n\t\t\t\tstyle: {\n\t\t\t\t\tmaxWidth: px(0),\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}\n}\n","import m, { Children, Component } from \"mithril\"\nimport type { ModalComponent } from \"./Modal\"\nimport { modal } from \"./Modal\"\nimport { alpha, AlphaEnum, AnimationPromise, animations, DefaultAnimationTime, opacity, transform, TransformEnum } from \"../animation/Animations\"\nimport { ease } from \"../animation/Easing\"\nimport type { TranslationKey, TranslationText } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport type { KeyPress, Shortcut } from \"../../misc/KeyManager\"\nimport { focusNext, focusPrevious, isKeyPressed, keyManager } from \"../../misc/KeyManager\"\nimport { getElevatedBackground } from \"../theme\"\nimport { px, size } from \"../size\"\nimport { HabReminderImage } from \"./icons/Icons\"\nimport { windowFacade } from \"../../misc/WindowFacade\"\nimport type { ButtonAttrs } from \"./Button.js\"\nimport { Button, ButtonType } from \"./Button.js\"\nimport type { DialogHeaderBarAttrs } from \"./DialogHeaderBar\"\nimport { DialogHeaderBar } from \"./DialogHeaderBar\"\nimport { Autocomplete, TextField, TextFieldType } from \"./TextField.js\"\nimport type { DropDownSelectorAttrs, SelectorItemList } from \"./DropDownSelector.js\"\nimport { DropDownSelector } from \"./DropDownSelector.js\"\nimport { Keys } from \"../../api/common/TutanotaConstants\"\nimport { AriaWindow } from \"../AriaUtils\"\nimport { styles } from \"../styles\"\nimport type { lazy, MaybeLazy, Thunk } from \"@tutao/tutanota-utils\"\nimport { $Promisable, assertNotNull, getAsLazy, identity, mapLazily, noOp } from \"@tutao/tutanota-utils\"\nimport type { DialogInjectionRightAttrs } from \"./DialogInjectionRight\"\nimport { DialogInjectionRight } from \"./DialogInjectionRight\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { Icon } from \"./Icon\"\nimport { BootIcons } from \"./icons/BootIcons\"\nimport { isOfflineError } from \"../../api/common/utils/ErrorCheckUtils.js\"\n\nassertMainOrNode()\nexport const INPUT = \"input, textarea, div[contenteditable='true']\"\n\nexport const enum DialogType {\n\tProgress = \"Progress\",\n\tAlert = \"Alert\",\n\tReminder = \"Reminder\",\n\tEditSmall = \"EditSmall\",\n\tEditMedium = \"EditMedium\",\n\tEditLarger = \"EditLarger\",\n\tEditLarge = \"EditLarge\",\n}\n\ntype Validator = () => $Promisable<TranslationKey | null>\n\nexport type ActionDialogProps = {\n\ttitle: lazy<string> | string\n\tchild: Component | lazy<Children>\n\tvalidator?: Validator | null\n\tokAction: null | ((arg0: Dialog) => unknown)\n\tallowCancel?: MaybeLazy<boolean>\n\tallowOkWithReturn?: boolean\n\tokActionTextId?: MaybeLazy<TranslationKey>\n\tcancelAction?: ((arg0: Dialog) => unknown) | null\n\tcancelActionTextId?: TranslationKey\n\ttype?: DialogType\n}\n\nexport class Dialog implements ModalComponent {\n\tprivate static _keyboardHeight: number = 0\n\tprivate _domDialog: HTMLElement | null = null\n\tprivate _shortcuts: Shortcut[]\n\tview: ModalComponent[\"view\"]\n\tvisible: boolean\n\tprivate _focusOnLoadFunction: Thunk\n\tprivate _wasFocusOnLoadCalled: boolean\n\tprivate _closeHandler: Thunk | null = null\n\tprivate _focusedBeforeShown: HTMLElement | null = null\n\tprivate _injectionRightAttrs: DialogInjectionRightAttrs<any> | null = null\n\n\tconstructor(dialogType: DialogType, childComponent: Component) {\n\t\tthis.visible = false\n\n\t\tthis._focusOnLoadFunction = () => this._defaultFocusOnLoad()\n\n\t\tthis._wasFocusOnLoadCalled = false\n\t\tthis._shortcuts = [\n\t\t\t{\n\t\t\t\tkey: Keys.TAB,\n\t\t\t\tshift: true,\n\t\t\t\texec: () => (this._domDialog ? focusPrevious(this._domDialog) : false),\n\t\t\t\thelp: \"selectPrevious_action\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tkey: Keys.TAB,\n\t\t\t\tshift: false,\n\t\t\t\texec: () => (this._domDialog ? focusNext(this._domDialog) : false),\n\t\t\t\thelp: \"selectNext_action\",\n\t\t\t},\n\t\t]\n\n\t\tthis.view = (): Children => {\n\t\t\tconst marginPx = px(size.hpad)\n\t\t\tconst sidesMargin = styles.isSingleColumnLayout() && dialogType === DialogType.EditLarge ? \"4px\" : marginPx\n\t\t\treturn m(\n\t\t\t\tthis._getDialogWrapperClasses(dialogType),\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tpaddingTop: \"env(safe-area-inset-top)\",\n\t\t\t\t\t\tpaddingLeft: \"env(safe-area-inset-left)\",\n\t\t\t\t\t\tpaddingRight: \"env(safe-area-inset-right)\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t/** controls vertical alignment\n\t\t\t\t * we need overflow-hidden (actually resulting in min-height: 0 instead of auto)\n\t\t\t\t * here because otherwise the content of the dialog may make this wrapper grow bigger outside\n\t\t\t\t * the window on some browsers, e.g. upgrade reminder on Firefox mobile */\n\t\t\t\tm(\n\t\t\t\t\t\".flex.justify-center.align-self-stretch.rel.overflow-hidden\" + (dialogType === DialogType.EditLarge ? \".flex-grow\" : \".transition-margin\"),\n\t\t\t\t\t{\n\t\t\t\t\t\t// controls horizontal alignment\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tmarginTop: marginPx,\n\t\t\t\t\t\t\tmarginLeft: sidesMargin,\n\t\t\t\t\t\t\tmarginRight: sidesMargin,\n\t\t\t\t\t\t\t\"margin-bottom\": Dialog._keyboardHeight > 0 ? px(Dialog._keyboardHeight) : dialogType === DialogType.EditLarge ? 0 : marginPx,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t[\n\t\t\t\t\t\tm(\n\t\t\t\t\t\t\tthis._getDialogStyle(dialogType),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trole: AriaWindow.Dialog,\n\t\t\t\t\t\t\t\t\"aria-modal\": \"true\",\n\t\t\t\t\t\t\t\t\"aria-labelledby\": \"dialog-title\",\n\t\t\t\t\t\t\t\t\"aria-describedby\": \"dialog-message\",\n\t\t\t\t\t\t\t\tonclick: (e: MouseEvent) => e.stopPropagation(),\n\t\t\t\t\t\t\t\t// do not propagate clicks on the dialog as the Modal expects all propagated clicks to be clicks on the background\n\t\t\t\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\t\t\t\tthis._domDialog = vnode.dom as HTMLElement\n\t\t\t\t\t\t\t\t\tlet animation: AnimationPromise | null = null\n\n\t\t\t\t\t\t\t\t\tif (dialogType === DialogType.EditLarge) {\n\t\t\t\t\t\t\t\t\t\tthis._domDialog.style.transform = `translateY(${window.innerHeight}px)`\n\t\t\t\t\t\t\t\t\t\tanimation = animations.add(this._domDialog, transform(TransformEnum.TranslateY, window.innerHeight, 0))\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst bgcolor = getElevatedBackground()\n\t\t\t\t\t\t\t\t\t\tconst children = Array.from(this._domDialog.children) as Array<HTMLElement>\n\t\t\t\t\t\t\t\t\t\tfor (let child of children) {\n\t\t\t\t\t\t\t\t\t\t\tchild.style.opacity = \"0\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tthis._domDialog.style.backgroundColor = `rgba(0, 0, 0, 0)`\n\t\t\t\t\t\t\t\t\t\tanimation = Promise.all([\n\t\t\t\t\t\t\t\t\t\t\tanimations.add(this._domDialog, alpha(AlphaEnum.BackgroundColor, bgcolor, 0, 1)),\n\t\t\t\t\t\t\t\t\t\t\tanimations.add(children, opacity(0, 1, true), {\n\t\t\t\t\t\t\t\t\t\t\t\tdelay: DefaultAnimationTime / 2,\n\t\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// select first input field. blur first to avoid that users can enter text in the previously focused element while the animation is running\n\t\t\t\t\t\t\t\t\twindow.requestAnimationFrame(() => {\n\t\t\t\t\t\t\t\t\t\tconst activeElement = document.activeElement as HTMLElement | null\n\t\t\t\t\t\t\t\t\t\tif (activeElement && typeof activeElement.blur === \"function\") {\n\t\t\t\t\t\t\t\t\t\t\tactiveElement.blur()\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\tanimation.then(() => {\n\t\t\t\t\t\t\t\t\t\tthis._focusOnLoadFunction()\n\n\t\t\t\t\t\t\t\t\t\tthis._wasFocusOnLoadCalled = true\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tm(childComponent),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tthis._injectionRightAttrs ? m(DialogInjectionRight, this._injectionRightAttrs) : null,\n\t\t\t\t\t],\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\t}\n\n\tsetInjectionRight(injectionRightAttrs: DialogInjectionRightAttrs<any>) {\n\t\tthis._injectionRightAttrs = injectionRightAttrs\n\t}\n\n\t_defaultFocusOnLoad() {\n\t\tconst dom = assertNotNull(this._domDialog)\n\t\tlet inputs = Array.from(dom.querySelectorAll(INPUT)) as Array<HTMLElement>\n\n\t\tif (inputs.length > 0) {\n\t\t\tinputs[0].focus()\n\t\t} else {\n\t\t\tlet button = dom.querySelector(\"button\")\n\n\t\t\tif (button) {\n\t\t\t\tbutton.focus()\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * By default the focus is set on the first text field after this dialog is fully visible. This behavior can be overwritten by calling this function.\n\t * If it has already been called, then calls it instantly\n\t */\n\tsetFocusOnLoadFunction(callback: Dialog[\"_focusOnLoadFunction\"]): void {\n\t\tthis._focusOnLoadFunction = callback\n\n\t\tif (this._wasFocusOnLoadCalled) {\n\t\t\tthis._focusOnLoadFunction()\n\t\t}\n\t}\n\n\t_getDialogWrapperClasses(dialogType: DialogType): string {\n\t\t// change direction of axis to handle resize of dialogs (iOS keyboard open changes size)\n\t\tlet dialogWrapperStyle = \".fill-absolute.flex.items-stretch.flex-column\"\n\n\t\tif (dialogType === DialogType.EditLarge) {\n\t\t\tdialogWrapperStyle += \".flex-start\"\n\t\t} else {\n\t\t\tdialogWrapperStyle += \".flex-center\" // vertical alignment\n\t\t}\n\n\t\treturn dialogWrapperStyle\n\t}\n\n\t_getDialogStyle(dialogType: DialogType): string {\n\t\tlet dialogStyle = \".dialog.elevated-bg.flex-grow.border-radius-top\"\n\n\t\tif (dialogType === DialogType.Progress) {\n\t\t\tdialogStyle += \".dialog-width-s.dialog-progress.border-radius-bottom\"\n\t\t} else if (dialogType === DialogType.Alert) {\n\t\t\tdialogStyle += \".dialog-width-alert.pt.border-radius-bottom\"\n\t\t} else if (dialogType === DialogType.Reminder) {\n\t\t\tdialogStyle += \".dialog-width-m.pt.flex.flex-column.border-radius-bottom\"\n\t\t} else if (dialogType === DialogType.EditSmall) {\n\t\t\tdialogStyle += \".dialog-width-s.flex.flex-column.border-radius-bottom\"\n\t\t} else if (dialogType === DialogType.EditMedium) {\n\t\t\tdialogStyle += \".dialog-width-m.border-radius-bottom\"\n\t\t} else if (dialogType === DialogType.EditLarge || dialogType === DialogType.EditLarger) {\n\t\t\tdialogStyle += \".dialog-width-l\"\n\t\t}\n\n\t\treturn dialogStyle\n\t}\n\n\taddShortcut(shortcut: Shortcut): Dialog {\n\t\tthis._shortcuts.push(shortcut)\n\n\t\tif (this.visible) {\n\t\t\tkeyManager.registerModalShortcuts([shortcut])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Sets a close handler to the dialog. If set the handler will be notified when onClose is called on the dialog.\n\t * The handler must is then responsible for closing the dialog.\n\t */\n\tsetCloseHandler(closeHandler: (() => unknown) | null): Dialog {\n\t\tthis._closeHandler = closeHandler\n\t\treturn this\n\t}\n\n\tshortcuts(): Shortcut[] {\n\t\treturn this._shortcuts\n\t}\n\n\tshow(): Dialog {\n\t\tthis._focusedBeforeShown = document.activeElement as HTMLElement\n\t\tmodal.display(this)\n\t\tthis.visible = true\n\t\treturn this\n\t}\n\n\t/**\n\t * Removes the dialog from the current view.\n\t */\n\tclose(): void {\n\t\tthis.visible = false\n\t\tmodal.remove(this)\n\t\tthis._focusedBeforeShown && this._focusedBeforeShown.focus()\n\t}\n\n\t/**\n\t * Should be called to close a dialog. Notifies the closeHandler about the close attempt.\n\t */\n\tonClose(): void {\n\t\tif (this._closeHandler) {\n\t\t\tthis._closeHandler()\n\t\t} else {\n\t\t\tthis.close()\n\t\t}\n\t}\n\n\tpopState(e: Event): boolean {\n\t\tthis.onClose()\n\t\treturn false\n\t}\n\n\t/**\n\t * Is invoked from modal as the two animations (background layer opacity and dropdown) should run in parallel\n\t * @returns {Promise.<void>}\n\t */\n\thideAnimation(): Promise<void> {\n\t\tlet bgcolor = getElevatedBackground()\n\n\t\tif (this._domDialog) {\n\t\t\treturn Promise.all([\n\t\t\t\tanimations.add(this._domDialog.children, opacity(1, 0, true)),\n\t\t\t\tanimations.add(this._domDialog, alpha(AlphaEnum.BackgroundColor, bgcolor, 1, 0), {\n\t\t\t\t\tdelay: DefaultAnimationTime / 2,\n\t\t\t\t\teasing: ease.linear,\n\t\t\t\t}),\n\t\t\t]).then(noOp)\n\t\t} else {\n\t\t\treturn Promise.resolve()\n\t\t}\n\t}\n\n\tbackgroundClick(e: MouseEvent) {}\n\n\t/**\n\t * show a dialog with only a \"ok\" button\n\t *\n\t * @param messageIdOrMessageFunction {TranslationKey | lazy<string>} the text to display\n\t * @param infoToAppend {?string | lazy<Children>} some text or UI elements to show below the message\n\t * @returns {Promise<void>} a promise that resolves after the dialog is fully closed\n\t */\n\tstatic message(messageIdOrMessageFunction: TranslationKey | lazy<string>, infoToAppend?: string | lazy<Children>): Promise<void> {\n\t\treturn new Promise((resolve) => {\n\t\t\tlet dialog: Dialog\n\n\t\t\tconst closeAction = () => {\n\t\t\t\tdialog.close()\n\t\t\t\tsetTimeout(() => resolve(), DefaultAnimationTime)\n\t\t\t}\n\n\t\t\tlet lines = lang.getMaybeLazy(messageIdOrMessageFunction).split(\"\\n\")\n\n\t\t\tif (typeof infoToAppend === \"string\") {\n\t\t\t\tlines.push(infoToAppend)\n\t\t\t}\n\n\t\t\tconst buttonAttrs: ButtonAttrs = {\n\t\t\t\tlabel: \"ok_action\",\n\t\t\t\tclick: closeAction,\n\t\t\t\ttype: ButtonType.Primary,\n\t\t\t}\n\t\t\tdialog = new Dialog(DialogType.Alert, {\n\t\t\t\tview: () => [\n\t\t\t\t\tm(\"#dialog-message.dialog-max-height.dialog-contentButtonsBottom.text-break.text-prewrap.selectable.scroll\", [\n\t\t\t\t\t\tlines.map((line) => m(\".text-break.selectable\", line)),\n\t\t\t\t\t\ttypeof infoToAppend == \"function\" ? infoToAppend() : null,\n\t\t\t\t\t]),\n\t\t\t\t\tm(\".flex-center.dialog-buttons\", m(Button, buttonAttrs)),\n\t\t\t\t],\n\t\t\t})\n\t\t\t\t.setCloseHandler(closeAction)\n\t\t\t\t.addShortcut({\n\t\t\t\t\tkey: Keys.RETURN,\n\t\t\t\t\tshift: false,\n\t\t\t\t\texec: closeAction,\n\t\t\t\t\thelp: \"close_alt\",\n\t\t\t\t})\n\t\t\t\t.addShortcut({\n\t\t\t\t\tkey: Keys.ESC,\n\t\t\t\t\tshift: false,\n\t\t\t\t\texec: closeAction,\n\t\t\t\t\thelp: \"close_alt\",\n\t\t\t\t})\n\t\t\t\t.show()\n\t\t})\n\t}\n\n\t/**\n\t * fallback for cases where we can't directly download and open a file\n\t */\n\tstatic legacyDownload(filename: string, url: string): Promise<void> {\n\t\treturn new Promise((resolve) => {\n\t\t\tlet dialog: Dialog\n\n\t\t\tconst closeAction = () => {\n\t\t\t\tdialog.close()\n\t\t\t\tsetTimeout(() => resolve(), DefaultAnimationTime)\n\t\t\t}\n\n\t\t\tconst closeButtonAttrs: ButtonAttrs = {\n\t\t\t\tlabel: \"close_alt\",\n\t\t\t\tclick: closeAction,\n\t\t\t\ttype: ButtonType.Primary,\n\t\t\t}\n\t\t\tconst downloadButtonAttrs: ButtonAttrs = {\n\t\t\t\tlabel: \"download_action\",\n\t\t\t\tclick: () => {\n\t\t\t\t\tconst popup = open(\"\", \"_blank\")\n\t\t\t\t\tif (popup) {\n\t\t\t\t\t\tpopup.location = url\n\t\t\t\t\t}\n\t\t\t\t\tdialog.close()\n\t\t\t\t\tresolve()\n\t\t\t\t},\n\t\t\t\ttype: ButtonType.Primary,\n\t\t\t}\n\t\t\tdialog = new Dialog(DialogType.Alert, {\n\t\t\t\tview: () =>\n\t\t\t\t\tm(\"\", [\n\t\t\t\t\t\tm(\".dialog-contentButtonsBottom.text-break\", [m(Button, downloadButtonAttrs), m(\".pt\", lang.get(\"saveDownloadNotPossibleIos_msg\"))]),\n\t\t\t\t\t\tm(\".flex-center.dialog-buttons\", m(Button, closeButtonAttrs)),\n\t\t\t\t\t]),\n\t\t\t})\n\t\t\t\t.setCloseHandler(closeAction)\n\t\t\t\t.show()\n\t\t})\n\t}\n\n\t/**\n\t * Simpler version of {@link Dialog#confirmMultiple} with just two options: no and yes (or another confirmation).\n\t * @return Promise, which is resolved with user selection - true for confirm, false for cancel.\n\t */\n\tstatic confirm(\n\t\tmessageIdOrMessageFunction: TranslationKey | lazy<string>,\n\t\tconfirmId: TranslationKey = \"ok_action\",\n\t\tinfoToAppend?: string | lazy<Children>,\n\t): Promise<boolean> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst closeAction = (conf: boolean) => {\n\t\t\t\tdialog.close()\n\t\t\t\tsetTimeout(() => resolve(conf), DefaultAnimationTime)\n\t\t\t}\n\n\t\t\tconst buttonAttrs: Array<ButtonAttrs> = [\n\t\t\t\t{\n\t\t\t\t\tlabel: \"cancel_action\",\n\t\t\t\t\tclick: () => closeAction(false),\n\t\t\t\t\ttype: ButtonType.Secondary,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: confirmId,\n\t\t\t\t\tclick: () => closeAction(true),\n\t\t\t\t\ttype: ButtonType.Primary,\n\t\t\t\t},\n\t\t\t]\n\t\t\tconst dialog = Dialog.confirmMultiple(messageIdOrMessageFunction, buttonAttrs, resolve, infoToAppend)\n\t\t})\n\t}\n\n\t/**\n\t * Show a dialog with multiple selection options below the message.\n\t * @param messageIdOrMessageFunction which displayed in the body\n\t * @param buttons which are displayed below\n\t * @param onclose which is called on shortcut or when dialog is closed any other way (e.g. back navigation). Not called when pressing\n\t * one of the buttons.\n\t * @param infoToAppend additional UI elements to show below the message\n\t */\n\tstatic confirmMultiple(\n\t\tmessageIdOrMessageFunction: TranslationKey | lazy<string>,\n\t\tbuttons: ReadonlyArray<ButtonAttrs>,\n\t\tonclose?: (positive: boolean) => unknown,\n\t\tinfoToAppend?: string | lazy<Children>,\n\t): Dialog {\n\t\tlet dialog: Dialog\n\n\t\tconst closeAction = (positive: boolean) => {\n\t\t\tdialog.close()\n\t\t\tsetTimeout(() => onclose && onclose(positive), DefaultAnimationTime)\n\t\t}\n\n\t\t// Wrap in a function to ensure that m() is called in every view() update for the infoToAppend\n\t\tfunction getContent(): Children {\n\t\t\tconst additionalChild =\n\t\t\t\ttypeof infoToAppend === \"string\"\n\t\t\t\t\t? m(\".dialog-contentButtonsBottom.text-break.selectable\", infoToAppend)\n\t\t\t\t\t: typeof infoToAppend === \"function\"\n\t\t\t\t\t? infoToAppend()\n\t\t\t\t\t: null\n\n\t\t\treturn [lang.getMaybeLazy(messageIdOrMessageFunction), additionalChild]\n\t\t}\n\n\t\tdialog = new Dialog(DialogType.Alert, {\n\t\t\tview: () => [\n\t\t\t\tm(\"#dialog-message.dialog-max-height.dialog-contentButtonsBottom.text-break.text-prewrap.selectable.scroll\", getContent()),\n\t\t\t\tm(\n\t\t\t\t\t\".flex-center.dialog-buttons\",\n\t\t\t\t\tbuttons.map((a) => m(Button, a)),\n\t\t\t\t),\n\t\t\t],\n\t\t})\n\t\t\t.setCloseHandler(() => closeAction(false))\n\t\t\t.addShortcut({\n\t\t\t\tkey: Keys.ESC,\n\t\t\t\tshift: false,\n\t\t\t\texec: () => closeAction(false),\n\t\t\t\thelp: \"cancel_action\",\n\t\t\t})\n\t\tdialog.show()\n\t\treturn dialog\n\t}\n\n\tstatic choice<T>(\n\t\tmessage: TranslationText,\n\t\tchoices: Array<{\n\t\t\ttext: TranslationText\n\t\t\tvalue: T\n\t\t}>,\n\t): Promise<T> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst choose = (choice: T) => {\n\t\t\t\tdialog.close()\n\t\t\t\tsetTimeout(() => resolve(choice), DefaultAnimationTime)\n\t\t\t}\n\n\t\t\tconst buttonAttrs = choices.map((choice) => {\n\t\t\t\treturn {\n\t\t\t\t\tlabel: choice.text,\n\t\t\t\t\tclick: () => choose(choice.value),\n\t\t\t\t\ttype: ButtonType.Secondary,\n\t\t\t\t}\n\t\t\t})\n\t\t\tconst dialog = Dialog.confirmMultiple(message, buttonAttrs)\n\t\t})\n\t}\n\n\t// used in admin client\n\tstatic save(title: lazy<string>, saveAction: () => Promise<void>, child: Component): Promise<void> {\n\t\treturn new Promise((resolve) => {\n\t\t\tlet saveDialog: Dialog\n\n\t\t\tconst closeAction = () => {\n\t\t\t\tsaveDialog.close()\n\t\t\t\tsetTimeout(() => resolve(), DefaultAnimationTime)\n\t\t\t}\n\n\t\t\tconst onOk = () => {\n\t\t\t\tsaveAction().then(() => {\n\t\t\t\t\tsaveDialog.close()\n\t\t\t\t\tsetTimeout(() => resolve(), DefaultAnimationTime)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tconst actionBarAttrs: DialogHeaderBarAttrs = {\n\t\t\t\tleft: [\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: \"close_alt\",\n\t\t\t\t\t\tclick: closeAction,\n\t\t\t\t\t\ttype: ButtonType.Secondary,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tright: [\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: \"save_action\",\n\t\t\t\t\t\tclick: onOk,\n\t\t\t\t\t\ttype: ButtonType.Primary,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tmiddle: title,\n\t\t\t}\n\t\t\tsaveDialog = new Dialog(DialogType.EditMedium, {\n\t\t\t\tview: () => m(\"\", [m(\".dialog-header.plr-l\", m(DialogHeaderBar, actionBarAttrs)), m(\".plr-l.pb.text-break\", m(child))]),\n\t\t\t})\n\t\t\t\t.setCloseHandler(closeAction)\n\t\t\t\t.show()\n\t\t})\n\t}\n\n\tstatic reminder(title: string, message: string): Promise<boolean> {\n\t\treturn new Promise((resolve) => {\n\t\t\tlet dialog: Dialog\n\n\t\t\tconst closeAction = (res: boolean) => {\n\t\t\t\tdialog.close()\n\t\t\t\tsetTimeout(() => resolve(res), DefaultAnimationTime)\n\t\t\t}\n\n\t\t\tconst buttonAttrs: Array<ButtonAttrs> = [\n\t\t\t\t{\n\t\t\t\t\tlabel: \"upgradeReminderCancel_action\",\n\t\t\t\t\tclick: () => closeAction(false),\n\t\t\t\t\ttype: ButtonType.Secondary,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: \"showMoreUpgrade_action\",\n\t\t\t\t\tclick: () => closeAction(true),\n\t\t\t\t\ttype: ButtonType.Primary,\n\t\t\t\t},\n\t\t\t]\n\t\t\tdialog = new Dialog(DialogType.Reminder, {\n\t\t\t\tview: () => [\n\t\t\t\t\tm(\".dialog-contentButtonsBottom.text-break.scroll\", [\n\t\t\t\t\t\tm(\".h2.pb\", title),\n\t\t\t\t\t\tm(\".flex-direction-change.items-center\", [\n\t\t\t\t\t\t\tm(\"#dialog-message.pb\", message),\n\t\t\t\t\t\t\tm(\"img[src=\" + HabReminderImage + \"].dialog-img.mb.bg-white.border-radius\", {\n\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\"min-width\": \"150px\",\n\t\t\t\t\t\t\t\t},\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\tm(\n\t\t\t\t\t\t\".flex-center.dialog-buttons.flex-no-grow-no-shrink-auto\",\n\t\t\t\t\t\tbuttonAttrs.map((a) => m(Button, a)),\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t})\n\t\t\t\t.setCloseHandler(() => closeAction(false))\n\t\t\t\t.addShortcut({\n\t\t\t\t\tkey: Keys.ESC,\n\t\t\t\t\tshift: false,\n\t\t\t\t\texec: () => closeAction(false),\n\t\t\t\t\thelp: \"cancel_action\",\n\t\t\t\t})\n\t\t\t\t.show()\n\t\t})\n\t}\n\n\t/**\n\t * Shows a dialog with a text field input and ok/cancel buttons.\n\t * @param   props.child either a component (object with view function that returns a Children) or a naked view Function\n\t * @param   props.validator Called when \"Ok\" is clicked. Must return null if the input is valid or an error messageID if it is invalid, so an error message is shown.\n\t * @param   props.okAction called after successful validation.\n\t * @param   props.cancelAction called when allowCancel is true and the cancel button/shortcut was pressed.\n\t * @returns the Dialog\n\t */\n\tstatic showActionDialog(props: ActionDialogProps): Dialog {\n\t\tlet dialog = this.createActionDialog(props)\n\t\treturn dialog.show()\n\t}\n\n\tstatic createActionDialog(props: ActionDialogProps): Dialog {\n\t\tlet dialog: Dialog\n\t\tconst { title, child, okAction, validator, allowCancel, allowOkWithReturn, okActionTextId, cancelActionTextId, cancelAction, type } = Object.assign(\n\t\t\t{},\n\t\t\t{\n\t\t\t\tallowCancel: true,\n\t\t\t\tallowOkWithReturn: false,\n\t\t\t\tokActionTextId: \"ok_action\",\n\t\t\t\tcancelActionTextId: \"cancel_action\",\n\t\t\t\ttype: DialogType.EditSmall,\n\t\t\t},\n\t\t\tprops,\n\t\t)\n\n\t\tconst doCancel = () => {\n\t\t\tif (cancelAction) {\n\t\t\t\tcancelAction(dialog)\n\t\t\t}\n\n\t\t\tdialog.close()\n\t\t}\n\n\t\tconst doAction = () => {\n\t\t\tif (!okAction) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlet validationResult: $Promisable<TranslationKey | null> | null = null\n\n\t\t\tif (validator) {\n\t\t\t\tvalidationResult = validator()\n\t\t\t}\n\n\t\t\tlet finalizer = Promise.resolve(validationResult).then((error_id) => {\n\t\t\t\tif (error_id) {\n\t\t\t\t\tDialog.message(error_id)\n\t\t\t\t} else {\n\t\t\t\t\tokAction(dialog)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tif (validationResult instanceof Promise) {\n\t\t\t\t// breaking hard circular dependency\n\t\t\t\timport(\"../dialogs/ProgressDialog\").then((module) => module.showProgressDialog(\"pleaseWait_msg\", finalizer))\n\t\t\t}\n\t\t}\n\n\t\tconst actionBarAttrs: DialogHeaderBarAttrs = {\n\t\t\tleft: mapLazily(allowCancel, (allow) =>\n\t\t\t\tallow\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlabel: cancelActionTextId,\n\t\t\t\t\t\t\t\tclick: doCancel,\n\t\t\t\t\t\t\t\ttype: ButtonType.Secondary,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t  ]\n\t\t\t\t\t: [],\n\t\t\t),\n\t\t\tright: okAction\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: mapLazily(okActionTextId, (id) => lang.get(id)),\n\t\t\t\t\t\t\tclick: doAction,\n\t\t\t\t\t\t\ttype: ButtonType.Primary,\n\t\t\t\t\t\t},\n\t\t\t\t  ]\n\t\t\t\t: [],\n\t\t\tmiddle: typeof title === \"function\" ? title : () => title,\n\t\t}\n\t\tdialog = new Dialog(type, {\n\t\t\tview: () => [\n\t\t\t\tm(\".dialog-header.plr-l\", m(DialogHeaderBar, actionBarAttrs)),\n\t\t\t\tm(\".dialog-max-height.plr-l.pb.text-break.scroll\", \"function\" === typeof child ? child() : m(child)),\n\t\t\t],\n\t\t}).setCloseHandler(doCancel)\n\t\tdialog.addShortcut({\n\t\t\tkey: Keys.ESC,\n\t\t\tshift: false,\n\t\t\texec: mapLazily(allowCancel, (allow) => allow && doCancel()),\n\t\t\thelp: \"cancel_action\",\n\t\t\tenabled: getAsLazy(allowCancel),\n\t\t})\n\n\t\tif (allowOkWithReturn) {\n\t\t\tdialog.addShortcut({\n\t\t\t\tkey: Keys.RETURN,\n\t\t\t\tshift: false,\n\t\t\t\texec: doAction,\n\t\t\t\thelp: \"ok_action\",\n\t\t\t})\n\t\t}\n\n\t\treturn dialog\n\t}\n\n\t/**\n\t * Shows a dialog with a text field input and ok/cancel buttons.\n\t * @param titleId title of the dialog\n\t * @param labelIdOrLabelFunction label of the text field\n\t * @param infoMsgId help label of the text field\n\t * @param value initial value\n\t * @param inputValidator Called when \"Ok\" is clicked receiving the entered text. Must return null if the text is valid or an error messageId if the text is invalid, so an error message is shown.\n\t * @returns A promise resolving to the entered text. The returned promise is only resolved if \"ok\" is clicked.\n\t */\n\tstatic showTextInputDialog(\n\t\ttitleId: TranslationKey | lazy<string>,\n\t\tlabelIdOrLabelFunction: TranslationKey | lazy<string>,\n\t\tinfoMsgId: (TranslationKey | null) | (lazy<string> | null),\n\t\tvalue: string,\n\t\tinputValidator?: stringValidator,\n\t): Promise<string> {\n\t\treturn new Promise((resolve) => {\n\t\t\tlet result = value\n\t\t\tDialog.showActionDialog({\n\t\t\t\ttitle: lang.getMaybeLazy(titleId),\n\t\t\t\tchild: () =>\n\t\t\t\t\tm(TextField, {\n\t\t\t\t\t\tlabel: labelIdOrLabelFunction,\n\t\t\t\t\t\tvalue: result,\n\t\t\t\t\t\toninput: (newValue) => (result = newValue),\n\t\t\t\t\t\thelpLabel: () => (infoMsgId ? lang.getMaybeLazy(infoMsgId) : \"\"),\n\t\t\t\t\t}),\n\t\t\t\tvalidator: () => (inputValidator ? inputValidator(result) : null),\n\t\t\t\tallowOkWithReturn: true,\n\t\t\t\tokAction: (dialog: Dialog) => {\n\t\t\t\t\tresolve(result)\n\t\t\t\t\tdialog.close()\n\t\t\t\t},\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Shows a dialog with a text field input and ok/cancel buttons. In contrast to {@link showTextInputDialog} the entered text is not returned but processed in the okayAction.\n\t * @param titleId title of the dialog\n\t * @param labelIdOrLabelFunction label of the text field\n\t * @param infoMsgId help label of the text field\n\t * @param value initial value\n\t * @param inputValidator Called when \"Ok\" is clicked receiving the entered text. Must return null if the text is valid or an error messageId if the text is invalid, so an error message is shown.\n\t * @param okAction Called when \"OK\" is clicked, receives the entered text. If the okayAction results in a ConnectionsError the dialog is not closed.\n\t */\n\tstatic showProcessTextInputDialog(\n\t\ttitleId: TranslationKey | lazy<string>,\n\t\tlabelIdOrLabelFunction: TranslationKey | lazy<string>,\n\t\tinfoMsgId: (TranslationKey | null) | (lazy<string> | null),\n\t\tvalue: string,\n\t\tokAction: (arg0: string) => Promise<unknown>,\n\t\tinputValidator?: stringValidator,\n\t) {\n\t\tlet result = value\n\t\tDialog.showActionDialog({\n\t\t\ttitle: lang.getMaybeLazy(titleId),\n\t\t\tchild: () =>\n\t\t\t\tm(TextField, {\n\t\t\t\t\tlabel: labelIdOrLabelFunction,\n\t\t\t\t\tvalue: result,\n\t\t\t\t\toninput: (newValue) => (result = newValue),\n\t\t\t\t\thelpLabel: () => (infoMsgId ? lang.getMaybeLazy(infoMsgId) : \"\"),\n\t\t\t\t}),\n\t\t\tvalidator: () => (inputValidator ? inputValidator(result) : null),\n\t\t\tallowOkWithReturn: true,\n\t\t\tokAction: (dialog: Dialog) => {\n\t\t\t\tokAction(result)\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tdialog.close()\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error) => {\n\t\t\t\t\t\tif (!isOfflineError(error)) {\n\t\t\t\t\t\t\tdialog.close()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t})\n\t\t\t},\n\t\t})\n\t}\n\n\t/**\n\t * Shows a dialog with a text area input and ok/cancel buttons.\n\t * @param titleId title of the dialog\n\t * @param labelIdOrLabelFunction label of the text area\n\t * @param infoMsgId help label of the text area\n\t * @param value initial value\n\t * @returns A promise resolving to the entered text. The returned promise is only resolved if \"ok\" is clicked.\n\t */\n\tstatic showTextAreaInputDialog(\n\t\ttitleId: TranslationKey,\n\t\tlabelIdOrLabelFunction: TranslationKey | lazy<string>,\n\t\tinfoMsgId: TranslationKey | null,\n\t\tvalue: string,\n\t): Promise<string> {\n\t\treturn new Promise((resolve) => {\n\t\t\tlet result: string = value\n\t\t\tDialog.showActionDialog({\n\t\t\t\ttitle: lang.get(titleId),\n\t\t\t\tchild: {\n\t\t\t\t\tview: () =>\n\t\t\t\t\t\tm(TextField, {\n\t\t\t\t\t\t\tlabel: labelIdOrLabelFunction,\n\t\t\t\t\t\t\thelpLabel: () => (infoMsgId ? lang.get(infoMsgId) : \"\"),\n\t\t\t\t\t\t\tvalue: result,\n\t\t\t\t\t\t\toninput: (newValue) => (result = newValue),\n\t\t\t\t\t\t\ttype: TextFieldType.Area,\n\t\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tokAction: (dialog: Dialog) => {\n\t\t\t\t\tresolve(result)\n\t\t\t\t\tdialog.close()\n\t\t\t\t},\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Show a dialog with a dropdown selector\n\t * @param titleId title of the dialog\n\t * @param label label of the dropdown selector\n\t * @param infoMsgId help label of the dropdown selector\n\t * @param items selection set\n\t * @param initialValue initial value\n\t * @param dropdownWidth width of the dropdown\n\t * @returns A promise resolving to the selected item. The returned promise is only resolved if \"ok\" is clicked.\n\t */\n\tstatic showDropDownSelectionDialog<T>(\n\t\ttitleId: TranslationKey,\n\t\tlabel: TranslationKey,\n\t\tinfoMsgId: TranslationKey | null,\n\t\titems: SelectorItemList<T>,\n\t\tinitialValue: T,\n\t\tdropdownWidth?: number,\n\t): Promise<T> {\n\t\tlet selectedValue: T = initialValue\n\t\treturn new Promise((resolve) => {\n\t\t\tDialog.showActionDialog({\n\t\t\t\ttitle: lang.get(titleId),\n\t\t\t\tchild: {\n\t\t\t\t\tview: () =>\n\t\t\t\t\t\t// identity as type assertion\n\t\t\t\t\t\tm(\n\t\t\t\t\t\t\tDropDownSelector,\n\t\t\t\t\t\t\tidentity<DropDownSelectorAttrs<T>>({\n\t\t\t\t\t\t\t\tlabel,\n\t\t\t\t\t\t\t\titems,\n\t\t\t\t\t\t\t\tselectedValue: selectedValue,\n\t\t\t\t\t\t\t\tselectionChangedHandler: (newValue) => (selectedValue = newValue),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\tokAction: (dialog: Dialog) => {\n\t\t\t\t\tresolve(selectedValue)\n\t\t\t\t\tdialog.close()\n\t\t\t\t},\n\t\t\t})\n\t\t})\n\t}\n\n\t/** @deprecated use editDialog*/\n\tstatic largeDialog(headerBarAttrs: DialogHeaderBarAttrs, child: Component): Dialog {\n\t\treturn new Dialog(DialogType.EditLarge, {\n\t\t\tview: () => {\n\t\t\t\treturn m(\"\", [\n\t\t\t\t\tm(\".dialog-header.plr-l\", m(DialogHeaderBar, headerBarAttrs)),\n\t\t\t\t\tm(\".dialog-container.scroll\", m(\".fill-absolute.plr-l\", m(child))),\n\t\t\t\t])\n\t\t\t},\n\t\t})\n\t}\n\n\tstatic editDialog<T extends {}>(headerBarAttrs: DialogHeaderBarAttrs, child: Class<Component<T>>, childAttrs: T): Dialog {\n\t\treturn new Dialog(DialogType.EditLarge, {\n\t\t\tview: () =>\n\t\t\t\tm(\"\", [\n\t\t\t\t\t/** fixed-height header with a title, left and right buttons that's fixed to the top of the dialog's area */\n\t\t\t\t\theaderBarAttrs.noHeader ? null : m(\".dialog-header.plr-l\", m(DialogHeaderBar, headerBarAttrs)),\n\t\t\t\t\t/** variable-size child container that may be scrollable. */\n\t\t\t\t\tm(\".dialog-container.scroll\", m(\".fill-absolute.plr-l\", m(child, childAttrs))),\n\t\t\t\t]),\n\t\t})\n\t}\n\n\t/**\n\t * Requests a password from the user. Stays open until the caller sets the error message to \"\".\n\t * @param props.action will be executed as an attempt to apply new password. Error message is the return value.\n\t */\n\tstatic showRequestPasswordDialog(props: {\n\t\taction: (pw: string) => Promise<string>\n\t\tcancel: {\n\t\t\ttextId: TranslationKey\n\t\t\taction: () => void\n\t\t} | null\n\t}): Dialog {\n\t\tlet value = \"\"\n\t\tlet state: { type: \"progress\" } | { type: \"idle\"; message: string } = { type: \"idle\", message: \"\" }\n\n\t\tconst doAction = async () => {\n\t\t\tstate = { type: \"progress\" }\n\t\t\tm.redraw()\n\t\t\tconst errorMessage = await props.action(value)\n\t\t\tstate = { type: \"idle\", message: errorMessage }\n\t\t\tm.redraw()\n\t\t}\n\n\t\tconst child = {\n\t\t\tview: () => {\n\t\t\t\tconst savedState = state\n\t\t\t\treturn savedState.type == \"idle\"\n\t\t\t\t\t? m(TextField, {\n\t\t\t\t\t\t\tlabel: \"password_label\",\n\t\t\t\t\t\t\thelpLabel: () => savedState.message,\n\t\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\t\toninput: (newValue) => (value = newValue),\n\t\t\t\t\t\t\tautocompleteAs: Autocomplete.off,\n\t\t\t\t\t\t\ttype: TextFieldType.Password,\n\t\t\t\t\t\t\tkeyHandler: (key: KeyPress) => {\n\t\t\t\t\t\t\t\tif (isKeyPressed(key.keyCode, Keys.RETURN)) {\n\t\t\t\t\t\t\t\t\tdoAction()\n\t\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t},\n\t\t\t\t\t  })\n\t\t\t\t\t: m(Icon, {\n\t\t\t\t\t\t\ticon: BootIcons.Progress,\n\t\t\t\t\t\t\tclass: \"icon-xl icon-progress block mt mb\",\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\tmarginLeft: \"auto\",\n\t\t\t\t\t\t\t\tmarginRight: \"auto\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t  })\n\t\t\t},\n\t\t}\n\t\tconst dialog = Dialog.showActionDialog({\n\t\t\ttitle: lang.get(\"password_label\"),\n\t\t\tchild: child,\n\t\t\tallowOkWithReturn: true,\n\t\t\tokAction: () => doAction(),\n\t\t\tcancelActionTextId: props.cancel?.textId,\n\t\t\tallowCancel: props.cancel != null,\n\t\t\tcancelAction: () => {\n\t\t\t\tprops?.cancel?.action?.()\n\t\t\t\tdialog.close()\n\t\t\t},\n\t\t})\n\t\treturn dialog\n\t}\n\n\tstatic _onKeyboardSizeChanged(newSize: number): void {\n\t\tDialog._keyboardHeight = newSize\n\t\tm.redraw()\n\t}\n}\n\nexport type stringValidator = (arg0: string) => (TranslationKey | null) | Promise<TranslationKey | null>\nwindowFacade.addKeyboardSizeListener(Dialog._onKeyboardSizeChanged)\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { px } from \"../size\"\nimport { DefaultAnimationTime, transform, TransformEnum } from \"../animation/Animations\"\nimport { displayOverlay } from \"./Overlay\"\nimport type { ButtonAttrs } from \"./Button.js\"\nimport { Button, ButtonType } from \"./Button.js\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { clickHandler } from \"./GuiUtils\"\n\nassertMainOrNode()\n\ninterface NotificationOverlayAttrs {\n\tmessage: Component\n\tbuttons: Array<ButtonAttrs>\n}\n\ninterface QueueItem extends NotificationOverlayAttrs {\n\tcloseButtonAttrs: Partial<ButtonAttrs>\n}\n\nconst notificationQueue: QueueItem[] = []\nlet currentAnimationTimeout: TimeoutID | null = null\n\nclass NotificationOverlay implements Component<NotificationOverlayAttrs> {\n\tview(vnode: Vnode<NotificationOverlayAttrs>): Children {\n\t\treturn m(\".notification-overlay-content.flex.flex-column.flex-space-between\", [\n\t\t\tm(vnode.attrs.message),\n\t\t\tm(\n\t\t\t\t\".flex.justify-end.flex-wrap\",\n\t\t\t\tvnode.attrs.buttons.map((b) => m(Button, b)),\n\t\t\t),\n\t\t])\n\t}\n}\n\n/**\n * @param message What will be shown inside notification\n * @param closeButtonAttrs To define the close button in the notification\n * @param buttons The postpone button is automatically added and does not have to be passed from outside\n */\n\nexport function show(message: Component, closeButtonAttrs: Partial<ButtonAttrs>, buttons: Array<ButtonAttrs>) {\n\tnotificationQueue.push({\n\t\tmessage,\n\t\tbuttons,\n\t\tcloseButtonAttrs,\n\t})\n\n\tif (notificationQueue.length > 1) {\n\t\t// another notification is already visible. Next notification will be shown when closing current notification\n\t\treturn\n\t}\n\n\tshowNextNotification()\n}\n\nfunction showNextNotification() {\n\tconst { message, buttons, closeButtonAttrs } = notificationQueue[0]\n\tcurrentAnimationTimeout = null\n\tconst width = window.innerWidth\n\tconst margin = (width - Math.min(400, width)) / 2\n\tconst allButtons = buttons.slice()\n\tconst overlayRect = {\n\t\ttop: px(0),\n\t\tleft: px(margin),\n\t\tright: px(margin),\n\t}\n\tconst closeFunction = displayOverlay(\n\t\t() => overlayRect,\n\t\t{\n\t\t\tview: () =>\n\t\t\t\tm(NotificationOverlay, {\n\t\t\t\t\tmessage,\n\t\t\t\t\tbuttons: allButtons,\n\t\t\t\t}),\n\t\t},\n\t\t(dom) => transform(TransformEnum.TranslateY, -dom.offsetHeight, 0),\n\t\t(dom) => transform(TransformEnum.TranslateY, 0, -dom.offsetHeight),\n\t)\n\n\tconst closeAndOpenNext = () => {\n\t\tif (currentAnimationTimeout !== null) {\n\t\t\treturn\n\t\t}\n\n\t\tcloseFunction()\n\t\tnotificationQueue.shift()\n\n\t\tif (notificationQueue.length > 0) {\n\t\t\tcurrentAnimationTimeout = setTimeout(showNextNotification, 2 * DefaultAnimationTime)\n\t\t}\n\t}\n\n\t// close the notification by default when pressing any button\n\tallButtons.forEach((b) => {\n\t\tconst originClickHandler: clickHandler | undefined = b.click\n\n\t\tb.click = (e, dom) => {\n\t\t\toriginClickHandler?.(e, dom)\n\t\t\tcloseAndOpenNext()\n\t\t}\n\t})\n\t// add the postpone button\n\tconst closeFinalAttrs: ButtonAttrs = Object.assign(\n\t\t{},\n\t\t{\n\t\t\tlabel: \"close_alt\",\n\t\t\tclick: closeAndOpenNext,\n\t\t\ttype: ButtonType.Secondary,\n\t\t},\n\t\tcloseButtonAttrs,\n\t)\n\n\tcloseFinalAttrs.click = (e, dom) => {\n\t\tcloseButtonAttrs.click && closeButtonAttrs.click(e, dom)\n\t\tcloseAndOpenNext()\n\t}\n\n\tallButtons.unshift(closeFinalAttrs)\n\tm.redraw()\n}\n","import m, { Component, Vnode } from \"mithril\"\n\nexport type ProgressBarAttrs = {\n\tprogress: number\n}\n\nexport const PROGRESS_DONE = 1\n\n/**\n * a progress bar that takes a progress value and displays it as\n * a portion of its containers width\n */\nexport class ProgressBar implements Component<ProgressBarAttrs> {\n\tprivate lastProgress: number | null = null\n\n\tview(vnode: Vnode<ProgressBarAttrs>) {\n\t\tconst a = vnode.attrs\n\t\tif (this.lastProgress === null && a.progress >= PROGRESS_DONE) {\n\t\t\t// no need to draw anything if we went from 0 to 100 real quick\n\t\t\treturn null\n\t\t}\n\n\t\tif (this.lastProgress !== null && this.lastProgress >= PROGRESS_DONE) {\n\t\t\t// on the last redraw, we were done\n\t\t\t// so we can start to remove now\n\t\t\treturn null\n\t\t}\n\t\tif (a.progress >= PROGRESS_DONE) {\n\t\t\t// schedule the removal redraw now because\n\t\t\t// we might not get another redraw for a while\n\t\t\t// otherwise (since progress is done)\n\t\t\tm.redraw()\n\t\t}\n\n\t\tthis.lastProgress = a.progress\n\t\treturn m(\".abs.accent-bg\", {\n\t\t\tonbeforeremove: (vn) =>\n\t\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\t\tvn.dom.addEventListener(\"transitionend\", () => {\n\t\t\t\t\t\tthis.lastProgress = null\n\t\t\t\t\t\tresolve()\n\t\t\t\t\t})\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tthis.lastProgress = null\n\t\t\t\t\t\tresolve()\n\t\t\t\t\t}, 500)\n\t\t\t\t}),\n\t\t\tstyle: {\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\ttransition: \"width 500ms\",\n\t\t\t\twidth: a.progress * 100 + \"%\",\n\t\t\t\theight: \"2px\",\n\t\t\t},\n\t\t})\n\t}\n}\n","import { PROGRESS_DONE } from \"./ProgressBar.js\"\nimport Stream from \"mithril/stream\"\nimport { WsConnectionState } from \"../../api/main/WorkerClient.js\"\nimport { ExposedCacheStorage } from \"../../api/worker/rest/DefaultEntityRestCache.js\"\nimport { PageContextLoginListener } from \"../../api/main/PageContextLoginListener.js\"\nimport { LoginController } from \"../../api/main/LoginController.js\"\nimport { OfflineIndicatorAttrs, OfflineIndicatorState } from \"./OfflineIndicator.js\"\nimport { WebsocketConnectivityModel } from \"../../misc/WebsocketConnectivityModel.js\"\nimport { ProgressTracker } from \"../../api/main/ProgressTracker.js\"\n\n/**\n * the offline indicator must take into account information\n * from multiple different sources:\n * * ws connection state (connected, not connected) from the worker\n * * login state (logged out, partial login, full login)\n * * sync progress\n * * last sync time\n *\n * the state necessary to determine the right indicator state from\n * previous updates from these information sources\n * is maintained in this class\n */\nexport class OfflineIndicatorViewModel {\n\tprivate lastProgress: number = PROGRESS_DONE\n\tprivate lastWsState: WsConnectionState = WsConnectionState.connecting\n\tprivate lastUpdate: Date | null = null\n\t/**\n\t * keeping this prevents flashing misleading states during login when\n\t * the full login succeeded but the ws connection attempt didn't\n\t * succeed or fail yet.\n\t * wsState is \"connecting\" both during first connect attempt and after we\n\t * disconnected.\n\t **/\n\tprivate wsWasConnectedBefore: boolean = false\n\n\tconstructor(\n\t\tprivate readonly cacheStorage: ExposedCacheStorage,\n\t\tprivate readonly loginListener: PageContextLoginListener,\n\t\tprivate readonly connectivityModel: WebsocketConnectivityModel,\n\t\tprivate readonly logins: LoginController,\n\t\tprogressTracker: ProgressTracker,\n\t\tprivate readonly cb: () => void,\n\t) {\n\t\tlogins.waitForFullLogin().then(() => this.cb())\n\t\tthis.setProgressUpdateStream(progressTracker.onProgressUpdate)\n\t\tthis.setWsStateStream(this.connectivityModel.wsConnection())\n\t}\n\n\tprivate setProgressUpdateStream(progressStream: Stream<number>): void {\n\t\tprogressStream.map((progress) => this.onProgressUpdate(progress))\n\t\tthis.onProgressUpdate(progressStream())\n\t}\n\n\tprivate setWsStateStream(wsStream: Stream<WsConnectionState>): void {\n\t\twsStream.map((state) => {\n\t\t\tthis.onWsStateChange(state)\n\t\t})\n\t\tthis.onWsStateChange(wsStream()).then()\n\t}\n\n\tprivate onProgressUpdate(progress: number): void {\n\t\tthis.lastProgress = progress\n\t\tthis.cb()\n\t}\n\n\tprivate async onWsStateChange(newState: WsConnectionState): Promise<void> {\n\t\tthis.lastWsState = newState\n\t\tif (newState !== WsConnectionState.connected) {\n\t\t\tconst lastUpdate = await this.cacheStorage!.getLastUpdateTime()\n\t\t\tswitch (lastUpdate.type) {\n\t\t\t\tcase \"recorded\":\n\t\t\t\t\tthis.lastUpdate = new Date(lastUpdate.time)\n\t\t\t\t\tbreak\n\t\t\t\tcase \"never\":\n\t\t\t\t// We can get into uninitialized state after temporary login e.g. during signup\n\t\t\t\tcase \"uninitialized\":\n\t\t\t\t\tthis.lastUpdate = null\n\t\t\t\t\tthis.wsWasConnectedBefore = false\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t} else {\n\t\t\tthis.wsWasConnectedBefore = true\n\t\t}\n\t\tthis.cb()\n\t}\n\n\tgetCurrentAttrs(): OfflineIndicatorAttrs {\n\t\tif (this.logins.isFullyLoggedIn() && this.wsWasConnectedBefore) {\n\t\t\tif (this.lastWsState === WsConnectionState.connected) {\n\t\t\t\t// normal, full login with a connected websocket\n\t\t\t\tif (this.lastProgress < PROGRESS_DONE) {\n\t\t\t\t\treturn { state: OfflineIndicatorState.Synchronizing, progress: this.lastProgress }\n\t\t\t\t} else {\n\t\t\t\t\treturn { state: OfflineIndicatorState.Online }\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// normal, full login with a disconnected websocket\n\t\t\t\treturn {\n\t\t\t\t\tstate: OfflineIndicatorState.Offline,\n\t\t\t\t\tlastUpdate: this.lastUpdate,\n\t\t\t\t\treconnectAction: () => {\n\t\t\t\t\t\tconsole.log(\"try reconnect ws\")\n\t\t\t\t\t\tthis.connectivityModel!.tryReconnect(true, true, 2000)\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// either not fully logged in or the websocket was not connected before\n\t\t\t// in cases where the indicator is visible, this is just offline login.\n\t\t\tif (this.loginListener.getFullLoginFailed()) {\n\t\t\t\treturn {\n\t\t\t\t\tstate: OfflineIndicatorState.Offline,\n\t\t\t\t\tlastUpdate: this.lastUpdate,\n\t\t\t\t\treconnectAction: () => {\n\t\t\t\t\t\tconsole.log(\"try full login\")\n\t\t\t\t\t\tthis.logins!.retryAsyncLogin().finally(() => this.cb())\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// partially logged in, but the last login attempt didn't fail yet\n\t\t\t\treturn { state: OfflineIndicatorState.Connecting }\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t * get the current progress for sync operations\n\t */\n\tgetProgress(): number {\n\t\t//getting the progress like this ensures that\n\t\t// the progress bar and sync percentage are consistent\n\t\tconst a = this.getCurrentAttrs()\n\t\treturn a.state === OfflineIndicatorState.Synchronizing && this.logins?.isUserLoggedIn() ? a.progress : 1\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { BootIcons } from \"./icons/BootIcons\"\nimport { Icon } from \"./Icon\"\nimport { addFlash, removeFlash } from \"./Flash\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\n\nexport type CheckboxAttrs = {\n\tlabel: lazy<string | Children>\n\tchecked: boolean\n\tonChecked: (value: boolean) => unknown\n\thelpLabel?: TranslationKey | lazy<string>\n\tdisabled?: boolean\n}\n\nexport class Checkbox implements Component<CheckboxAttrs> {\n\tprivate focused: boolean\n\tprivate _domInput: HTMLElement | null = null\n\tprivate _domIcon: HTMLElement | null = null\n\n\tconstructor() {\n\t\tthis.focused = false\n\t}\n\n\tview(vnode: Vnode<CheckboxAttrs>): Children {\n\t\tconst a = vnode.attrs\n\t\tconst helpLabel = a.helpLabel ? m(\"small.block.content-fg\", lang.getMaybeLazy(a.helpLabel)) : []\n\t\treturn m(\n\t\t\t\".click.pt\",\n\t\t\t{\n\t\t\t\tonclick: (e: MouseEvent) => {\n\t\t\t\t\tif (e.target !== this._domInput) {\n\t\t\t\t\t\tthis.toggle(e, a) // event is bubbling in IE besides we invoke e.stopPropagation()\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t\t[\n\t\t\t\tm(\n\t\t\t\t\t\".wrapper.flex.items-center\",\n\t\t\t\t\t{\n\t\t\t\t\t\toncreate: (vnode) => addFlash(vnode.dom),\n\t\t\t\t\t\tonremove: (vnode) => removeFlash(vnode.dom),\n\t\t\t\t\t},\n\t\t\t\t\t[\n\t\t\t\t\t\t// the real checkbox is transparent and only used to allow keyboard focusing and selection\n\t\t\t\t\t\tm(\"input[type=checkbox]\", {\n\t\t\t\t\t\t\toncreate: (vnode) => (this._domInput = vnode.dom as HTMLElement),\n\t\t\t\t\t\t\tonchange: (e: Event) => this.toggle(e, a),\n\t\t\t\t\t\t\tchecked: a.checked,\n\t\t\t\t\t\t\tonfocus: () => (this.focused = true),\n\t\t\t\t\t\t\tonblur: () => (this.focused = false),\n\t\t\t\t\t\t\tonremove: (e) => {\n\t\t\t\t\t\t\t\t// workaround for chrome error on login with return shortcut \"Error: Failed to execute 'removeChild' on 'Node': The node to be removed is no longer a child of this node. Perhaps it was moved in a 'blur' event handler?\"\n\t\t\t\t\t\t\t\t// TODO test if still needed with mithril 1.1.1\n\t\t\t\t\t\t\t\tif (this._domInput) this._domInput.onblur = null\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t\t\t\tz_index: -1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tm(Icon, {\n\t\t\t\t\t\t\ticon: a.checked ? BootIcons.CheckboxSelected : BootIcons.Checkbox,\n\t\t\t\t\t\t\tclass: this.focused ? \"svg-content-accent-fg\" : \"svg-content-fg\",\n\t\t\t\t\t\t\toncreate: (vnode) => (this._domIcon = vnode.dom as HTMLElement),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tm(\n\t\t\t\t\t\t\t\".pl\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tclass: this.focused ? \"content-accent-fg\" : \"content-fg\",\n\t\t\t\t\t\t\t\tonclick: (e: MouseEvent) => {\n\t\t\t\t\t\t\t\t\t// if the label contains a link, then stop the event so that the checkbox doesnt get toggled upon clicking\n\t\t\t\t\t\t\t\t\t// we still allow it to be checked if they click on the non-link part of the label\n\t\t\t\t\t\t\t\t\tif (e.target instanceof HTMLElement && e.target.tagName.toUpperCase() === \"A\") {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation()\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ta.label(),\n\t\t\t\t\t\t),\n\t\t\t\t\t],\n\t\t\t\t),\n\t\t\t\thelpLabel,\n\t\t\t],\n\t\t)\n\t}\n\n\ttoggle(event: Event, attrs: CheckboxAttrs) {\n\t\tif (!attrs.disabled) {\n\t\t\tattrs.onChecked(!attrs.checked)\n\t\t}\n\n\t\tevent.stopPropagation()\n\n\t\tif (this._domInput) {\n\t\t\tthis._domInput.focus()\n\t\t}\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport { addFlash, removeFlash } from \"./Flash\"\nimport { Icon } from \"./Icon\"\nimport { Icons } from \"./icons/Icons\"\nimport { BootIcons } from \"./icons/BootIcons\"\nimport { theme } from \"../theme\"\nimport { px } from \"../size\"\nimport { DefaultAnimationTime } from \"../animation/Animations\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { assertNotNull } from \"@tutao/tutanota-utils\"\n\nexport type ExpanderAttrs = {\n\tlabel: TranslationKey | lazy<string>\n\texpanded: boolean\n\tonExpandedChange: (value: boolean) => unknown\n\tshowWarning?: boolean\n\tcolor?: string\n\tstyle?: Record<string, any>\n}\nexport type ExpanderPanelAttrs = {\n\texpanded: boolean\n}\n\nexport class ExpanderButton implements Component<ExpanderAttrs> {\n\tview(vnode: Vnode<ExpanderAttrs>): Children {\n\t\tconst a = vnode.attrs\n\t\treturn m(\".limit-width\", [\n\t\t\tm(\n\t\t\t\t\"button.expander.bg-transparent.pt-s.hover-ul.limit-width.flex.items-center\",\n\t\t\t\t{\n\t\t\t\t\tstyle: a.style,\n\t\t\t\t\tonclick: (event: MouseEvent) => {\n\t\t\t\t\t\ta.onExpandedChange(!a.expanded)\n\t\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\t},\n\t\t\t\t\toncreate: (vnode) => addFlash(vnode.dom),\n\t\t\t\t\tonremove: (vnode) => removeFlash(vnode.dom),\n\t\t\t\t\t\"aria-expanded\": String(a.expanded),\n\t\t\t\t},\n\t\t\t\t[\n\t\t\t\t\ta.showWarning\n\t\t\t\t\t\t? m(Icon, {\n\t\t\t\t\t\t\t\ticon: Icons.Warning,\n\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\tfill: a.color ? a.color : theme.content_button,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t  })\n\t\t\t\t\t\t: null,\n\t\t\t\t\tm(\n\t\t\t\t\t\t\"small.b.text-ellipsis\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\tcolor: a.color || theme.content_button,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tlang.getMaybeLazy(a.label).toUpperCase(),\n\t\t\t\t\t),\n\t\t\t\t\tm(Icon, {\n\t\t\t\t\t\ticon: BootIcons.Expand,\n\t\t\t\t\t\tclass: \"flex-center items-center\",\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tfill: a.color ? a.color : theme.content_button,\n\t\t\t\t\t\t\t\"margin-right\": px(-4),\n\t\t\t\t\t\t\t// icon is has 4px whitespace to the right,\n\t\t\t\t\t\t\ttransform: `rotateZ(${a.expanded ? 180 : 0}deg)`,\n\t\t\t\t\t\t\ttransition: `transform ${DefaultAnimationTime}ms`,\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\t}\n}\n\n/**\n * Panel which shows or hides content depending on the attrs.expanded and animates transitions.\n */\nexport class ExpanderPanel implements Component<ExpanderPanelAttrs> {\n\tchildDiv: HTMLElement | null = null\n\t// There are some cases where the child div will be added to and a redraw won't be triggered, in which case\n\t// the expander panel won't update until some kind of interaction happens.\n\t// Unfortunately no one knows what these cases are anymore besides some direct mutation.\n\tobserver: MutationObserver | null = null\n\t// We calculate the height manually because we need concrete values for the transition (can't just transition from 0px to 100%)\n\tlastCalculatedHeight: number | null = null\n\t// We remove the children from the DOM to take them out of the taborder. Setting \"tabindex = -1\" on the element will not work because\n\t// it does not apply to any children\n\tchildrenInDom: boolean | null = null\n\tsetChildrenInDomTimeout: TimeoutID | null\n\n\toninit(vnode: Vnode<ExpanderPanelAttrs>) {\n\t\tthis.childrenInDom = vnode.attrs.expanded\n\t\tthis.observer = new MutationObserver((mutations) => {\n\t\t\t// redraw if a child has been added that won't be getting displayed\n\t\t\tif (this.childDiv && this.childDiv.getBoundingClientRect().height !== this.lastCalculatedHeight) {\n\t\t\t\tm.redraw()\n\t\t\t}\n\t\t})\n\t}\n\n\tonbeforeupdate(vnode: Vnode<ExpanderPanelAttrs>, old: Vnode<ExpanderPanelAttrs>): boolean {\n\t\tconst oldExpanded = old.attrs.expanded\n\t\tconst currentExpanded = vnode.attrs.expanded\n\n\t\tif (oldExpanded !== currentExpanded) {\n\t\t\tthis.handleExpansionStateChanged(currentExpanded)\n\t\t}\n\n\t\treturn true\n\t}\n\n\tview(vnode: Vnode<ExpanderPanelAttrs>): Children {\n\t\tconst expanded = vnode.attrs.expanded\n\t\t// getBoundingClientRect() gives us the correct size, with a fraction\n\t\tthis.lastCalculatedHeight = this.childDiv?.getBoundingClientRect().height ?? 0\n\t\treturn m(\n\t\t\t\".expander-panel\",\n\t\t\t// We want overflow while expanded in some specific cases like dropdowns, but generally we don't want it because we want to clip our children\n\t\t\t// for animation and sizing, so we enable it only when expanded\n\t\t\tm(\n\t\t\t\texpanded ? \"div\" : \".overflow-hidden\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\topacity: expanded ? \"1\" : \"0\",\n\t\t\t\t\t\theight: expanded ? `${this.lastCalculatedHeight}px` : \"0px\",\n\t\t\t\t\t\ttransition: `opacity ${DefaultAnimationTime}ms ease-out, height ${DefaultAnimationTime}ms ease-out`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t// we use this wrapper to measure the child reliably\n\t\t\t\t// just a marker class\n\t\t\t\tm(\n\t\t\t\t\t\".expander-child-wrapper\",\n\t\t\t\t\t{\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t// one way to deal with collapsible margins.\n\t\t\t\t\t\t\t// CSS is fun in the way that it likes to collapse some vertical margins in some cases.\n\t\t\t\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing\n\t\t\t\t\t\t\t// One of such cases is when there's no content between the parent and the child and no margins or borders.\n\t\t\t\t\t\t\t// So assuming that the child we want to display inside has a margin-top set it would actually overflow our child-wrapper on the\n\t\t\t\t\t\t\t// top. Which means all our sizing is wrong.\n\t\t\t\t\t\t\t// There are few ways to prevent this, one of them is `display: flow-root`. It should have no side effects except for some\n\t\t\t\t\t\t\t// `display: float` items but if you are using `float` still you have no one to blame but yourself.\n\t\t\t\t\t\t\t// we could set `overflow: hidden` here instead but we do measure this element so we probably shouldn't\n\t\t\t\t\t\t\tdisplay: \"flow-root\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\t\tthis.childDiv = vnode.dom as HTMLElement\n\t\t\t\t\t\t\tassertNotNull(this.observer).observe(this.childDiv, {\n\t\t\t\t\t\t\t\tchildList: true,\n\t\t\t\t\t\t\t\tsubtree: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonremove: () => {\n\t\t\t\t\t\t\tthis.observer?.disconnect()\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tthis.childrenInDom ? vnode.children : null,\n\t\t\t\t),\n\t\t\t),\n\t\t)\n\t}\n\n\tprivate handleExpansionStateChanged(expanded: boolean) {\n\t\tclearTimeout(this.setChildrenInDomTimeout)\n\n\t\tif (expanded) {\n\t\t\tthis.childrenInDom = true\n\t\t} else {\n\t\t\tthis.setChildrenInDomTimeout = setTimeout(() => {\n\t\t\t\tthis.childrenInDom = false\n\t\t\t\tm.redraw()\n\t\t\t}, DefaultAnimationTime)\n\t\t}\n\t}\n}\n","export const FontIcons = Object.freeze({\n\tReply: `\\uea01`,\n\tReplyAll: `\\uea02`,\n\tWarning: `\\uea03`,\n\tForward: `\\uea04`,\n\tAttach: `\\uea05`,\n\tFolder: `\\uea06`,\n\tInbox: `\\uea07`,\n\tSent: `\\uea08`,\n\tTrash: `\\uea09`,\n\tArchive: `\\uea0a`,\n\tSpam: `\\uea0b`,\n\tDraft: `\\uea0c`,\n\tEdit: `\\uea0d`,\n\tConfidential: `\\uea0e`,\n\tCheckbox: `\\uea0f`,\n} as const)\n","import m, { Children, ClassComponent, Vnode } from \"mithril\"\nimport { AriaLandmarks, landmarkAttrs } from \"../AriaUtils.js\"\nimport { px, size, size as sizes } from \"../size.js\"\nimport { theme } from \"../theme.js\"\n\n/**\n * Base layout for the header in desktop layout.\n */\nexport class DesktopBaseHeader implements ClassComponent {\n\tview(vnode: Vnode): Children {\n\t\treturn m(\".header-nav.flex.items-center.rel\", [this.renderLogo(), vnode.children])\n\t}\n\n\tprivate renderLogo() {\n\t\treturn m(\n\t\t\t\".logo-height\",\n\t\t\t{\n\t\t\t\t...landmarkAttrs(AriaLandmarks.Banner, \"Tutanota logo\"),\n\t\t\t\tstyle: {\n\t\t\t\t\t\"margin-left\": px(sizes.drawer_menu_width + size.hpad + size.hpad_button),\n\t\t\t\t},\n\t\t\t},\n\t\t\tm.trust(theme.logo),\n\t\t)\n\t}\n}\n","import m, { Child, Component, Vnode } from \"mithril\"\nimport { AriaLandmarks, landmarkAttrs } from \"../AriaUtils\"\nimport { LayerType } from \"../../RootView\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\n\nassertMainOrNode()\n\nexport const enum ColumnType {\n\tBackground = 1,\n\tForeground = 0,\n}\n\ntype HeaderCenter = {\n\tleft: Child\n\tmiddle: string\n\tright: Child\n}\ntype Attrs = {\n\trightBorder?: boolean\n}\n\nexport class ViewColumn implements Component<Attrs> {\n\tcomponent: Component\n\tcolumnType: ColumnType\n\tminWidth: number\n\tmaxWidth: number\n\theaderCenter: lazy<string | HeaderCenter>\n\tariaLabel: lazy<string> | null\n\twidth: number\n\toffset: number // offset to the left\n\n\t// not private because used by ViewSlider\n\t_domColumn: HTMLElement | null = null\n\tview: Component<Attrs>[\"view\"]\n\tisInForeground: boolean\n\tvisible: boolean\n\tprivate _ariaRole: AriaLandmarks | null = null\n\n\t/**\n\t * Create a view column.\n\t * @param component The component that is rendered as this column\n\t * @param columnType The type of the view column.\n\t * @param minWidth The minimum allowed width for the view column.\n\t * @param maxWidth The maximum allowed width for the view column.\n\t */\n\tconstructor(\n\t\tcomponent: Component,\n\t\tcolumnType: ColumnType,\n\t\tminWidth: number,\n\t\tmaxWidth: number,\n\t\theaderCenter?: lazy<string | HeaderCenter>,\n\t\tariaLabel?: lazy<string>,\n\t) {\n\t\tthis.component = component\n\t\tthis.columnType = columnType\n\t\tthis.minWidth = minWidth\n\t\tthis.maxWidth = maxWidth\n\n\t\tthis.headerCenter = headerCenter || (() => \"\")\n\n\t\tthis.ariaLabel = ariaLabel ?? null\n\t\tthis.width = minWidth\n\t\tthis.offset = 0\n\t\tthis.isInForeground = false\n\t\tthis.visible = false\n\n\t\tthis.view = (vnode: Vnode<Attrs>) => {\n\t\t\tconst zIndex = !this.visible && this.columnType === ColumnType.Foreground ? LayerType.ForegroundMenu + 1 : \"\"\n\t\t\tconst landmark = this._ariaRole ? landmarkAttrs(this._ariaRole, this.ariaLabel ? this.ariaLabel() : this.getTitle()) : {}\n\t\t\treturn m(\n\t\t\t\t\".view-column.overflow-x-hidden.fill-absolute\",\n\t\t\t\t{\n\t\t\t\t\t...landmark,\n\t\t\t\t\t\"aria-hidden\": this.visible || this.isInForeground ? \"false\" : \"true\",\n\t\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t\tthis._domColumn = vnode.dom as HTMLElement\n\t\t\t\t\t\tthis._domColumn.style.transform =\n\t\t\t\t\t\t\tthis.columnType === ColumnType.Foreground ? \"translateX(\" + this.getOffsetForeground(this.isInForeground) + \"px)\" : \"\"\n\n\t\t\t\t\t\tif (this._ariaRole === AriaLandmarks.Main) {\n\t\t\t\t\t\t\tthis.focus()\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tzIndex,\n\t\t\t\t\t\twidth: this.width + \"px\",\n\t\t\t\t\t\tleft: this.offset + \"px\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tm(this.component),\n\t\t\t)\n\t\t}\n\t}\n\n\tsetWidth(width: number) {\n\t\tthis.width = width\n\t}\n\n\tsetRole(landmark: AriaLandmarks | null) {\n\t\tthis._ariaRole = landmark\n\t}\n\n\tgetWidth(): number {\n\t\treturn this.width\n\t}\n\n\tgetTitle(): string {\n\t\tconst center = this.headerCenter()\n\t\treturn typeof center === \"string\" ? center : center.middle\n\t}\n\n\tgetOffsetForeground(foregroundState: boolean): number {\n\t\tif (this.visible || foregroundState) {\n\t\t\treturn 0\n\t\t} else {\n\t\t\treturn -this.width\n\t\t}\n\t}\n\n\tfocus() {\n\t\tthis._domColumn && this._domColumn.focus()\n\t}\n}\n","import m, { Child, Children, Component, Vnode } from \"mithril\"\nimport { AriaLandmarks, landmarkAttrs } from \"../AriaUtils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\n\nassertMainOrNode()\nexport type Attrs = void\n\nexport class NavBar implements Component<Attrs> {\n\tview({ children }: Vnode<Attrs>): Children {\n\t\treturn m(\n\t\t\t\"nav.nav-bar.flex-end\",\n\t\t\tlandmarkAttrs(AriaLandmarks.Navigation, \"top\"),\n\t\t\t(children as Array<Child>).map((child) => m(\".plr-nav-button\", child)),\n\t\t)\n\t}\n}\n","import m, { Children, Component, RouteLinkAttrs, Vnode } from \"mithril\"\nimport { handleUncaughtError } from \"../../misc/ErrorHandler\"\nimport { px, size } from \"../size\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { lazyStringValue, neverNull } from \"@tutao/tutanota-utils\"\nimport type { lazyIcon } from \"./Icon\"\nimport { Icon } from \"./Icon\"\nimport { theme } from \"../theme\"\nimport { styles } from \"../styles\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport { Keys } from \"../../api/common/TutanotaConstants\"\nimport { isKeyPressed } from \"../../misc/KeyManager\"\nimport type { dropHandler } from \"./GuiUtils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { stateBgHover } from \"../builtinThemes.js\"\n\nassertMainOrNode()\nexport type NavButtonAttrs = {\n\tlabel: TranslationKey | lazy<string>\n\ticon?: lazyIcon\n\thref: string | lazy<string>\n\tisSelectedPrefix?: string | boolean\n\tclick?: (event: Event, dom: HTMLElement) => unknown\n\tcolors?: NavButtonColor\n\tdropHandler?: dropHandler\n\thideLabel?: boolean\n\tvertical?: boolean\n\tfontSize?: number\n\tsmall?: boolean\n\tcentred?: boolean\n\tleftInjection?: () => Children\n\tdisableHoverBackground?: boolean\n\tdisabled?: boolean\n\tpersistentBackground?: boolean\n\tonfocus?: () => unknown\n\tonblur?: () => unknown\n}\n\nexport class NavButton implements Component<NavButtonAttrs> {\n\tprivate _domButton!: HTMLElement\n\tprivate _draggedOver: boolean\n\tprivate _dropCounter: number // we also get drag enter/leave events from subelements, so we need to count to know when the drag leaves this button\n\n\tconstructor() {\n\t\tthis._draggedOver = false\n\t\tthis._dropCounter = 0\n\t}\n\n\tview(vnode: Vnode<NavButtonAttrs>): Children {\n\t\tconst a = vnode.attrs\n\n\t\tconst linkAttrs = this.createButtonAttributes(a)\n\t\tconst icon = a.icon?.()\n\t\tconst children = [\n\t\t\ta.leftInjection?.() ?? null,\n\t\t\ticon\n\t\t\t\t? m(Icon, {\n\t\t\t\t\t\ticon,\n\t\t\t\t\t\tclass: this._getIconClass(a),\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tfill: isNavButtonSelected(a) || this._draggedOver ? getColors(a.colors).button_selected : getColors(a.colors).button,\n\t\t\t\t\t\t},\n\t\t\t\t  })\n\t\t\t\t: null,\n\t\t\t!a.hideLabel ? m(\"span.label.click.text-ellipsis\" + (!a.vertical && icon ? \".pl-m\" : \"\"), this.getLabel(a.label)) : null,\n\t\t]\n\n\t\t// allow nav button without label for registration button on mobile devices\n\t\tif (this._isExternalUrl(a.href)) {\n\t\t\treturn m(this._getNavButtonClass(a), linkAttrs, children)\n\t\t} else {\n\t\t\treturn m(m.route.Link, linkAttrs, children)\n\t\t}\n\t}\n\n\tgetLabel(label: TranslationKey | lazy<string>): string {\n\t\treturn lang.getMaybeLazy(label)\n\t}\n\n\t_getUrl(href: string | lazy<string>): string {\n\t\treturn lazyStringValue(href)\n\t}\n\n\t_getNavButtonClass(a: NavButtonAttrs): string {\n\t\treturn (\n\t\t\t\"a.nav-button.noselect.flex-no-shrink.items-center.click.plr-button.no-text-decoration.button-height.border-radius\" +\n\t\t\t(a.vertical ? \".col\" : \"\") +\n\t\t\t(!a.centred ? \".flex-start\" : \".flex-center\") +\n\t\t\t(a.disableHoverBackground ? \"\" : \".state-bg\") +\n\t\t\t(a.disabled ? \".no-hover\" : \"\")\n\t\t)\n\t}\n\n\t_getIconClass(a: NavButtonAttrs): string {\n\t\tconst isSelected = isNavButtonSelected(a)\n\n\t\tif (a.colors === NavButtonColor.Header && !styles.isDesktopLayout()) {\n\t\t\treturn \"flex-end items-center icon-xl\" + (isSelected ? \" selected\" : \"\")\n\t\t} else if (a.small === true) {\n\t\t\treturn \"flex-center items-center icon\" + (isSelected ? \" selected\" : \"\")\n\t\t} else {\n\t\t\treturn \"flex-center items-center icon-large\" + (isSelected ? \" selected\" : \"\")\n\t\t}\n\t}\n\n\t_isExternalUrl(href: string | lazy<string>): boolean {\n\t\tlet url = this._getUrl(href)\n\n\t\treturn url != null ? url.indexOf(\"http\") === 0 : false\n\t}\n\n\tcreateButtonAttributes(a: NavButtonAttrs): RouteLinkAttrs {\n\t\tlet attr: RouteLinkAttrs = {\n\t\t\trole: \"button\",\n\t\t\t// role button for screen readers\n\t\t\thref: this._getUrl(a.href),\n\t\t\tstyle: {\n\t\t\t\tcolor: isNavButtonSelected(a) || this._draggedOver ? getColors(a.colors).button_selected : getColors(a.colors).button,\n\t\t\t\t\"font-size\": a.fontSize ? px(a.fontSize) : \"\",\n\t\t\t\tbackground: (isNavButtonSelected(a) && a.persistentBackground) || this._draggedOver ? stateBgHover : \"\",\n\t\t\t},\n\t\t\ttitle: this.getLabel(a.label),\n\t\t\ttarget: this._isExternalUrl(a.href) ? \"_blank\" : undefined,\n\t\t\tselector: this._getNavButtonClass(a),\n\t\t\tonclick: (e: MouseEvent) => this.click(e, a),\n\t\t\tonkeyup: (e: KeyboardEvent) => {\n\t\t\t\tif (isKeyPressed(e.keyCode, Keys.SPACE)) {\n\t\t\t\t\tthis.click(e, a)\n\t\t\t\t}\n\t\t\t},\n\t\t\tonfocus: a.onfocus,\n\t\t\tonblur: a.onblur,\n\t\t}\n\n\t\tif (a.dropHandler) {\n\t\t\tattr.ondragenter = (ev: DragEvent) => {\n\t\t\t\tthis._dropCounter++\n\t\t\t\tthis._draggedOver = true\n\t\t\t\tev.preventDefault()\n\t\t\t}\n\n\t\t\tattr.ondragleave = (ev: DragEvent) => {\n\t\t\t\tthis._dropCounter--\n\n\t\t\t\tif (this._dropCounter === 0) {\n\t\t\t\t\tthis._draggedOver = false\n\t\t\t\t}\n\n\t\t\t\tev.preventDefault()\n\t\t\t}\n\n\t\t\tattr.ondragover = (ev: DragEvent) => {\n\t\t\t\t// needed to allow dropping\n\t\t\t\tev.preventDefault()\n\t\t\t}\n\n\t\t\tattr.ondrop = (ev: DragEvent) => {\n\t\t\t\tthis._dropCounter = 0\n\t\t\t\tthis._draggedOver = false\n\t\t\t\tev.preventDefault()\n\n\t\t\t\tif (ev.dataTransfer?.getData(\"text\")) {\n\t\t\t\t\tneverNull(a.dropHandler)(ev.dataTransfer.getData(\"text\"))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn attr\n\t}\n\n\tclick(event: Event, a: NavButtonAttrs) {\n\t\tif (!this._isExternalUrl(a.href)) {\n\t\t\tm.route.set(this._getUrl(a.href))\n\n\t\t\ttry {\n\t\t\t\tif (a.click != null) {\n\t\t\t\t\ta.click(event, this._domButton)\n\t\t\t\t}\n\n\t\t\t\tevent.preventDefault()\n\t\t\t} catch (e) {\n\t\t\t\thandleUncaughtError(e)\n\t\t\t}\n\t\t}\n\t}\n\n\tgetHeight(): number {\n\t\treturn size.button_height\n\t}\n}\n\nexport const enum NavButtonColor {\n\tHeader = \"header\",\n\tNav = \"nav\",\n\tContent = \"content\",\n}\n\nfunction getColors(buttonColors: NavButtonColor | null | undefined) {\n\tswitch (buttonColors) {\n\t\tcase NavButtonColor.Header:\n\t\t\treturn {\n\t\t\t\tbutton: styles.isDesktopLayout() ? theme.header_button : theme.content_accent,\n\t\t\t\tbutton_selected: styles.isDesktopLayout() ? theme.header_button_selected : theme.content_accent,\n\t\t\t}\n\n\t\tcase NavButtonColor.Nav:\n\t\t\treturn {\n\t\t\t\tbutton: theme.navigation_button,\n\t\t\t\tbutton_selected: theme.navigation_button_selected,\n\t\t\t}\n\n\t\tdefault:\n\t\t\t// for nav buttons in the more dropdown menu\n\t\t\treturn {\n\t\t\t\tbutton: theme.content_button,\n\t\t\t\tbutton_selected: theme.content_button_selected,\n\t\t\t}\n\t}\n}\n\nexport function isNavButtonSelected(a: NavButtonAttrs): boolean {\n\tif (typeof a.isSelectedPrefix === \"boolean\") {\n\t\treturn a.isSelectedPrefix\n\t}\n\n\tconst selectedPrefix = a.isSelectedPrefix || lazyStringValue(a.href)\n\treturn isSelectedPrefix(selectedPrefix)\n}\n\nexport function isSelectedPrefix(href: string): boolean {\n\tconst current = m.route.get()\n\t// don't just check current.indexOf(buttonHref) because other buttons may also start with this href\n\treturn href !== \"\" && (current === href || current.indexOf(href + \"/\") === 0 || current.indexOf(href + \"?\") === 0)\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { theme } from \"../theme\"\nimport { isSameDayOfDate, noOp } from \"@tutao/tutanota-utils\"\nimport { lang } from \"../../misc/LanguageViewModel\"\n\nexport const enum OfflineIndicatorState {\n\tOffline = 0,\n\tConnecting = 1,\n\tSynchronizing = 2,\n\tOnline = 3,\n}\n\nexport type OfflineIndicatorAttrs =\n\t| { state: OfflineIndicatorState.Online }\n\t| { state: OfflineIndicatorState.Connecting }\n\t| { state: OfflineIndicatorState.Synchronizing; progress: number }\n\t| { state: OfflineIndicatorState.Offline; lastUpdate: Date | null; reconnectAction: () => void }\n\n/**\n * the first line of the offline indicator shows if we're offline or online and\n * adds action prompts (if any)\n * it's returned as a span so the consumer can decide how to layout it.\n */\nfunction attrToFirstLine(attr: OfflineIndicatorAttrs): Children {\n\tconst { state } = attr\n\tswitch (state) {\n\t\tcase OfflineIndicatorState.Online:\n\t\tcase OfflineIndicatorState.Synchronizing:\n\t\t\treturn m(\"span\", lang.get(\"online_label\"))\n\n\t\tcase OfflineIndicatorState.Offline:\n\t\t\treturn [m(\"span\", lang.get(\"offline_label\")), m(\"span.b.content-accent-fg.mlr-s\", lang.get(\"reconnect_action\"))]\n\t\tcase OfflineIndicatorState.Connecting:\n\t\t\treturn m(\"span\", lang.get(\"offline_label\"))\n\t}\n}\n\n/**\n * the second line provides additional information about the current state.\n * it's returned as a span so the consumer can decide how to layout it.\n */\nfunction attrToSecondLine(a: OfflineIndicatorAttrs): Children {\n\tswitch (a.state) {\n\t\tcase OfflineIndicatorState.Online:\n\t\t\treturn m(\"span\", lang.get(\"upToDate_label\"))\n\t\tcase OfflineIndicatorState.Offline:\n\t\t\tif (a.lastUpdate) {\n\t\t\t\treturn m(\"span\", lang.get(\"lastSync_label\", { \"{date}\": formatDate(a.lastUpdate) }))\n\t\t\t} else {\n\t\t\t\t// never synced, don't show last sync label\n\t\t\t\treturn null\n\t\t\t}\n\t\tcase OfflineIndicatorState.Synchronizing:\n\t\t\treturn m(\"span\", lang.get(\"synchronizing_label\", { \"{progress}\": formatPercentage(a.progress) }))\n\t\tcase OfflineIndicatorState.Connecting:\n\t\t\treturn m(\"span\", lang.get(\"reconnecting_label\"))\n\t}\n}\n\n/**\n * format a number as a percentage string with 0 = 0% and 1 = 100%\n */\nfunction formatPercentage(percentage: number): string {\n\treturn `${Math.round(percentage * 100)}%`\n}\n\n/*\n * format a date either as a time without date (if it's today) or\n * as a date without time\n */\nfunction formatDate(date: Date): string {\n\treturn isSameDayOfDate(new Date(), date) ? lang.formats.time.format(date) : lang.formats.simpleDate.format(date)\n}\n\nexport class OfflineIndicatorDesktop implements Component<OfflineIndicatorAttrs> {\n\tview(vnode: Vnode<OfflineIndicatorAttrs>): Children {\n\t\tconst a = vnode.attrs\n\t\treturn m(\n\t\t\t\"button.small.mlr-l.flex.col\",\n\t\t\t{\n\t\t\t\ttype: \"button\",\n\t\t\t\thref: \"#\",\n\t\t\t\ttabindex: \"0\",\n\t\t\t\trole: \"button\",\n\t\t\t\tonclick: a.state === OfflineIndicatorState.Offline ? a.reconnectAction : noOp,\n\t\t\t},\n\t\t\t[m(\"\", { color: theme.content_accent }, attrToFirstLine(a)), m(\"\", { color: theme.content_accent }, attrToSecondLine(a))],\n\t\t)\n\t}\n}\n\nexport class OfflineIndicatorMobile implements Component<OfflineIndicatorAttrs> {\n\tview({ attrs }: Vnode<OfflineIndicatorAttrs>): Children {\n\t\treturn m(\n\t\t\t\"button.small.center.mb-xs\",\n\t\t\t{\n\t\t\t\ttype: \"button\",\n\t\t\t\thref: \"#\",\n\t\t\t\ttabindex: \"0\",\n\t\t\t\trole: \"button\",\n\t\t\t\tonclick: attrs.state === OfflineIndicatorState.Offline ? attrs.reconnectAction : noOp,\n\t\t\t},\n\t\t\tattrToFirstLine(attrs),\n\t\t)\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { AllIcons, Icon } from \"../Icon.js\"\nimport { lang, TranslationText } from \"../../../misc/LanguageViewModel.js\"\nimport { ButtonColor, getColors } from \"../Button.js\"\nimport { ButtonSize } from \"../ButtonSize.js\"\n\nexport interface ToggleButtonAttrs {\n\ticon: AllIcons\n\ttitle: TranslationText\n\ttoggled: boolean\n\tonToggled: (selected: boolean, event: MouseEvent) => unknown\n\tcolors?: ButtonColor\n\tsize?: ButtonSize\n\ttoggledTitle?: TranslationText\n\tstyle?: Record<string, any>\n}\n\nexport class ToggleButton implements Component<ToggleButtonAttrs> {\n\tview({ attrs }: Vnode<ToggleButtonAttrs>): Children {\n\t\treturn m(\n\t\t\t\"button.toggle-button.state-bg\",\n\t\t\t{\n\t\t\t\ttitle: attrs.toggledTitle && attrs.toggled ? lang.getMaybeLazy(attrs.toggledTitle) : lang.getMaybeLazy(attrs.title),\n\t\t\t\tonclick: (e: MouseEvent) => attrs.onToggled(!attrs.toggled, e),\n\t\t\t\ttoggled: String(attrs.toggled),\n\t\t\t\tclass: attrs.size === ButtonSize.Compact ? \"compact\" : \"\",\n\t\t\t\t\"aria-pressed\": String(attrs.toggled),\n\t\t\t\tstyle: attrs.style,\n\t\t\t},\n\t\t\tm(Icon, {\n\t\t\t\ticon: attrs.icon,\n\t\t\t\tcontainer: \"div\",\n\t\t\t\tclass: \"center-h\",\n\t\t\t\tlarge: true,\n\t\t\t\tstyle: {\n\t\t\t\t\tfill: getColors(attrs.colors ?? ButtonColor.Content).button,\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\t}\n}\n","import { size } from \"../size\"\n\nexport const enum DirectionLock {\n\tHorizontal,\n\tVertical,\n}\n\nexport interface Coordinate2D {\n\tx: number\n\ty: number\n}\n\n/* Tool to detect swipe gestures on certain elements. */\nexport class SwipeHandler {\n\t/** uses clientX/clientY thus relative to view port */\n\tstartPos: Coordinate2D\n\ttouchArea: HTMLElement\n\tanimating: Promise<unknown>\n\tisAnimating: boolean = false\n\tdirectionLock: DirectionLock | null\n\n\tconstructor(touchArea: HTMLElement) {\n\t\tthis.startPos = {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t}\n\t\tthis.touchArea = touchArea\n\t\tthis.animating = Promise.resolve()\n\t\tthis.directionLock = null\n\t}\n\n\tattach() {\n\t\tthis.touchArea.addEventListener(\"touchstart\", this.onTouchStart, { passive: true })\n\t\t// does invoke prevent default\n\t\tthis.touchArea.addEventListener(\"touchmove\", this.onTouchMove, { passive: false })\n\t\tthis.touchArea.addEventListener(\"touchend\", this.onTouchEnd, { passive: true })\n\t}\n\n\tdetach() {\n\t\tthis.touchArea.removeEventListener(\"touchstart\", this.onTouchStart)\n\t\tthis.touchArea.removeEventListener(\"touchmove\", this.onTouchMove)\n\t\tthis.touchArea.removeEventListener(\"touchend\", this.onTouchEnd)\n\t}\n\n\tprivate readonly onTouchStart = (e: TouchEvent) => {\n\t\tthis.startPos = {\n\t\t\tx: e.touches[0].clientX,\n\t\t\ty: e.touches[0].clientY,\n\t\t}\n\t}\n\n\tprivate readonly onTouchMove = (e: TouchEvent) => {\n\t\tlet { x, y } = this.getDelta(e)\n\n\t\t// If we're either locked horizontally OR if we're not locked vertically but would like to lock horizontally, then lock horizontally\n\t\tif (\n\t\t\tthis.directionLock === DirectionLock.Horizontal ||\n\t\t\t(this.directionLock !== DirectionLock.Vertical && Math.abs(x) > Math.abs(y) && Math.abs(x) > 14)\n\t\t) {\n\t\t\tthis.directionLock = DirectionLock.Horizontal\n\t\t\t// Do not scroll the list\n\t\t\te.preventDefault()\n\n\t\t\tif (!this.isAnimating) {\n\t\t\t\tthis.onHorizontalDrag(x, y)\n\t\t\t} // If we don't have a vertical lock yet but we would like to have it, lock vertically\n\t\t} else if (this.directionLock !== DirectionLock.Vertical && Math.abs(y) > Math.abs(x) && Math.abs(y) > size.list_row_height) {\n\t\t\tthis.directionLock = DirectionLock.Vertical\n\n\t\t\tif (!this.isAnimating) {\n\t\t\t\t// Reset the row\n\t\t\t\twindow.requestAnimationFrame(() => {\n\t\t\t\t\tif (!this.isAnimating) {\n\t\t\t\t\t\tthis.reset({\n\t\t\t\t\t\t\tx,\n\t\t\t\t\t\t\ty,\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\t}\n\n\tprivate readonly onTouchEnd = (e: TouchEvent) => {\n\t\tthis.gestureEnd(e)\n\t}\n\n\tprivate gestureEnd(e: TouchEvent) {\n\t\tconst delta = this.getDelta(e)\n\n\t\tif (!this.isAnimating && this.directionLock === DirectionLock.Horizontal) {\n\t\t\t// Gesture is completed\n\t\t\tthis.animating = this.onHorizontalGestureCompleted(delta)\n\t\t\tthis.isAnimating = true\n\t\t} else if (!this.isAnimating) {\n\t\t\t// Gesture is not completed, reset row\n\t\t\tthis.animating = this.reset(delta)\n\t\t\tthis.isAnimating = true\n\t\t}\n\n\t\tthis.animating.then(() => (this.isAnimating = false))\n\t\tthis.directionLock = null\n\t}\n\n\tonHorizontalDrag(xDelta: number, yDelta: number) {\n\t\t// noOp\n\t}\n\n\tonHorizontalGestureCompleted(delta: { x: number; y: number }): Promise<unknown> {\n\t\t// noOp\n\t\treturn Promise.resolve()\n\t}\n\n\treset(delta: { x: number; y: number }): Promise<unknown> {\n\t\treturn Promise.resolve()\n\t}\n\n\tgetDelta(e: any): {\n\t\tx: number\n\t\ty: number\n\t} {\n\t\treturn {\n\t\t\tx: e.changedTouches[0].clientX - this.startPos.x,\n\t\t\ty: e.changedTouches[0].clientY - this.startPos.y,\n\t\t}\n\t}\n}\n","import { Coordinate2D, SwipeHandler } from \"./SwipeHandler.js\"\nimport { assertNotNull } from \"@tutao/tutanota-utils\"\nimport { animations, DefaultAnimationTime, opacity, transform, TransformEnum } from \"../animation/Animations.js\"\nimport { ease } from \"../animation/Easing.js\"\nimport { ListRow, ListSwipeDecision, ViewHolder } from \"./List.js\"\nimport { ACTION_DISTANCE } from \"./ListUtils.js\"\n\n/** Detects swipe gestures for list elements. On mobile some lists have actions on swiping, e.g. deleting an email. */\nexport class ListSwipeHandler<ElementType, VH extends ViewHolder<ElementType>> extends SwipeHandler {\n\tprivate virtualElement: ListRow<ElementType, VH> | null = null\n\tprivate xoffset!: number\n\n\tconstructor(\n\t\ttouchArea: HTMLElement,\n\t\tprivate readonly config: {\n\t\t\tdomSwipeSpacerLeft: () => HTMLElement\n\t\t\tdomSwipeSpacerRight: () => HTMLElement\n\t\t\twidth: () => number\n\t\t\tgetRowForPosition: (clientCoordiantes: Coordinate2D) => ListRow<ElementType, VH> | null\n\t\t\tonSwipeLeft: (entity: ElementType) => Promise<ListSwipeDecision>\n\t\t\tonSwipeRight: (entity: ElementType) => Promise<ListSwipeDecision>\n\t\t},\n\t) {\n\t\tsuper(touchArea)\n\t}\n\n\tonHorizontalDrag(xDelta: number, yDelta: number) {\n\t\tsuper.onHorizontalDrag(xDelta, yDelta)\n\t\t// get it *before* raf so that we don't pick an element after reset() again\n\t\tconst ve = this.getVirtualElement()\n\t\t// Animate the row with following touch\n\t\twindow.requestAnimationFrame(() => {\n\t\t\t// Do not animate the swipe gesture more than necessary\n\t\t\tthis.xoffset = xDelta < 0 ? Math.max(xDelta, -ACTION_DISTANCE) : Math.min(xDelta, ACTION_DISTANCE)\n\n\t\t\tif (!this.isAnimating && ve && ve.domElement && ve.entity) {\n\t\t\t\tve.domElement.style.transform = `translateX(${this.xoffset}px) translateY(${ve.top}px)`\n\t\t\t\tthis.config.domSwipeSpacerLeft().style.transform = `translateX(${this.xoffset - this.width()}px) translateY(${ve.top}px)`\n\t\t\t\tthis.config.domSwipeSpacerRight().style.transform = `\n\t\t\t\ttranslateX(${this.xoffset + this.width()}px) translateY(${ve.top}px)`\n\t\t\t}\n\t\t})\n\t}\n\n\tonHorizontalGestureCompleted(delta: { x: number; y: number }): Promise<unknown> {\n\t\tif (this.virtualElement && this.virtualElement.entity && Math.abs(delta.x) > ACTION_DISTANCE) {\n\t\t\t// the gesture is completed\n\t\t\treturn this.finish(this.virtualElement, this.virtualElement.entity, delta)\n\t\t} else {\n\t\t\treturn this.reset(delta)\n\t\t}\n\t}\n\n\tprivate async finish(\n\t\tvirtualElement: ListRow<ElementType, VH>,\n\t\tentity: ElementType,\n\t\tdelta: {\n\t\t\tx: number\n\t\t\ty: number\n\t\t},\n\t): Promise<unknown> {\n\t\tif (this.xoffset === 0) {\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tconst listTargetPosition = this.xoffset < 0 ? -this.width() : this.width()\n\n\t\t\tawait Promise.all([\n\t\t\t\t// animate swipe action to full width\n\t\t\t\tvirtualElement.domElement &&\n\t\t\t\t\tanimations.add(\n\t\t\t\t\t\tvirtualElement.domElement,\n\t\t\t\t\t\ttransform(TransformEnum.TranslateX, this.xoffset, listTargetPosition).chain(\n\t\t\t\t\t\t\tTransformEnum.TranslateY,\n\t\t\t\t\t\t\tvirtualElement.top,\n\t\t\t\t\t\t\tvirtualElement.top,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teasing: ease.inOut,\n\t\t\t\t\t\t\tduration: DefaultAnimationTime * 2,\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\tanimations.add(\n\t\t\t\t\tthis.config.domSwipeSpacerLeft(),\n\t\t\t\t\ttransform(TransformEnum.TranslateX, this.xoffset - this.width(), listTargetPosition - this.width()).chain(\n\t\t\t\t\t\tTransformEnum.TranslateY,\n\t\t\t\t\t\tvirtualElement.top,\n\t\t\t\t\t\tvirtualElement.top,\n\t\t\t\t\t),\n\t\t\t\t\t{\n\t\t\t\t\t\teasing: ease.inOut,\n\t\t\t\t\t\tduration: DefaultAnimationTime * 2,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tanimations.add(\n\t\t\t\t\tthis.config.domSwipeSpacerRight(),\n\t\t\t\t\ttransform(TransformEnum.TranslateX, this.xoffset + this.width(), listTargetPosition + this.width()).chain(\n\t\t\t\t\t\tTransformEnum.TranslateY,\n\t\t\t\t\t\tvirtualElement.top,\n\t\t\t\t\t\tvirtualElement.top,\n\t\t\t\t\t),\n\t\t\t\t\t{\n\t\t\t\t\t\teasing: ease.inOut,\n\t\t\t\t\t\tduration: DefaultAnimationTime * 2,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t])\n\n\t\t\tthis.xoffset = listTargetPosition\n\n\t\t\tlet swipeDecision: ListSwipeDecision\n\t\t\ttry {\n\t\t\t\tif (delta.x < 0) {\n\t\t\t\t\tswipeDecision = await this.config.onSwipeLeft(entity)\n\t\t\t\t} else {\n\t\t\t\t\tswipeDecision = await this.config.onSwipeRight(entity)\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(\"rejection in swipe action\", e)\n\t\t\t\tswipeDecision = ListSwipeDecision.Cancel\n\t\t\t}\n\n\t\t\tif (swipeDecision === ListSwipeDecision.Cancel) {\n\t\t\t\tawait this.reset(delta)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// fade out element\n\t\t\tthis.xoffset = 0\n\n\t\t\tif (virtualElement.domElement) {\n\t\t\t\tvirtualElement.domElement.style.transform = `translateX(${this.xoffset}px) translateY(${virtualElement.top}px)`\n\t\t\t}\n\n\t\t\tawait Promise.all([\n\t\t\t\tanimations.add(this.config.domSwipeSpacerLeft(), opacity(1, 0, true)),\n\t\t\t\tanimations.add(this.config.domSwipeSpacerRight(), opacity(1, 0, true)),\n\t\t\t])\n\n\t\t\t// set swipe element to initial configuration\n\t\t\t// with different zoom levels Blink does weird things and shows parts of elements that it shouldn't so we shift them around by a pixel\n\t\t\tthis.config.domSwipeSpacerLeft().style.transform = `translateX(${this.xoffset - this.width() - 1}px) translateY(${virtualElement.top}px)`\n\t\t\tthis.config.domSwipeSpacerRight().style.transform = `translateX(${this.xoffset + this.width() + 1}px) translateY(${virtualElement.top}px)`\n\t\t\tthis.config.domSwipeSpacerRight().style.opacity = \"\"\n\t\t\tthis.config.domSwipeSpacerLeft().style.opacity = \"\"\n\t\t} finally {\n\t\t\tthis.virtualElement = null\n\t\t}\n\t}\n\n\tprivate width() {\n\t\treturn this.config.width()\n\t}\n\n\tprivate getVirtualElement(): ListRow<ElementType, VH> {\n\t\tif (!this.virtualElement) {\n\t\t\t// touch coordinates are based on clientX so they are relative to the viewport and we need to adjust them by the position of the list\n\t\t\tthis.virtualElement = this.config.getRowForPosition(this.startPos)\n\t\t}\n\n\t\treturn assertNotNull(this.virtualElement)\n\t}\n\n\treset(delta: { x: number; y: number }): Promise<unknown> {\n\t\ttry {\n\t\t\tif (this.xoffset !== 0) {\n\t\t\t\tconst ve = this.virtualElement\n\n\t\t\t\tif (ve && ve.domElement && ve.entity) {\n\t\t\t\t\treturn Promise.all([\n\t\t\t\t\t\tanimations.add(ve.domElement, transform(TransformEnum.TranslateX, this.xoffset, 0).chain(TransformEnum.TranslateY, ve.top, ve.top), {\n\t\t\t\t\t\t\teasing: ease.inOut,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tanimations.add(\n\t\t\t\t\t\t\tthis.config.domSwipeSpacerLeft(),\n\t\t\t\t\t\t\ttransform(TransformEnum.TranslateX, this.xoffset - this.width(), -this.width()).chain(TransformEnum.TranslateY, ve.top, ve.top),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\teasing: ease.inOut,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tanimations.add(\n\t\t\t\t\t\t\tthis.config.domSwipeSpacerRight(),\n\t\t\t\t\t\t\ttransform(TransformEnum.TranslateX, this.xoffset + this.width(), this.width()).chain(TransformEnum.TranslateY, ve.top, ve.top),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\teasing: ease.inOut,\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}\n\n\t\t\t\tthis.xoffset = 0\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.virtualElement = null\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n}\n","import m, { Children, ClassComponent, Vnode, VnodeDOM } from \"mithril\"\nimport { debounce, memoized, numberRange } from \"@tutao/tutanota-utils\"\nimport { px, size } from \"../size.js\"\nimport { isKeyPressed } from \"../../misc/KeyManager.js\"\nimport { Keys, TabIndex } from \"../../api/common/TutanotaConstants.js\"\nimport { client } from \"../../misc/ClientDetector.js\"\nimport { progressIcon } from \"./Icon.js\"\nimport { Button, ButtonType } from \"./Button.js\"\nimport { ListSwipeHandler } from \"./ListSwipeHandler.js\"\nimport { applySafeAreaInsetMarginLR } from \"../HtmlUtils.js\"\nimport { theme } from \"../theme.js\"\nimport { ProgrammingError } from \"../../api/common/error/ProgrammingError.js\"\nimport { Coordinate2D } from \"./SwipeHandler.js\"\n\nexport type ListState<T> = Readonly<{\n\titems: ReadonlyArray<T>\n\tloadingStatus: ListLoadingState\n\tloadingAll: boolean\n\tselectedItems: ReadonlySet<T>\n\tinMultiselect: boolean\n\tactiveIndex: number | null\n}>\n\nexport enum ListLoadingState {\n\t/** not loading anything */\n\tIdle,\n\tLoading,\n\t/** loading was cancelled, e.g. because of the network error or explicit user request */\n\tConnectionLost,\n\t/** finished loading */\n\tDone,\n}\n\nexport type SwipeConfiguration<T> = {\n\trenderLeftSpacer(): Children\n\trenderRightSpacer(): Children\n\tswipeLeft(element: T): Promise<ListSwipeDecision>\n\tswipeRight(element: T): Promise<ListSwipeDecision>\n}\n\nexport interface ViewHolder<T> {\n\tupdate(item: T, selected: boolean, multiselect: boolean): void\n}\n\nexport interface RenderConfig<T, R extends ViewHolder<T>> {\n\t/** Create a ViewHolder item. This function is responsible for attaching it to the {@param dom}. */\n\tcreateElement: (dom: HTMLElement) => R\n\titemHeight: number\n\tmultiselectionAllowed: MultiselectMode\n\tswipe: SwipeConfiguration<T> | null\n\n\t/**\n\t * add custom drag behaviour to the list.\n\t * @param ev dragstart event\n\t * @param entity: the row the event was started on\n\t * @param selectedElements the currently selected elements\n\t */\n\tdragStart?: (ev: DragEvent, entity: T, selectedElements: ReadonlySet<T>) => void\n}\n\nexport const enum MultiselectMode {\n\tDisabled,\n\tEnabled,\n}\n\nexport const enum ListSwipeDecision {\n\tCancel,\n\tCommit,\n}\n\nexport interface ListAttrs<T, R extends ViewHolder<T>> {\n\t/** will be compared referentially, will update the DOM on change  */\n\tstate: ListState<T>\n\t/** will be compared referentially, will completely reset DOM and state on change */\n\trenderConfig: RenderConfig<T, R>\n\n\t/** called when the end of the list is getting close to the viewport or when \"load more\" button is pressed. */\n\tonLoadMore(): void\n\n\t/** called after the loading failed/cancelled and retry button on progress item was pressed */\n\tonRetryLoading(): void\n\n\t/** A normal selection for single item. */\n\tonSingleSelection(item: T): unknown\n\n\t/** Selection that enters multiselect when triggered. Toggling the selection for the selected item in multiselect deselects it. */\n\tonSingleTogglingMultiselection(item: T): unknown\n\n\t/** called when range selection is extended */\n\tonRangeSelectionTowards(item: T): unknown\n\n\t/** called when stop button was pressed in progress item */\n\tonStopLoading(): unknown\n}\n\nexport interface ListRow<T, R extends ViewHolder<T>> {\n\tentity: T | null\n\trow: R\n\ttop: number\n\tdomElement: HTMLElement\n}\n\nconst ScrollBuffer = 15\n\n/** Displays the items in the virtual list. Can also display progress/cancelled loading state. */\nexport class List<T, VH extends ViewHolder<T>> implements ClassComponent<ListAttrs<T, VH>> {\n\tprivate innerDom: HTMLElement | null = null\n\tprivate containerDom: HTMLElement | null = null\n\tprivate rows: ListRow<T, VH>[] = []\n\tprivate state: ListState<T> | null = null\n\tprivate currentPosition: number = 0\n\tprivate lastAttrs!: ListAttrs<T, VH>\n\tprivate domSwipeSpacerLeft!: HTMLElement\n\tprivate domSwipeSpacerRight!: HTMLElement\n\tprivate loadingIndicatorChildDom!: HTMLElement\n\tprivate swipeHandler!: ListSwipeHandler<T, VH>\n\tprivate width = 0\n\tprivate height = 0\n\t// remember the last time we needed to scroll somewhere\n\tprivate activeIndex: number | null = null\n\n\tview({ attrs }: Vnode<ListAttrs<T, VH>>) {\n\t\tconst oldAttrs = this.lastAttrs\n\t\tthis.lastAttrs = attrs\n\t\treturn m(\n\t\t\t\".list-container.overflow-y-scroll.nofocus.overflow-x-hidden.fill-absolute\",\n\t\t\t{\n\t\t\t\toncreate: ({ dom }: VnodeDOM) => {\n\t\t\t\t\tthis.containerDom = dom as HTMLElement\n\n\t\t\t\t\tnew ResizeObserver(() => {\n\t\t\t\t\t\tthis.updateSize()\n\t\t\t\t\t}).observe(this.containerDom)\n\n\t\t\t\t\tthis.swipeHandler = this.createSwipeHandler()\n\t\t\t\t},\n\t\t\t\tonscroll: () => {\n\t\t\t\t\tthis.onScroll(attrs)\n\t\t\t\t},\n\t\t\t},\n\t\t\tthis.renderSwipeItems(attrs),\n\t\t\t// we need rel for the status indicator\n\t\t\tm(\"ul.list.rel.click\", {\n\t\t\t\toncreate: ({ dom }) => {\n\t\t\t\t\tthis.innerDom = dom as HTMLElement\n\t\t\t\t\tthis.initializeDom(dom as HTMLElement, attrs)\n\t\t\t\t\tthis.updateDomElements(attrs)\n\t\t\t\t\tthis.state = attrs.state\n\t\t\t\t},\n\t\t\t\tonupdate: ({ dom }) => {\n\t\t\t\t\tif (oldAttrs.renderConfig !== attrs.renderConfig) {\n\t\t\t\t\t\t// reset everything\n\t\t\t\t\t\tconsole.log(\"list renderConfig has changed, reset\")\n\t\t\t\t\t\t// m.render actually does diffing if you call it on the same dom element again which is not something that we want, we want completely\n\t\t\t\t\t\t// new dom elements (at least that's the simplest and most reliable way to reset).\n\t\t\t\t\t\t// so we trick mithril into thinking that nothing was rendered before. mithril will reset the DOM for us too.\n\t\t\t\t\t\t// @ts-ignore\n\t\t\t\t\t\tdom.vnodes = null\n\t\t\t\t\t\tthis.initializeDom(dom as HTMLElement, attrs)\n\t\t\t\t\t}\n\t\t\t\t\tif (this.state !== attrs.state) {\n\t\t\t\t\t\tthis.updateDomElements(attrs)\n\t\t\t\t\t\tthis.state = attrs.state\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tonscroll: () => {\n\t\t\t\t\tattrs.onLoadMore()\n\t\t\t\t},\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate createSwipeHandler() {\n\t\treturn new ListSwipeHandler<T, VH>(this.containerDom!, {\n\t\t\twidth: () => this.width,\n\t\t\tdomSwipeSpacerLeft: () => this.domSwipeSpacerLeft,\n\t\t\tdomSwipeSpacerRight: () => this.domSwipeSpacerRight,\n\t\t\tgetRowForPosition: (coord) => this.getRowForPosition(coord),\n\t\t\tonSwipeLeft: async (el) => this.lastAttrs.renderConfig.swipe?.swipeLeft(el) ?? ListSwipeDecision.Cancel,\n\t\t\tonSwipeRight: async (el) => this.lastAttrs.renderConfig.swipe?.swipeRight(el) ?? ListSwipeDecision.Cancel,\n\t\t})\n\t}\n\n\tprivate getRowForPosition(clientCoordiante: Coordinate2D) {\n\t\tconst touchAreaOffset = this.containerDom!.getBoundingClientRect().top\n\t\tconst relativeYPosition = this.currentPosition + clientCoordiante.y - touchAreaOffset\n\n\t\tconst itemIndex = Math.floor(relativeYPosition / this.lastAttrs.renderConfig.itemHeight)\n\t\tconst targetElementPosition = itemIndex * this.lastAttrs.renderConfig.itemHeight\n\n\t\t// We could find the entity just by indexing into it but we would need to scan the rows to find the right one anyway\n\t\t// Assuming that the rows are used in the order of their position we could use binary search\n\t\treturn this.rows.find((ve) => ve.top === targetElementPosition) ?? null\n\t}\n\n\tprivate readonly VIRTUAL_LIST_LENGTH = 100\n\n\tprivate initializeDom(dom: HTMLElement, attrs: ListAttrs<T, VH>) {\n\t\tconst rows: ListRow<T, VH>[] = []\n\t\tm.render(\n\t\t\tdom,\n\t\t\t// hardcoded number of elements for now\n\t\t\t[numberRange(0, this.VIRTUAL_LIST_LENGTH - 1).map(() => this.createRow(attrs, rows)), this.renderStatusRow()],\n\t\t)\n\n\t\tthis.rows = rows\n\t\tif (rows.length !== this.VIRTUAL_LIST_LENGTH) {\n\t\t\tthrow new ProgrammingError(`invalid rows length, expected ${this.VIRTUAL_LIST_LENGTH} rows, got ${this.rows.length}`)\n\t\t}\n\n\t\tif (attrs.renderConfig.swipe) {\n\t\t\tthis.swipeHandler?.attach()\n\t\t} else {\n\t\t\tthis.swipeHandler.detach()\n\t\t}\n\t}\n\n\tprivate onScroll(attrs: ListAttrs<T, VH>) {\n\t\tconst visibleElementHeight = this.updateDomElements(attrs)\n\t\tthis.loadMoreIfNecessary(attrs, visibleElementHeight)\n\t}\n\n\tprivate createRow(attrs: ListAttrs<T, VH>, rows: ListRow<T, VH>[]) {\n\t\treturn m(\"li.list-row\", {\n\t\t\tdraggable: attrs.renderConfig.dragStart ? \"true\" : undefined,\n\t\t\ttabindex: TabIndex.Default,\n\t\t\toncreate: (vnode: VnodeDOM) => {\n\t\t\t\tconst dom = vnode.dom as HTMLElement\n\t\t\t\tconst r = attrs.renderConfig.createElement(dom)\n\t\t\t\tconst row = {\n\t\t\t\t\trow: r,\n\t\t\t\t\tdomElement: dom,\n\t\t\t\t\ttop: -1,\n\t\t\t\t\tentity: null,\n\t\t\t\t}\n\t\t\t\trows.push(row)\n\t\t\t\tthis.setRowEventListeners(attrs, dom, row)\n\t\t\t},\n\t\t})\n\t}\n\n\tprivate setRowEventListeners(attrs: ListAttrs<T, VH>, domElement: HTMLElement, row: ListRow<T, VH>) {\n\t\tconst LONG_PRESS_DURATION_MS = 400\n\t\tlet touchStartTime: number | null = null\n\n\t\tdomElement.onclick = (e) => {\n\t\t\tif (!touchStartTime || Date.now() - touchStartTime < LONG_PRESS_DURATION_MS) {\n\t\t\t\trow.entity && this.handleEvent(row.entity, e)\n\t\t\t}\n\t\t}\n\n\t\tdomElement.onkeyup = (e) => {\n\t\t\tif (isKeyPressed(e.keyCode, Keys.SPACE, Keys.RETURN)) {\n\t\t\t\trow.entity && this.handleEvent(row.entity, e)\n\t\t\t}\n\t\t}\n\n\t\tdomElement.ondragstart = (e: DragEvent) => {\n\t\t\t// The quick change of the background color is to prevent a white background appearing in dark mode\n\t\t\tif (row.domElement) row.domElement!.style.background = theme.navigation_bg\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tif (row.domElement) row.domElement!.style.background = \"\"\n\t\t\t})\n\t\t\tif (attrs.renderConfig.dragStart) {\n\t\t\t\trow.entity && this.state && attrs.renderConfig.dragStart(e, row.entity, this.state.selectedItems)\n\t\t\t}\n\t\t}\n\n\t\tif (attrs.renderConfig.multiselectionAllowed === MultiselectMode.Enabled) {\n\t\t\tlet timeoutId: TimeoutID | null\n\t\t\tlet touchStartCoords: { x: number; y: number } | null = null\n\t\t\tdomElement.addEventListener(\"touchstart\", (e: TouchEvent) => {\n\t\t\t\ttouchStartTime = Date.now()\n\n\t\t\t\t// Activate multi selection after pause\n\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\t// check that virtualRow.entity exists because we had error feedbacks about it\n\t\t\t\t\tif (row.entity) {\n\t\t\t\t\t\tattrs.onSingleTogglingMultiselection(row.entity)\n\t\t\t\t\t}\n\t\t\t\t\tm.redraw()\n\t\t\t\t}, LONG_PRESS_DURATION_MS)\n\t\t\t\ttouchStartCoords = {\n\t\t\t\t\tx: e.touches[0].pageX,\n\t\t\t\t\ty: e.touches[0].pageY,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst touchEnd = () => {\n\t\t\t\ttimeoutId && clearTimeout(timeoutId)\n\t\t\t}\n\t\t\tdomElement.addEventListener(\"touchend\", touchEnd)\n\t\t\tdomElement.addEventListener(\"touchcancel\", touchEnd)\n\n\t\t\tdomElement.addEventListener(\"touchmove\", (e: TouchEvent) => {\n\t\t\t\t// If the user moved the finger too much by any axis, don't count it as a long press\n\t\t\t\tconst maxDistance = 30\n\t\t\t\tconst touch = e.touches[0]\n\n\t\t\t\tif (\n\t\t\t\t\ttouchStartCoords &&\n\t\t\t\t\ttimeoutId &&\n\t\t\t\t\t(Math.abs(touch.pageX - touchStartCoords.x) > maxDistance || Math.abs(touch.pageY - touchStartCoords.y) > maxDistance)\n\t\t\t\t) {\n\t\t\t\t\tclearTimeout(timeoutId)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Updates the given list of selected items with a click on the given clicked item. Takes ctrl and shift key events into consideration for multi selection.\n\t * If ctrl is pressed the selection status of the clickedItem is toggled.\n\t * If shift is pressed, all items beginning from the nearest selected item to the clicked item are additionally selected.\n\t * If neither ctrl nor shift are pressed only the clicked item is selected.\n\t */\n\tprivate handleEvent(clickedEntity: T, event: TouchEvent | MouseEvent | KeyboardEvent) {\n\t\t// normal click changes the selection to a single\n\t\t// ctrl click toggles the selection for an item and enables multiselect\n\t\t// shift click selects a lot of things and enabled multiselect\n\t\t// (there are also key press handlers but they are invoked from another place)\n\t\tlet changeType: Parameters<typeof this.changeSelection>[1]\n\t\tif ((client.isMobileDevice() && this.lastAttrs.state.inMultiselect) || event.ctrlKey || (client.isMacOS && event.metaKey)) {\n\t\t\tchangeType = \"togglingIncludingSingle\"\n\t\t} else if (event.shiftKey) {\n\t\t\tchangeType = \"range\"\n\t\t} else {\n\t\t\tchangeType = \"single\"\n\t\t}\n\t\tthis.changeSelection(clickedEntity, changeType)\n\t}\n\n\t/**\n\t * changeType:\n\t *  * single: one item selection (not multiselect)\n\t *  * togglingIncludingSingle: if not in multiselect, start multiselect. Turns multiselect on or off for the item. Includes the item from single selection\n\t *    when turning multiselect on.\n\t *  * togglingNewMultiselect: if not in multiselect, start multiselect. Turns multiselect on or off for the item. Only selected item will be in multiselect\n\t *    when turning multiselect on.\n\t *  * range: range selection, extends the range until the selected item\n\t */\n\tprivate changeSelection(clickedEntity: T, changeType: \"single\" | \"togglingIncludingSingle\" | \"range\") {\n\t\tswitch (changeType) {\n\t\t\tcase \"single\":\n\t\t\t\tthis.lastAttrs.onSingleSelection(clickedEntity)\n\t\t\t\tbreak\n\t\t\tcase \"togglingIncludingSingle\":\n\t\t\t\tif (this.lastAttrs.renderConfig.multiselectionAllowed === MultiselectMode.Enabled) {\n\t\t\t\t\tthis.lastAttrs.onSingleTogglingMultiselection(clickedEntity)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\tcase \"range\":\n\t\t\t\tif (this.lastAttrs.renderConfig.multiselectionAllowed === MultiselectMode.Enabled) {\n\t\t\t\t\tthis.lastAttrs.onRangeSelectionTowards(clickedEntity)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tprivate updateDomElements(attrs: ListAttrs<T, VH>): number {\n\t\t// if resize didn't kick in yet, measure it right away once\n\t\tif (this.height === 0) this.height = this.containerDom!.clientHeight\n\t\tconst rowHeight = attrs.renderConfig.itemHeight\n\t\t// plus loading indicator\n\t\t// should depend on whether we are completely loaded maybe?\n\t\tconst statusHeight = attrs.state.loadingStatus === ListLoadingState.Done ? 0 : size.list_row_height\n\t\tthis.innerDom!.style.height = px(attrs.state.items.length * rowHeight + statusHeight)\n\t\tif (attrs.state.activeIndex != null && attrs.state.activeIndex !== this.activeIndex) {\n\t\t\tconst index = attrs.state.activeIndex\n\t\t\tconst desiredPosition = attrs.state.activeIndex * rowHeight\n\t\t\tif (desiredPosition > this.containerDom!.scrollTop + this.height || desiredPosition < this.containerDom!.scrollTop) {\n\t\t\t\tconsole.log(\"active item out of screen, scrolling to\", index, desiredPosition)\n\t\t\t\tthis.currentPosition = this.containerDom!.scrollTop = desiredPosition\n\t\t\t} else {\n\t\t\t\tthis.currentPosition = this.containerDom!.scrollTop\n\t\t\t}\n\t\t} else {\n\t\t\tthis.currentPosition = this.containerDom!.scrollTop\n\t\t}\n\t\tthis.activeIndex = attrs.state.activeIndex\n\n\t\tconst visibleElements = 2 * Math.ceil(this.height / rowHeight / 2) // divide and multiply by two to get an even number\n\t\tconst visibleElementsHeight = visibleElements * rowHeight\n\t\tconst bufferHeight = ScrollBuffer * rowHeight\n\t\tconst maxStartPosition = rowHeight * attrs.state.items.length - bufferHeight * 2 - visibleElementsHeight\n\n\t\tlet nextPosition = this.currentPosition - (this.currentPosition % rowHeight) - bufferHeight\n\n\t\tif (nextPosition < 0) {\n\t\t\tnextPosition = 0\n\t\t} else if (nextPosition > maxStartPosition) {\n\t\t\tnextPosition = maxStartPosition\n\t\t}\n\n\t\tfor (const row of this.rows) {\n\t\t\trow.top = nextPosition\n\t\t\tnextPosition += rowHeight\n\n\t\t\tconst pos = row.top / rowHeight\n\t\t\tconst item = attrs.state.items[pos]\n\t\t\trow.entity = item\n\n\t\t\tif (!item) {\n\t\t\t\trow.domElement.style.display = \"none\"\n\t\t\t} else {\n\t\t\t\trow.domElement.style.display = \"\"\n\t\t\t\trow.domElement.style.transform = `translateY(${row.top}px)`\n\t\t\t\trow.row.update(item, attrs.state.selectedItems.has(item), attrs.state.inMultiselect)\n\t\t\t}\n\t\t}\n\t\tthis.updateStatus(attrs.state.loadingStatus)\n\n\t\tthis.loadMoreIfNecessary(attrs, visibleElementsHeight)\n\n\t\treturn visibleElementsHeight\n\t}\n\n\tprivate readonly updateStatus = memoized((status: ListLoadingState) => {\n\t\tswitch (status) {\n\t\t\tcase ListLoadingState.Idle:\n\t\t\tcase ListLoadingState.Done:\n\t\t\t\tm.render(this.loadingIndicatorChildDom, null)\n\t\t\t\tthis.loadingIndicatorChildDom.style.display = \"none\"\n\t\t\t\tbreak\n\t\t\tcase ListLoadingState.Loading:\n\t\t\t\tm.render(this.loadingIndicatorChildDom, this.renderLoadingIndicator())\n\t\t\t\tthis.loadingIndicatorChildDom.style.display = \"\"\n\t\t\t\tbreak\n\t\t\tcase ListLoadingState.ConnectionLost:\n\t\t\t\tm.render(this.loadingIndicatorChildDom, this.renderConnectionLostIndicator())\n\t\t\t\tthis.loadingIndicatorChildDom.style.display = \"\"\n\t\t\t\tbreak\n\t\t}\n\t})\n\n\tprivate renderLoadingIndicator(): Children {\n\t\treturn m(\n\t\t\t\".flex-center.items-center\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\theight: px(size.list_row_height),\n\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tgap: px(size.hpad_small),\n\t\t\t\t},\n\t\t\t},\n\t\t\tprogressIcon(),\n\t\t\tm(Button, {\n\t\t\t\tlabel: \"cancel_action\",\n\t\t\t\ttype: ButtonType.Primary,\n\t\t\t\tclick: () => this.lastAttrs.onStopLoading(),\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate renderConnectionLostIndicator(): Children {\n\t\treturn m(\n\t\t\t\".plr-l.flex-center.items-center\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\theight: px(size.list_row_height),\n\t\t\t\t},\n\t\t\t},\n\t\t\tm(Button, {\n\t\t\t\tlabel: \"loadMore_action\",\n\t\t\t\ttype: ButtonType.Primary,\n\t\t\t\tclick: () => this.retryLoading(),\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate retryLoading() {\n\t\tthis.lastAttrs.onRetryLoading()\n\t}\n\n\tprivate async loadMoreIfNecessary(attrs: ListAttrs<T, VH>, visibleElementsHeight: number) {\n\t\t// WARNING this is hacky:\n\t\t// lastBunchVisible depends on visibleElementsHeight which is set inside _createVirtualRows which might not have completed by the time we\n\t\t// reach here, so waiting for domDeferred guarantees that oncreate has finished running, and in turn that _createVirtualRows has completed\n\t\tconst lastBunchVisible = this.currentPosition > attrs.state.items.length * attrs.renderConfig.itemHeight - visibleElementsHeight * 2\n\n\t\tif (lastBunchVisible && attrs.state.loadingStatus == ListLoadingState.Idle) {\n\t\t\tawait attrs.onLoadMore()\n\t\t}\n\t}\n\n\tprivate renderStatusRow(): Children {\n\t\treturn m(\"li.list-row\", {\n\t\t\tstyle: {\n\t\t\t\tbottom: 0,\n\t\t\t\theight: px(size.list_row_height),\n\t\t\t\t// display: \"none\",\n\t\t\t},\n\t\t\toncreate: (vnode) => {\n\t\t\t\tthis.loadingIndicatorChildDom = vnode.dom as HTMLElement\n\t\t\t},\n\t\t})\n\t}\n\n\tprivate renderSwipeItems(attrs: ListAttrs<T, VH>): Children {\n\t\tif (attrs.renderConfig.swipe == null) {\n\t\t\treturn null\n\t\t}\n\t\treturn [\n\t\t\tm(\n\t\t\t\t\".swipe-spacer.flex.items-center.justify-end.pr-l.blue\",\n\t\t\t\t{\n\t\t\t\t\toncreate: (vnode) => (this.domSwipeSpacerLeft = vnode.dom as HTMLElement),\n\t\t\t\t\ttabindex: TabIndex.Programmatic,\n\t\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\theight: px(attrs.renderConfig.itemHeight),\n\t\t\t\t\t\ttransform: `translateY(-${attrs.renderConfig.itemHeight}px)`,\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\"z-index\": 1,\n\t\t\t\t\t\t// width: px(this.width),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tattrs.renderConfig.swipe.renderLeftSpacer(),\n\t\t\t),\n\t\t\tm(\n\t\t\t\t\".swipe-spacer.flex.items-center.pl-l.red\",\n\t\t\t\t{\n\t\t\t\t\toncreate: (vnode) => (this.domSwipeSpacerRight = vnode.dom as HTMLElement),\n\t\t\t\t\ttabindex: TabIndex.Programmatic,\n\t\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\theight: px(attrs.renderConfig.itemHeight),\n\t\t\t\t\t\ttransform: `translateY(-${attrs.renderConfig.itemHeight}px)`,\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\"z-index\": 1,\n\t\t\t\t\t\t// width: px(this.width),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tattrs.renderConfig.swipe.renderRightSpacer(),\n\t\t\t),\n\t\t]\n\t}\n\n\tprivate updateSize() {\n\t\tconst containerDom = this.containerDom\n\t\tif (containerDom && this.domSwipeSpacerLeft && this.domSwipeSpacerRight) {\n\t\t\tthis.domSwipeSpacerLeft.style.opacity = \"0\"\n\t\t\tthis.domSwipeSpacerRight.style.opacity = \"0\"\n\t\t\tthis.doUpdateWidth(containerDom)\n\t\t}\n\t}\n\n\tprivate readonly doUpdateWidth = debounce(60, (containerDom: HTMLElement) => {\n\t\tthis.width = containerDom.clientWidth\n\t\tthis.height = containerDom.clientHeight\n\n\t\tif (this.swipeHandler) {\n\t\t\t// with different zoom levels Blink does weird things and shows parts of elements that it shouldn't so we shift them around by a pixel\n\t\t\tconst translateX = this.width + 1\n\t\t\tthis.domSwipeSpacerLeft.style.width = px(this.width)\n\t\t\tthis.domSwipeSpacerRight.style.width = px(this.width)\n\t\t\tthis.domSwipeSpacerLeft.style.transform = `translateX(${-translateX}px) translateY(0px)`\n\t\t\tthis.domSwipeSpacerRight.style.transform = `translateX(${translateX}px) translateY(0px)`\n\n\t\t\tthis.rows.forEach((row) => {\n\t\t\t\trow.domElement && applySafeAreaInsetMarginLR(row.domElement)\n\t\t\t})\n\n\t\t\tthis.domSwipeSpacerLeft.style.opacity = \"1\"\n\t\t\tthis.domSwipeSpacerRight.style.opacity = \"1\"\n\t\t}\n\t})\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport type { AllIcons } from \"./Icon\"\nimport { Icon } from \"./Icon\"\nimport { px, size } from \"../size\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\n\nassertMainOrNode()\n\n// If you change this make sure you pass through all the attrs\nexport type InfoMessaggeBoxAttrs = {\n\tmessage: TranslationKey | lazy<Children>\n\ticon?: AllIcons\n\tcolor: string\n\tbottomContent?: Children\n\tbackgroundColor?: string\n}\n\n/** Displays a big message with an option icon above it. */\nexport class IconMessageBox implements Component<InfoMessaggeBoxAttrs> {\n\tview({ attrs }: Vnode<InfoMessaggeBoxAttrs>): Children {\n\t\treturn m(\".flex.col.items-center.justify-center.mlr\", [\n\t\t\tattrs.icon\n\t\t\t\t? m(Icon, {\n\t\t\t\t\t\ticon: attrs.icon,\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\tfill: attrs.color,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tclass: \"icon-message-box\",\n\t\t\t\t  })\n\t\t\t\t: null,\n\t\t\tm(\n\t\t\t\t\".h2.text-center.text-preline\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tcolor: attrs.color,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tgetMessage(attrs),\n\t\t\t),\n\t\t])\n\t}\n}\n\nexport type ColumnEmptyMessageBoxAttrs = InfoMessaggeBoxAttrs\n\n/**\n * A message displaying a text. A message box can be displayed on the background of a column if the column is empty. The text inside of it will be centered vertically, taking the icon into account.\n */\n\nexport default class ColumnEmptyMessageBox implements Component<ColumnEmptyMessageBoxAttrs> {\n\tview({ attrs }: Vnode<ColumnEmptyMessageBoxAttrs>): Children {\n\t\treturn m(\n\t\t\t\".fill-absolute.flex.col.items-center.justify-center.overflow-hidden\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\tbackgroundColor: attrs?.backgroundColor,\n\t\t\t\t},\n\t\t\t},\n\t\t\tm(\n\t\t\t\t\".flex.col.items-center\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\t// move up *only* this element, not the whole .fill-absolute parent to not overflow into the items above us\n\t\t\t\t\t\t\"margin-top\": px(attrs.icon ? -size.icon_message_box - size.vpad_xl : -size.vpad_xl),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t[\n\t\t\t\t\t// If we pass plain attrs all lifecycle callbacks we attach from the outside will be called twice, once on the wrong element.\n\t\t\t\t\tm(IconMessageBox, {\n\t\t\t\t\t\tmessage: attrs.message,\n\t\t\t\t\t\ticon: attrs.icon,\n\t\t\t\t\t\tcolor: attrs.color,\n\t\t\t\t\t}),\n\t\t\t\t\tattrs.bottomContent ?? m(\".button-height\"),\n\t\t\t\t],\n\t\t\t),\n\t\t)\n\t}\n}\n\nfunction getMessage({ message }: InfoMessaggeBoxAttrs) {\n\treturn typeof message === \"function\" ? message() : lang.get(message)\n}\n","import m, { Children, Component, Vnode, VnodeDOM } from \"mithril\"\nimport { Icons } from \"./icons/Icons\"\nimport type { Editor, Listing, Style } from \"../editor/Editor\"\nimport { Alignment } from \"../editor/Editor\"\nimport { numberRange } from \"@tutao/tutanota-utils\"\nimport { size } from \"../size\"\nimport { createDropdown, DropdownButtonAttrs } from \"./Dropdown.js\"\nimport { lang, TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { animations, height, opacity } from \"../animation/Animations\"\nimport { client } from \"../../misc/ClientDetector\"\nimport { BrowserType } from \"../../misc/ClientConstants\"\nimport { ToggleButton } from \"./buttons/ToggleButton.js\"\nimport { IconButton, IconButtonAttrs } from \"./IconButton.js\"\nimport { ButtonSize } from \"./ButtonSize.js\"\n\nexport interface RichTextToolbarAttrs {\n\teditor: Editor\n\timageButtonClickHandler?: ((ev: Event, editor: Editor) => unknown) | null\n\talignmentEnabled?: boolean\n\tfontSizeEnabled?: boolean\n\tcustomButtonAttrs?: Array<IconButtonAttrs>\n}\n\nexport class RichTextToolbar implements Component<RichTextToolbarAttrs> {\n\tselectedSize = size.font_size_base\n\n\tconstructor({ attrs }: Vnode<RichTextToolbarAttrs>) {\n\t\ttry {\n\t\t\tthis.selectedSize = parseInt(attrs.editor.squire.getFontInfo().size.slice(0, -2))\n\t\t} catch (e) {\n\t\t\tthis.selectedSize = size.font_size_base\n\t\t}\n\t}\n\n\toncreate(vnode: VnodeDOM<any>): void {\n\t\tconst dom = vnode.dom as HTMLElement\n\t\tdom.style.height = \"0\"\n\t\tanimateToolbar(dom, true)\n\t}\n\n\tonbeforeremove(vnode: VnodeDOM<any>): Promise<void> {\n\t\treturn animateToolbar(vnode.dom as HTMLElement, false)\n\t}\n\n\tview({ attrs }: Vnode<RichTextToolbarAttrs>): Children {\n\t\treturn m(\n\t\t\t\".elevated-bg.overflow-hidden\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\ttop: \"0px\",\n\t\t\t\t\tposition:\n\t\t\t\t\t\tclient.browser === BrowserType.SAFARI\n\t\t\t\t\t\t\t? client.isMacOS\n\t\t\t\t\t\t\t\t? \"-webkit-sticky\" // safari on macos\n\t\t\t\t\t\t\t\t: \"inherit\" // sticky changes the rendering order on iOS\n\t\t\t\t\t\t\t: \"sticky\", // normal browsers\n\t\t\t\t},\n\t\t\t},\n\t\t\t[\n\t\t\t\tm(\n\t\t\t\t\t\".flex-end.wrap.items-center.mb-xs.mt-xs.ml-between-s\",\n\t\t\t\t\tthis.renderStyleButtons(attrs),\n\t\t\t\t\tthis.renderCustomButtons(attrs),\n\t\t\t\t\tthis.renderAlignDropDown(attrs),\n\t\t\t\t\tthis.renderSizeButtons(attrs),\n\t\t\t\t\tthis.renderRemoveFormattingButton(attrs),\n\t\t\t\t),\n\t\t\t],\n\t\t)\n\t}\n\n\tprivate renderStyleButtons(attrs: RichTextToolbarAttrs): Children {\n\t\tconst { editor, imageButtonClickHandler } = attrs\n\n\t\treturn [\n\t\t\tthis.renderStyleToggleButton(\"b\", lang.get(\"formatTextBold_msg\") + \" (Ctrl + B)\", Icons.Bold, editor),\n\t\t\tthis.renderStyleToggleButton(\"i\", lang.get(\"formatTextItalic_msg\") + \" (Ctrl + I)\", Icons.Italic, editor),\n\t\t\tthis.renderStyleToggleButton(\"u\", lang.get(\"formatTextUnderline_msg\") + \" (Ctrl + U)\", Icons.Underline, editor),\n\t\t\tthis.renderStyleToggleButton(\"c\", lang.get(\"formatTextMonospace_msg\"), Icons.Code, editor),\n\t\t\tthis.renderStyleToggleButton(\"a\", editor.hasStyle(\"a\") ? lang.get(\"breakLink_action\") : lang.get(\"makeLink_action\"), Icons.Link, editor),\n\t\t\tthis.renderListToggleButton(\"ol\", lang.get(\"formatTextOl_msg\") + \" (Ctrl + Shift + 9)\", Icons.ListOrdered, editor),\n\t\t\tthis.renderListToggleButton(\"ul\", lang.get(\"formatTextUl_msg\") + \" (Ctrl + Shift + 8)\", Icons.ListUnordered, editor),\n\t\t\timageButtonClickHandler\n\t\t\t\t? m(IconButton, {\n\t\t\t\t\t\ttitle: \"insertImage_action\",\n\t\t\t\t\t\tclick: (ev) => imageButtonClickHandler(ev, editor),\n\t\t\t\t\t\ticon: Icons.Picture,\n\t\t\t\t\t\tsize: ButtonSize.Compact,\n\t\t\t\t  })\n\t\t\t\t: null,\n\t\t]\n\t}\n\n\tprivate renderStyleToggleButton(style: Style, title: string, icon: Icons, editor: Editor): Children {\n\t\treturn this.renderToggleButton(\n\t\t\ttitle,\n\t\t\ticon,\n\t\t\t() => editor.setStyle(!editor.hasStyle(style), style),\n\t\t\t() => editor.hasStyle(style),\n\t\t)\n\t}\n\n\tprivate renderListToggleButton(listing: Listing, title: string, icon: Icons, editor: Editor): Children {\n\t\treturn this.renderToggleButton(\n\t\t\ttitle,\n\t\t\ticon,\n\t\t\t() =>\n\t\t\t\teditor.styles.listing === listing\n\t\t\t\t\t? editor.squire.removeList()\n\t\t\t\t\t: listing === \"ul\"\n\t\t\t\t\t? editor.squire.makeUnorderedList()\n\t\t\t\t\t: editor.squire.makeOrderedList(),\n\t\t\t() => editor.styles.listing === listing,\n\t\t)\n\t}\n\n\tprivate renderToggleButton(title: string, icon: Icons, click: () => void, isSelected: () => boolean): Children {\n\t\treturn m(ToggleButton, {\n\t\t\ttitle: () => title,\n\t\t\tonToggled: click,\n\t\t\ticon: icon,\n\t\t\ttoggled: isSelected(),\n\t\t\tsize: ButtonSize.Compact,\n\t\t})\n\t}\n\n\tprivate renderCustomButtons(attrs: RichTextToolbarAttrs): Children {\n\t\treturn (attrs.customButtonAttrs ?? []).map((attrs) => m(IconButton, attrs))\n\t}\n\n\tprivate renderAlignDropDown(attrs: RichTextToolbarAttrs): Children {\n\t\tif (attrs.alignmentEnabled === false) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst alignButtonAttrs = (alignment: Alignment, title: TranslationKey, icon: Icons): DropdownButtonAttrs => {\n\t\t\treturn {\n\t\t\t\tlabel: title,\n\t\t\t\tclick: () => {\n\t\t\t\t\tattrs.editor.squire.setTextAlignment(alignment)\n\t\t\t\t\tsetTimeout(() => attrs.editor.squire.focus(), 100) // blur for the editor is fired after the handler for some reason\n\t\t\t\t\tm.redraw()\n\t\t\t\t},\n\t\t\t\ticon: icon,\n\t\t\t}\n\t\t}\n\n\t\treturn m(IconButton, {\n\t\t\t// label: () => \"▼\",\n\t\t\ttitle: \"formatTextAlignment_msg\",\n\t\t\ticon: this.alignIcon(attrs),\n\t\t\tsize: ButtonSize.Compact,\n\t\t\tclick: (e, dom) => {\n\t\t\t\te.stopPropagation()\n\t\t\t\tcreateDropdown({\n\t\t\t\t\twidth: 200,\n\t\t\t\t\tlazyButtons: () => [\n\t\t\t\t\t\talignButtonAttrs(\"left\", \"formatTextLeft_msg\", Icons.AlignLeft),\n\t\t\t\t\t\talignButtonAttrs(\"center\", \"formatTextCenter_msg\", Icons.AlignCenter),\n\t\t\t\t\t\talignButtonAttrs(\"right\", \"formatTextRight_msg\", Icons.AlignRight),\n\t\t\t\t\t\talignButtonAttrs(\"justify\", \"formatTextJustify_msg\", Icons.AlignJustified),\n\t\t\t\t\t],\n\t\t\t\t})(e, dom)\n\t\t\t},\n\t\t})\n\t}\n\n\tprivate alignIcon(attrs: RichTextToolbarAttrs) {\n\t\tswitch (attrs.editor.styles.alignment) {\n\t\t\tcase \"left\":\n\t\t\t\treturn Icons.AlignLeft\n\n\t\t\tcase \"center\":\n\t\t\t\treturn Icons.AlignCenter\n\n\t\t\tcase \"right\":\n\t\t\t\treturn Icons.AlignRight\n\n\t\t\tcase \"justify\":\n\t\t\t\treturn Icons.AlignJustified\n\t\t}\n\t}\n\n\tprivate renderSizeButtons({ editor }: RichTextToolbarAttrs): Children {\n\t\treturn m(IconButton, {\n\t\t\ttitle: \"formatTextFontSize_msg\",\n\t\t\ticon: Icons.FontSize,\n\t\t\tsize: ButtonSize.Compact,\n\t\t\tclick: (e, dom) => {\n\t\t\t\te.stopPropagation()\n\t\t\t\tcreateDropdown({\n\t\t\t\t\tlazyButtons: () =>\n\t\t\t\t\t\tnumberRange(8, 144).map((n) => {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tlabel: () => n.toString(),\n\t\t\t\t\t\t\t\tclick: () => {\n\t\t\t\t\t\t\t\t\teditor.squire.setFontSize(n)\n\t\t\t\t\t\t\t\t\tthis.selectedSize = n\n\t\t\t\t\t\t\t\t\tsetTimeout(() => editor.squire.focus(), 100) // blur for the editor is fired after the handler for some reason\n\t\t\t\t\t\t\t\t\tm.redraw()\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t})(e, dom)\n\t\t\t},\n\t\t})\n\t}\n\n\tprivate renderRemoveFormattingButton(attrs: RichTextToolbarAttrs): Children {\n\t\tif (attrs.fontSizeEnabled === false) {\n\t\t\treturn null\n\t\t}\n\n\t\treturn m(IconButton, {\n\t\t\ttitle: \"removeFormatting_action\",\n\t\t\ticon: Icons.FormatClear,\n\t\t\tclick: (e) => {\n\t\t\t\te.stopPropagation()\n\t\t\t\tattrs.editor.squire.removeAllFormatting()\n\t\t\t},\n\t\t\tsize: ButtonSize.Compact,\n\t\t})\n\t}\n}\n\nexport function animateToolbar(dom: HTMLElement, appear: boolean): Promise<void> {\n\tlet childHeight = Array.from(dom.children)\n\t\t.map((domElement) => (domElement as HTMLElement).offsetHeight)\n\t\t.reduce((current: number, previous: number) => Math.max(current, previous), 0)\n\treturn animations.add(dom, [height(appear ? 0 : childHeight, appear ? childHeight : 0), appear ? opacity(0, 1, false) : opacity(1, 0, false)]).then(() => {\n\t\tif (appear) {\n\t\t\tdom.style.height = \"\"\n\t\t}\n\t})\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport { theme } from \"../theme\"\nimport { inputLineHeight, px, size } from \"../size\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\n\nexport type TextDisplayAreaAttrs = {\n\tvalue: string\n\tlabel: TranslationKey | lazy<string>\n}\n\n/**\n * Simple text area to display some preformated non-editable text.\n */\nexport class TextDisplayArea implements Component<TextDisplayAreaAttrs> {\n\tview(vnode: Vnode<TextDisplayAreaAttrs>): Children {\n\t\treturn m(\".flex.flex-grow.flex-column.text.pt\", [\n\t\t\tm(\n\t\t\t\t\"label.text-ellipsis.noselect.z1.i.pr-s\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tfontSize: px(size.font_size_small),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tlang.getMaybeLazy(vnode.attrs.label),\n\t\t\t),\n\t\t\tm(\n\t\t\t\t\".text-pre.flex-grow\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tborderBottom: `1px solid ${theme.content_border}`,\n\t\t\t\t\t\tlineHeight: px(inputLineHeight),\n\t\t\t\t\t\tminHeight: px(inputLineHeight),\n\t\t\t\t\t},\n\t\t\t\t\tdisabled: true,\n\t\t\t\t},\n\t\t\t\tvnode.attrs.value,\n\t\t\t),\n\t\t])\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { PositionRect } from \"./Overlay\"\n\n/**\n * Small badge symbol to display numeric values to indicate that content is available, e.g. unread mail counter.\n * It will only appear if the counter value is greater than zero.\n */\nexport type CounterBadgeAttrs = {\n\tcount: number\n\tposition?: PositionRect\n\tcolor: string\n\tbackground: string\n\tshowFullCount?: boolean\n}\n\nexport class CounterBadge implements Component<CounterBadgeAttrs> {\n\t_hovered: boolean = false\n\n\tconstructor(vnode: Vnode<CounterBadgeAttrs>) {\n\t\tthis._hovered = false\n\t}\n\n\tview(vnode: Vnode<CounterBadgeAttrs>): Children {\n\t\tconst { count, position, background, color, showFullCount } = vnode.attrs\n\t\treturn count > 0\n\t\t\t? m(\n\t\t\t\t\t\".counter-badge.z2\",\n\t\t\t\t\t{\n\t\t\t\t\t\tclass: position ? \"abs\" : \"\",\n\t\t\t\t\t\tonmouseenter: () => {\n\t\t\t\t\t\t\tthis._hovered = true\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonmouseleave: () => {\n\t\t\t\t\t\t\tthis._hovered = false\n\t\t\t\t\t\t},\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\twidth: position?.width,\n\t\t\t\t\t\t\ttop: position?.top,\n\t\t\t\t\t\t\tbottom: position?.bottom,\n\t\t\t\t\t\t\tright: position?.right,\n\t\t\t\t\t\t\tleft: position?.left,\n\t\t\t\t\t\t\theight: position?.height,\n\t\t\t\t\t\t\t\"z-index\": position?.zIndex,\n\t\t\t\t\t\t\tbackground,\n\t\t\t\t\t\t\tcolor,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tcount < 99 || this._hovered || showFullCount ? count : \"99+\",\n\t\t\t  )\n\t\t\t: null\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { TranslationText } from \"../../../misc/LanguageViewModel\"\nimport { lang } from \"../../../misc/LanguageViewModel\"\nimport { addFlash, removeFlash } from \"../Flash\"\nimport { assertNotNull } from \"@tutao/tutanota-utils\"\nimport type { clickHandler } from \"../GuiUtils\"\nimport { theme } from \"../../theme.js\"\nimport { px, size } from \"../../size.js\"\n\nexport interface FolderColumnHeaderButtonAttrs {\n\tlabel: TranslationText\n\tclick: clickHandler\n}\n\nexport class FolderColumnHeaderButton implements Component<FolderColumnHeaderButtonAttrs> {\n\tprivate domButton: HTMLElement | null = null\n\n\tview({ attrs }: Vnode<FolderColumnHeaderButtonAttrs>): Children {\n\t\treturn m(\n\t\t\t\"button\",\n\t\t\t{\n\t\t\t\tclass: \"bg-transparent full-width noselect limit-width border-radius-big\",\n\t\t\t\tstyle: {\n\t\t\t\t\tborder: `2px solid ${theme.content_accent}`,\n\t\t\t\t\t// matching toolbar\n\t\t\t\t\theight: px(size.button_height + size.vpad_xs * 2),\n\t\t\t\t},\n\t\t\t\tonclick: (event: MouseEvent) => attrs.click(event, assertNotNull(this.domButton)),\n\t\t\t\ttitle: lang.getMaybeLazy(attrs.label),\n\t\t\t\toncreate: (vnode) => (this.domButton = vnode.dom as HTMLButtonElement),\n\t\t\t},\n\t\t\tm(\n\t\t\t\t\"\",\n\t\t\t\t{\n\t\t\t\t\t// additional wrapper for flex box styling as safari does not support flex box on buttons.\n\t\t\t\t\tclass: \"button-content flex items-center justify-center\",\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tborderColor: theme.content_accent,\n\t\t\t\t\t},\n\t\t\t\t\toncreate: (vnode) => addFlash(vnode.dom),\n\t\t\t\t\tonremove: (vnode) => removeFlash(vnode.dom),\n\t\t\t\t},\n\t\t\t\tthis.renderLabel(attrs),\n\t\t\t),\n\t\t)\n\t}\n\n\tprivate renderLabel(attrs: FolderColumnHeaderButtonAttrs): Children {\n\t\treturn m(\n\t\t\t\"\",\n\t\t\t{\n\t\t\t\tclass: \"text-ellipsis\",\n\t\t\t\tstyle: {\n\t\t\t\t\tcolor: theme.content_accent,\n\t\t\t\t\t\"font-weight\": \"bold\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tlang.getMaybeLazy(attrs.label),\n\t\t)\n\t}\n}\n","import m, { Children, ClassComponent, Vnode } from \"mithril\"\nimport { TextField } from \"./TextField.js\"\nimport { TranslationText } from \"../../misc/LanguageViewModel\"\nimport { Button, ButtonType } from \"./Button.js\"\nimport { Keys } from \"../../api/common/TutanotaConstants\"\nimport { createAsyncDropdown, DropdownChildAttrs } from \"./Dropdown.js\"\n\nexport interface BubbleTextFieldAttrs {\n\tlabel: TranslationText\n\titems: Array<string>\n\trenderBubbleText: (item: string) => string\n\tgetBubbleDropdownAttrs: (item: string) => Promise<DropdownChildAttrs[]>\n\ttext: string\n\tonInput: (text: string) => void\n\tonBackspace: () => boolean\n\tonEnterKey: () => boolean\n\tonUpKey: () => boolean\n\tonDownKey: () => boolean\n\tdisabled: boolean\n\tinjectionsRight?: Children | null\n\tonFocus: () => void\n\tonBlur: () => void\n}\n\nexport class BubbleTextField implements ClassComponent<BubbleTextFieldAttrs> {\n\tprivate active: boolean = false\n\tprivate domInput: HTMLInputElement | null = null\n\n\tview({ attrs }: Vnode<BubbleTextFieldAttrs>) {\n\t\treturn m(\".bubble-text-field\", [\n\t\t\tm(TextField, {\n\t\t\t\tlabel: attrs.label,\n\t\t\t\tdisabled: attrs.disabled,\n\t\t\t\tvalue: attrs.text,\n\t\t\t\toninput: attrs.onInput,\n\t\t\t\tinjectionsLeft: () => {\n\t\t\t\t\treturn attrs.items.map((item, idx, items) => {\n\t\t\t\t\t\t// We need overflow: hidden on both so that ellipsis on button works.\n\t\t\t\t\t\t// flex is for reserving space for the comma. align-items: end so that comma is pushed to the bottom.\n\t\t\t\t\t\treturn m(\".flex.overflow-hidden.items-end\", [\n\t\t\t\t\t\t\tm(\n\t\t\t\t\t\t\t\t\".flex-no-grow-shrink-auto.overflow-hidden\",\n\t\t\t\t\t\t\t\tm(Button, {\n\t\t\t\t\t\t\t\t\tlabel: () => attrs.renderBubbleText(item),\n\t\t\t\t\t\t\t\t\ttype: ButtonType.TextBubble,\n\t\t\t\t\t\t\t\t\tisSelected: () => false,\n\t\t\t\t\t\t\t\t\tclick: (e) => {\n\t\t\t\t\t\t\t\t\t\te.stopPropagation() // do not focus the text field\n\t\t\t\t\t\t\t\t\t\tcreateAsyncDropdown({\n\t\t\t\t\t\t\t\t\t\t\tlazyButtons: () => attrs.getBubbleDropdownAttrs(item),\n\t\t\t\t\t\t\t\t\t\t\twidth: 250,\n\t\t\t\t\t\t\t\t\t\t})(e, e.target as HTMLElement)\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t// Comma is shown when there's text/another bubble afterwards or if the field is active\n\t\t\t\t\t\t\tthis.active || idx < items.length - 1 || attrs.text !== \"\" ? m(\"span.pr\", \",\") : null,\n\t\t\t\t\t\t])\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t\tinjectionsRight: () => attrs.injectionsRight ?? null,\n\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\t// If the field is initialized with bubbles but the user did not edit it yet then field will not have correct size\n\t\t\t\t\t// and last bubble will not be on the same line with right injections (like \"show\" button). It is fixed after user\n\t\t\t\t\t// edits the field and autocompletion changes the field but before that it's broken. To avoid it we set the size\n\t\t\t\t\t// manually.\n\t\t\t\t\t//\n\t\t\t\t\t// This oncreate is run before the dom input's oncreate is run and sets the field so we have to access input on the\n\t\t\t\t\t// next frame. There's no other callback to use without requesting redraw.\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tif (this.domInput) this.domInput.size = 1\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t\tonDomInputCreated: (dom) => (this.domInput = dom),\n\t\t\t\tonfocus: () => {\n\t\t\t\t\tthis.active = true\n\t\t\t\t\tattrs.onFocus()\n\t\t\t\t},\n\t\t\t\tonblur: () => {\n\t\t\t\t\tthis.active = false\n\t\t\t\t\tattrs.onBlur()\n\t\t\t\t},\n\t\t\t\tkeyHandler: (key) => {\n\t\t\t\t\tswitch (key.keyCode) {\n\t\t\t\t\t\tcase Keys.BACKSPACE.code:\n\t\t\t\t\t\t\treturn attrs.onBackspace()\n\n\t\t\t\t\t\tcase Keys.RETURN.code:\n\t\t\t\t\t\t\treturn attrs.onEnterKey()\n\n\t\t\t\t\t\tcase Keys.DOWN.code:\n\t\t\t\t\t\t\treturn attrs.onUpKey()\n\n\t\t\t\t\t\tcase Keys.UP.code:\n\t\t\t\t\t\t\treturn attrs.onDownKey()\n\t\t\t\t\t}\n\t\t\t\t\treturn true\n\t\t\t\t},\n\t\t\t}),\n\t\t])\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { theme } from \"../theme\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\n\nassertMainOrNode()\nexport type MessageBoxAttrs = {\n\tstyle?: Record<string, any>\n}\n\n/**\n * A message box displaying a text. A message box can be displayed on the background of a column if the column is empty.\n */\nexport class MessageBox implements Component<MessageBoxAttrs> {\n\tview({ attrs, children }: Vnode<MessageBoxAttrs>): Children {\n\t\treturn m(\n\t\t\t\".justify-center.items-start.dialog-width-s.pt.pb.plr.border-radius\",\n\t\t\t{\n\t\t\t\tstyle: Object.assign(\n\t\t\t\t\t{\n\t\t\t\t\t\t\"white-space\": \"pre-wrap\",\n\t\t\t\t\t\t\"text-align\": \"center\",\n\t\t\t\t\t\tborder: `2px solid ${theme.content_border}`,\n\t\t\t\t\t},\n\t\t\t\t\tattrs.style,\n\t\t\t\t),\n\t\t\t},\n\t\t\tchildren,\n\t\t)\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\n\ntype BadgeAttrs = {\n\tclasses?: string\n}\nexport default class Badge implements Component<BadgeAttrs> {\n\tview(vnode: Vnode<BadgeAttrs>): Children {\n\t\treturn m(\".b.teamLabel.pl-s.pr-s.border-radius.no-wrap\" + (vnode.attrs.classes || \"\"), vnode.children)\n\t}\n}\n","import { AllIcons, Icon } from \"./Icon.js\"\nimport m, { Children, Component, Vnode } from \"mithril\"\nimport { theme } from \"../theme.js\"\nimport type { InfoLink, TranslationKey } from \"../../misc/LanguageViewModel.js\"\nimport { lang } from \"../../misc/LanguageViewModel.js\"\nimport type { ButtonAttrs } from \"./Button.js\"\nimport { Button, ButtonType } from \"./Button.js\"\nimport { NavButton } from \"./NavButton.js\"\nimport type { lazy } from \"@tutao/tutanota-utils\"\nimport { isNotNull } from \"@tutao/tutanota-utils\"\nimport { Icons } from \"./icons/Icons.js\"\nimport { px, size } from \"../size.js\"\n\nconst WARNING_RED = \"#ca0606\"\n\nexport const enum BannerType {\n\tInfo = \"info\",\n\tWarning = \"warning\",\n}\n\nexport interface InfoBannerAttrs {\n\tmessage: TranslationKey | lazy<Children>\n\ticon: AllIcons\n\thelpLink?: InfoLink | null\n\tbuttons: ReadonlyArray<ButtonAttrs | null>\n\ttype?: BannerType\n}\n\n/**\n * A low profile banner with a message and 0 or more buttons\n */\nexport class InfoBanner implements Component<InfoBannerAttrs> {\n\tview(vnode: Vnode<InfoBannerAttrs>): Children {\n\t\tconst { message, icon, helpLink, buttons, type } = vnode.attrs\n\t\t// Adjust the top and bottom spacing because the buttons have a minimum height of 44px.\n\t\t// This way the clickable area of the button overlaps with the text and the border a bit without having\n\t\t// too much empty space\n\t\tconst buttonContainerStyle =\n\t\t\thelpLink != null || buttons.length > 0\n\t\t\t\t? {\n\t\t\t\t\t\tmarginTop: \"-10px\",\n\t\t\t\t\t\tmarginBottom: \"-6px\",\n\t\t\t\t  }\n\t\t\t\t: undefined\n\t\treturn m(\n\t\t\t\".center-vertically.border-bottom.pr-s.pl.border-radius.mt-xs\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\tborder: `solid 2px ${type === BannerType.Warning ? WARNING_RED : theme.content_border}`,\n\t\t\t\t\t// keep the distance to the bottom of the banner the same in the case that buttons aren't present\n\t\t\t\t\tminHeight: buttons.length > 0 ? undefined : px(37),\n\t\t\t\t},\n\t\t\t},\n\t\t\t[\n\t\t\t\tm(\".mt-s.mr-s.abs\", this.renderIcon(icon, type ?? null)), // absolute position makes the icon fixed to the top left corner of the banner\n\t\t\t\tm(\n\t\t\t\t\t\"\",\n\t\t\t\t\t{ style: { \"margin-left\": px(size.icon_size_large + 1) } }, // allow room for the icon\n\t\t\t\t\t[\n\t\t\t\t\t\tm(\".mr.pt-s.pb-s\", typeof message === \"function\" ? message() : m(\".small.text-break\", lang.get(message))),\n\t\t\t\t\t\tm(\".flex.ml-negative-s\", { style: buttonContainerStyle }, [this.renderButtons(buttons), this.renderHelpLink(helpLink)]),\n\t\t\t\t\t],\n\t\t\t\t),\n\t\t\t],\n\t\t)\n\t}\n\n\trenderIcon(icon: AllIcons, type: BannerType | null): Children {\n\t\treturn m(Icon, {\n\t\t\ticon,\n\t\t\tstyle: {\n\t\t\t\tfill: type === BannerType.Warning ? WARNING_RED : theme.content_button,\n\t\t\t\tdisplay: \"block\",\n\t\t\t},\n\t\t})\n\t}\n\n\trenderButtons(buttons: ReadonlyArray<ButtonAttrs | null>): Children {\n\t\tif (buttons.length === 0) return null\n\t\treturn m(\n\t\t\t\"small\",\n\t\t\tbuttons.filter(isNotNull).map((attrs) => m(Button, { ...attrs, type: ButtonType.Secondary })),\n\t\t)\n\t}\n\n\trenderHelpLink(helpLink?: InfoLink | null): Children | null {\n\t\tif (helpLink == null) return null\n\n\t\treturn [\n\t\t\t// Push the help button all the way to the right\n\t\t\tm(\".flex-grow\"),\n\t\t\tm(\n\t\t\t\t\".button-content\",\n\t\t\t\t{\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tmarginRight: \"-10px\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tm(NavButton, {\n\t\t\t\t\ticon: () => Icons.QuestionMark,\n\t\t\t\t\thref: helpLink,\n\t\t\t\t\tsmall: true,\n\t\t\t\t\thideLabel: true,\n\t\t\t\t\tcentred: true,\n\t\t\t\t\tlabel: \"help_label\",\n\t\t\t\t}),\n\t\t\t),\n\t\t]\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { px, size } from \"../size\"\nimport type { clickHandler } from \"./GuiUtils\"\n\nexport type Attrs = {\n\tlabel: string\n\tclick: clickHandler\n\tstyle?: {}\n}\n\nexport class RecipientButton implements Component<Attrs> {\n\tview({ attrs }: Vnode<Attrs>): Children {\n\t\treturn m(\n\t\t\t\"button.mr-button.secondary.print.small\",\n\t\t\t{\n\t\t\t\tstyle: Object.assign(\n\t\t\t\t\t{\n\t\t\t\t\t\t\"white-space\": \"normal\",\n\t\t\t\t\t\t\"word-break\": \"break-all\",\n\t\t\t\t\t},\n\t\t\t\t\tattrs.style,\n\t\t\t\t),\n\t\t\t\tonclick: (e: MouseEvent) => attrs.click(e, e.target as HTMLElement),\n\t\t\t},\n\t\t\t[attrs.label],\n\t\t)\n\t}\n}\n","import type { TranslationText } from \"../../misc/LanguageViewModel\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport m, { Children, Component, Vnode } from \"mithril\"\nimport { theme } from \"../theme\"\n\nexport type RadioSelectorOption<T> = {\n\tname: TranslationText\n\tvalue: T\n\thelpText: TranslationText\n}\nexport type RadioSelectorAttrs<T> = {\n\toptions: ReadonlyArray<RadioSelectorOption<T>>\n\tselectedOption: T\n\tonOptionSelected: (arg0: T) => unknown\n}\n\n/**\n * Component which shows selection for a single choice.\n */\nexport class RadioSelector<T> implements Component<RadioSelectorAttrs<T>> {\n\tview({ attrs }: Vnode<RadioSelectorAttrs<T>>): Children {\n\t\treturn attrs.options.map((option) => this._renderOption(option, attrs.selectedOption, attrs.onOptionSelected))\n\t}\n\n\t_renderOption(option: RadioSelectorOption<T>, selectedOption: T, onOptionSelected: (arg0: T) => unknown): Children {\n\t\treturn m(\n\t\t\t\".border.border-radius.mb.pt.pb.pl.pr\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\tborderColor: option.value === selectedOption ? theme.content_accent : theme.content_border,\n\t\t\t\t\tborderWidth: \"2px\",\n\t\t\t\t},\n\t\t\t\tonclick: () => {\n\t\t\t\t\tonOptionSelected(option.value)\n\t\t\t\t},\n\t\t\t},\n\t\t\t[m(\".b\", lang.getMaybeLazy(option.name)), m(\".small\", lang.getMaybeLazy(option.helpText))],\n\t\t)\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { lang } from \"../../misc/LanguageViewModel\"\nimport type { TranslationKey } from \"../../misc/LanguageViewModel\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\n\nassertMainOrNode()\nexport type StatusType = \"neutral\" | \"valid\" | \"invalid\"\nexport type StatusFieldAttrs = {\n\tstatus: Status\n}\n\nexport class StatusField implements Component<StatusFieldAttrs> {\n\tview(vnode: Vnode<StatusFieldAttrs>): Children {\n\t\tconst { status } = vnode.attrs\n\t\tif (!status) return null\n\t\treturn m(\"\", lang.get(status.text))\n\t}\n}\n\nexport type Status = {\n\ttype: StatusType\n\ttext: TranslationKey\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport type { ButtonAttrs } from \"./Button.js\"\nimport { Button } from \"./Button.js\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { IconButton, IconButtonAttrs } from \"./IconButton.js\"\n\nassertMainOrNode()\nexport type ActionBarAttrs = {\n\tbuttons: IconButtonAttrs[]\n}\n\n/**\n * An action bar is a bar that contains buttons (either on the left or on the right).\n */\nexport class ActionBar implements Component<ActionBarAttrs> {\n\tview(vnode: Vnode<ActionBarAttrs>): Children {\n\t\treturn m(\n\t\t\t\".action-bar.flex-end.items-center.ml-between-s\",\n\t\t\tvnode.attrs.buttons.map((b) => m(IconButton, b)),\n\t\t)\n\t}\n}\n","import m, { Children, ClassComponent, Vnode } from \"mithril\"\nimport { AriaLandmarks, landmarkAttrs } from \"../AriaUtils.js\"\nimport { inputLineHeight, px, size } from \"../size.js\"\nimport { styles } from \"../styles.js\"\nimport { TabIndex } from \"../../api/common/TutanotaConstants.js\"\nimport { lang } from \"../../misc/LanguageViewModel.js\"\nimport { Icon } from \"./Icon.js\"\nimport { BootIcons } from \"./icons/BootIcons.js\"\nimport { theme } from \"../theme.js\"\nimport { DefaultAnimationTime } from \"../animation/Animations.js\"\nimport { Icons } from \"./icons/Icons.js\"\nimport { TextFieldType } from \"./TextField.js\"\n\nexport interface BaseSearchBarAttrs {\n\tplaceholder?: string | null\n\ttext: string\n\tbusy: boolean\n\tonInput: (text: string) => unknown\n\tonFocus?: () => unknown\n\tonBlur?: () => unknown\n\tonSearchClick?: () => unknown\n\tonClear?: () => unknown\n\tonInputCreated?: (dom: HTMLElement) => unknown\n\tonWrapperCreated?: (dom: HTMLElement) => unknown\n\tonKeyDown?: (keyboardEvent: KeyboardEvent) => unknown\n}\n\nexport class BaseSearchBar implements ClassComponent<BaseSearchBarAttrs> {\n\tprivate domInput!: HTMLInputElement\n\tprivate isFocused: boolean = false\n\n\tview({ attrs }: Vnode<BaseSearchBarAttrs>) {\n\t\treturn m(\n\t\t\t\".flex-end.items-center.border-radius.plr-s.pt-xs.pb-xs.search-bar.flex-grow\",\n\t\t\t{\n\t\t\t\tfocused: String(this.isFocused),\n\t\t\t\t...landmarkAttrs(AriaLandmarks.Search),\n\t\t\t\tstyle: {\n\t\t\t\t\t\"min-height\": px(inputLineHeight + 2),\n\t\t\t\t\t\"margin-top\": px(6),\n\t\t\t\t\t\"margin-bottom\": px(6),\n\t\t\t\t\t\"max-width\": styles.isUsingBottomNavigation() ? \"\" : px(350),\n\t\t\t\t},\n\t\t\t\toncreate: ({ dom }) => {\n\t\t\t\t\tattrs.onWrapperCreated?.(dom as HTMLElement)\n\t\t\t\t},\n\t\t\t},\n\t\t\t[\n\t\t\t\tstyles.isDesktopLayout()\n\t\t\t\t\t? m(\n\t\t\t\t\t\t\t\"button.click\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttabindex: TabIndex.Default,\n\t\t\t\t\t\t\t\ttitle: lang.get(\"search_label\"),\n\t\t\t\t\t\t\t\tonmousedown: (e: MouseEvent) => {\n\t\t\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tonclick: (e: MouseEvent) => {\n\t\t\t\t\t\t\t\t\te.preventDefault()\n\t\t\t\t\t\t\t\t\tattrs.onSearchClick?.()\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tm(Icon, {\n\t\t\t\t\t\t\t\ticon: BootIcons.Search,\n\t\t\t\t\t\t\t\tclass: \"flex-center items-center icon-large\",\n\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\tfill: theme.header_button,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t  )\n\t\t\t\t\t: null,\n\t\t\t\tm(\n\t\t\t\t\t\".flex.items-center\",\n\t\t\t\t\t{\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\ttransition: `width ${DefaultAnimationTime}ms`,\n\t\t\t\t\t\t\t\"padding-left\": styles.isDesktopLayout() ? px(10) : px(6),\n\t\t\t\t\t\t\t\"padding-top\": \"3px\",\n\t\t\t\t\t\t\t\"padding-bottom\": \"3px\",\n\t\t\t\t\t\t\t\"overflow-x\": \"hidden\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t[\n\t\t\t\t\t\tthis.renderInputField(attrs),\n\t\t\t\t\t\tm(\n\t\t\t\t\t\t\t\"button.closeIconWrapper\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tonclick: () => attrs.onClear?.(),\n\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\twidth: size.icon_size_large,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttitle: lang.get(\"close_alt\"),\n\t\t\t\t\t\t\t\ttabindex: TabIndex.Default,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tattrs.busy\n\t\t\t\t\t\t\t\t? m(Icon, {\n\t\t\t\t\t\t\t\t\t\ticon: BootIcons.Progress,\n\t\t\t\t\t\t\t\t\t\t// see comment on icon-progress-search for what is going on with sizes here\n\t\t\t\t\t\t\t\t\t\tclass: \"flex-center items-center icon-progress icon-progress-search\",\n\t\t\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\t\tfill: theme.header_button,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t  })\n\t\t\t\t\t\t\t\t: attrs.text\n\t\t\t\t\t\t\t\t? m(Icon, {\n\t\t\t\t\t\t\t\t\t\ticon: Icons.Close,\n\t\t\t\t\t\t\t\t\t\tclass: \"flex-center items-center icon-large\",\n\t\t\t\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\t\t\t\tfill: theme.header_button,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t  })\n\t\t\t\t\t\t\t\t: null,\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\t}\n\n\tprivate renderInputField(attrs: BaseSearchBarAttrs): Children {\n\t\treturn m(\"input.input.input-no-clear\", {\n\t\t\t\"aria-autocomplete\": \"list\",\n\t\t\ttabindex: TabIndex.Default,\n\t\t\trole: \"combobox\",\n\t\t\tplaceholder: attrs.placeholder,\n\t\t\ttype: TextFieldType.Text,\n\t\t\tvalue: attrs.text,\n\t\t\toncreate: (vnode) => {\n\t\t\t\tthis.domInput = vnode.dom as HTMLInputElement\n\t\t\t\tattrs.onInputCreated?.(this.domInput)\n\t\t\t},\n\t\t\tonfocus: () => {\n\t\t\t\tthis.isFocused = true\n\n\t\t\t\tattrs.onFocus?.()\n\t\t\t},\n\t\t\tonblur: () => {\n\t\t\t\tthis.isFocused = false\n\t\t\t\tattrs.onBlur?.()\n\t\t\t},\n\t\t\tonremove: () => {\n\t\t\t\tthis.domInput.onblur = null\n\t\t\t\tthis.isFocused = false\n\t\t\t},\n\t\t\toninput: () => {\n\t\t\t\tattrs.onInput(this.domInput.value)\n\t\t\t},\n\t\t\tonkeydown: (e: KeyboardEvent) => {\n\t\t\t\tattrs.onKeyDown?.(e)\n\t\t\t},\n\t\t\tstyle: {\n\t\t\t\t\"line-height\": px(inputLineHeight),\n\t\t\t},\n\t\t})\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { px } from \"../size\"\n\nexport type SegmentControlItem<T> = {\n\tname: string\n\tvalue: T\n}\nexport type SegmentControlAttrs<T> = {\n\tselectedValue: T\n\tonValueSelected: (_: T) => unknown\n\titems: SegmentControlItem<T>[]\n\titemMaxWidth?: number\n}\n\nexport class SegmentControl<T> implements Component<SegmentControlAttrs<T>> {\n\tview(vnode: Vnode<SegmentControlAttrs<T>>): Children {\n\t\treturn [\n\t\t\tm(\n\t\t\t\t\".segmentControl.flex.center-horizontally.button-height\",\n\t\t\t\t{\n\t\t\t\t\trole: \"tablist\",\n\t\t\t\t},\n\t\t\t\tvnode.attrs.items.map((item) =>\n\t\t\t\t\tm(\n\t\t\t\t\t\t\"button.segmentControlItem.flex.center-horizontally.center-vertically.text-ellipsis.small\" +\n\t\t\t\t\t\t\t(item.value === vnode.attrs.selectedValue ? \".segmentControl-border-active.content-accent-fg\" : \".segmentControl-border\"),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\t\tflex: \"0 1 \" + (typeof vnode.attrs.itemMaxWidth !== \"undefined\" ? px(vnode.attrs.itemMaxWidth) : px(120)),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttitle: item.name,\n\t\t\t\t\t\t\trole: \"tab\",\n\t\t\t\t\t\t\t\"aria-selected\": String(item.value === vnode.attrs.selectedValue),\n\t\t\t\t\t\t\tonclick: () => this._onSelected(item, vnode.attrs),\n\t\t\t\t\t\t},\n\t\t\t\t\t\titem.name,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t]\n\t}\n\n\t_onSelected(item: SegmentControlItem<T>, attrs: SegmentControlAttrs<T>) {\n\t\tif (item.value !== attrs.selectedValue) {\n\t\t\tattrs.onValueSelected(item.value)\n\t\t}\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\n\nexport type ColorPickerAttrs = {\n\tvalue: string\n\tonValueChange: (value: string) => unknown\n}\n\nexport class ColorPicker implements Component<ColorPickerAttrs> {\n\tview(vnode: Vnode<ColorPickerAttrs>): Children {\n\t\tconst a = vnode.attrs\n\t\treturn m(\"input.color-picker\", {\n\t\t\ttype: \"color\",\n\t\t\tvalue: a.value,\n\t\t\toninput: (event: InputEvent) => a.onValueChange((event.target as HTMLInputElement).value),\n\t\t})\n\t}\n}\n","import m, { Children, Component } from \"mithril\"\nimport { px } from \"../size\"\nimport { AriaLandmarks, landmarkAttrs } from \"../AriaUtils\"\nimport { assertMainOrNode } from \"../../api/common/Env\"\nimport { lang } from \"../../misc/LanguageViewModel.js\"\nimport { Button, ButtonType } from \"./Button.js\"\n\nassertMainOrNode()\n\nexport class NotFoundPage implements Component<void> {\n\tview(): Children {\n\t\treturn m(\n\t\t\t\".main-view.flex.items-center.justify-center.mlr\",\n\t\t\t{\n\t\t\t\t...landmarkAttrs(AriaLandmarks.Main),\n\t\t\t\tstyle: {\n\t\t\t\t\t\"max-height\": px(450),\n\t\t\t\t},\n\t\t\t},\n\t\t\tm(\".message.center.max-width-l\", [\n\t\t\t\tm(\"h2\", \"404\"),\n\t\t\t\t[\n\t\t\t\t\tm(\"p\", lang.get(\"notFound404_msg\")),\n\t\t\t\t\tm(Button, {\n\t\t\t\t\t\tlabel: \"back_action\",\n\t\t\t\t\t\tclick: () => window.history.back(),\n\t\t\t\t\t\ttype: ButtonType.Primary,\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t]),\n\t\t)\n\t}\n}\n","import m, { Children, Component, Vnode } from \"mithril\"\nimport { SwipeHandler } from \"./SwipeHandler\"\nimport { animations, transform, TransformEnum } from \"../animation/Animations\"\nimport { client } from \"../../misc/ClientDetector.js\"\n\ntype Page = {\n\tkey: string | number\n\tnodes: Children\n}\ntype Attrs = {\n\tpreviousPage: Page\n\tcurrentPage: Page\n\tnextPage: Page\n\tonChangePage: (next: boolean) => unknown\n}\n\nexport class PageView implements Component<Attrs> {\n\tprivate _viewDom: HTMLElement | null = null\n\tprivate _swipeHandler!: PageSwipeHandler\n\tprivate _onChangePage!: (_: boolean) => unknown\n\n\tview({ attrs }: Vnode<Attrs>): Children {\n\t\tthis._onChangePage = (next) => attrs.onChangePage(next)\n\n\t\treturn m(\n\t\t\t\".fill-absolute\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\t// this prevents \"wobbly\" calendar when the height is being changed, otherwise the scrollbar shows up until we actually do the resize\n\t\t\t\t\t// for a short time and shifts all the events horizontally. without scrollbar there's no horizontal shift.\n\t\t\t\t\t// overflow-y: hidden produces *horizontal* scrollbar for some reason? clip should do a similar thing\n\t\t\t\t\t// *but* overflow-y clip does very weird things to offscreen pages in mobile Safari (tested with 16.3.1)\n\t\t\t\t\t// as there are no scrollbar gutters on mobile anyway we don't have to set it\n\t\t\t\t\t\"overflow-y\": client.isMobileDevice() ? \"\" : \"clip\",\n\t\t\t\t},\n\t\t\t\toncreate: (vnode) => {\n\t\t\t\t\tthis._viewDom = vnode.dom as HTMLElement\n\t\t\t\t\tthis._swipeHandler = new PageSwipeHandler(this._viewDom, (next) => this._onChangePage(next))\n\t\t\t\t\tthis._swipeHandler.attach()\n\t\t\t\t},\n\t\t\t},\n\t\t\t[\n\t\t\t\tm(\n\t\t\t\t\t\".abs\",\n\t\t\t\t\t{\n\t\t\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\t\t\tkey: attrs.previousPage.key,\n\t\t\t\t\t\tstyle: this._viewDom &&\n\t\t\t\t\t\t\tthis._viewDom.offsetWidth > 0 && {\n\t\t\t\t\t\t\t\twidth: this._viewDom.offsetWidth + \"px\",\n\t\t\t\t\t\t\t\theight: this._viewDom.offsetHeight + \"px\",\n\t\t\t\t\t\t\t\ttransform: `translateX(${-this._viewDom.offsetWidth}px)`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tattrs.previousPage.nodes,\n\t\t\t\t),\n\t\t\t\tm(\n\t\t\t\t\t\".fill-absolute\",\n\t\t\t\t\t{\n\t\t\t\t\t\tkey: attrs.currentPage.key,\n\t\t\t\t\t},\n\t\t\t\t\tattrs.currentPage.nodes,\n\t\t\t\t),\n\t\t\t\tm(\n\t\t\t\t\t\".abs\",\n\t\t\t\t\t{\n\t\t\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\t\t\tkey: attrs.nextPage.key,\n\t\t\t\t\t\tstyle: this._viewDom &&\n\t\t\t\t\t\t\tthis._viewDom.offsetWidth > 0 && {\n\t\t\t\t\t\t\t\twidth: this._viewDom.offsetWidth + \"px\",\n\t\t\t\t\t\t\t\theight: this._viewDom.offsetHeight + \"px\",\n\t\t\t\t\t\t\t\ttransform: `translateX(${this._viewDom.offsetWidth}px)`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tattrs.nextPage.nodes,\n\t\t\t\t),\n\t\t\t],\n\t\t)\n\t}\n}\n\nexport class PageSwipeHandler extends SwipeHandler {\n\t_onGestureCompleted: (next: boolean) => unknown\n\t_xoffset: number = 0\n\n\tconstructor(touchArea: HTMLElement, onGestureCompleted: (next: boolean) => unknown) {\n\t\tsuper(touchArea)\n\t\t// avoid flickering especially in day and week view when overflow-y is set on nested elements\n\t\ttouchArea.style.transformStyle = \"preserve-3d\"\n\t\ttouchArea.style.backfaceVisibility = \"hidden\"\n\t\tthis._onGestureCompleted = onGestureCompleted\n\t}\n\n\tonHorizontalDrag(xDelta: number, yDelta: number) {\n\t\tthis._xoffset = Math.abs(xDelta) > 40 ? xDelta : 0\n\t\tthis.touchArea.style.transform = `translateX(${this._xoffset}px)`\n\t}\n\n\tonHorizontalGestureCompleted(delta: { x: number; y: number }): Promise<void> {\n\t\tif (Math.abs(delta.x) > 100) {\n\t\t\tthis._xoffset = 0\n\t\t\treturn animations\n\t\t\t\t.add(this.touchArea, transform(TransformEnum.TranslateX, delta.x, this.touchArea.offsetWidth * (delta.x > 0 ? 1 : -1)))\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis._onGestureCompleted(delta.x < 0)\n\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tthis.touchArea.style.transform = \"\"\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t} else {\n\t\t\treturn this.reset(delta)\n\t\t}\n\t}\n\n\treset(delta: { x: number; y: number }): Promise<any> {\n\t\tif (Math.abs(this._xoffset) > 40) {\n\t\t\tanimations.add(this.touchArea, transform(TransformEnum.TranslateX, delta.x, 0))\n\t\t} else {\n\t\t\tthis.touchArea.style.transform = \"\"\n\t\t}\n\n\t\tthis._xoffset = 0\n\t\treturn super.reset(delta)\n\t}\n}\n","import { lang, TranslationKey } from \"../../../misc/LanguageViewModel.js\"\nimport { lazy } from \"@tutao/tutanota-utils\"\nimport m, { Children, Component, Vnode } from \"mithril\"\nimport { px, size } from \"../../size.js\"\n\nexport type BannerButtonAttrs = {\n\tborderColor: string\n\tcolor: string\n\tclick: () => unknown\n\ttext: TranslationKey | lazy<string>\n}\n\nexport class BannerButton implements Component<BannerButtonAttrs> {\n\tview({ attrs }: Vnode<BannerButtonAttrs>): Children {\n\t\treturn m(\n\t\t\t\"button.border-radius.mr-s.center\",\n\t\t\t{\n\t\t\t\tstyle: {\n\t\t\t\t\tborder: `2px solid ${attrs.borderColor}`,\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tcolor: attrs.color,\n\t\t\t\t\twidth: \"min-content\",\n\t\t\t\t\tpadding: px(size.hpad_button),\n\t\t\t\t\tminWidth: \"60px\",\n\t\t\t\t},\n\t\t\t\tonclick: attrs.click,\n\t\t\t},\n\t\t\tlang.getMaybeLazy(attrs.text),\n\t\t)\n\t}\n}\n"],"names":["buttons","xPos","yPos","width","dropdown","Dropdown","setOrigin","DomRectReadOnlyPolyfilled","modal","displayUnique","args","button","label","click","type","makeButtonAttrsForSnackBar","notificationQueue","push","message","onClose","_a","length","showNextNotification","logins","linkId","render","canSeeTutanotaLinks","lazyChildren","dropdownWidth","icon","colors","createAsyncDropdown","lazyButtons","async","resolveMaybeLazy","moreButtonAttrsImpl","event","MouseEvent","x","clientX","y","clientY","assertNotNull","touches","item","dom","eventType","Event","bubbles","cancelable","dispatchEvent","data","pages","closeAction","view","child","unregisterCloseListener","windowFacade","addWindowCloseListener","wizardDialogAttrs","WizardDialogAttrs","wizardDialog","close","Dialog","largeDialog","headerBarAttrs","m","WizardDialog","addShortcut","key","Keys","ESC","exec","confirmThenCleanup","help","setCloseHandler","dialog","attrs","component","attributes","instance","currentElement","indexOfElement","prefixActions","elements","getArray","title","createDropdown","splice","unshift","updateInstance","prev","next","size","state","selectedItems","values","value","params","DropDownSelector","helpLabel","items","dropdownCountries","name","lang","get","selectedValue","selectedCountry","selectionChangedHandler","onSelectionChanged","currentTarget","HTMLElement","height","left","top","getBoundingClientRect","targetHeight","targetWidth","ProgrammingError","mainButtonAttrs","childAttrs","showDropdown","overrideOrigin","Object","assign","e","Promise","resolve","dropDownFn","stopPropagation","multiselectMode","list","multiselectionEnabled","UP","mapLazily","selectPrevious","K","shift","enabled","DOWN","selectNext","J","A","ctrl","areAllSelected","selectNone","selectAll","right","client","isMobileDevice","confirmMessage","confirmationPromise","confirm","confirmation","confirmed","action","then","ok","cancelled","result","scrollDom","entryHeight","getSelectedEntryIndex","scrollListDom","IconsSvg","freeze","Add","AlignLeft","AlignRight","AlignCenter","AlignJustified","ArrowBackward","ArrowForward","Attachment","Bold","Book","Call","Cancel","Checkmark","Code","ContactImport","Desktop","Download","Edit","Italic","Link","ListUnordered","ListOrdered","Login","Lock","MatchCase","Mobile","More","NewWindow","Pin","Trash","TrashEmpty","Underline","Unlock","Warning","WarningOutline","NoEye","Eye","People","Print","Chat","Copy","Close","Picture","FontSize","Table","TableColumns","TableSingle","Language","ListAlt","Notifications","ArrowDropLeft","ArrowDropRight","Power","Palette","Import","Export","PencilSquare","Time","CircleCheckmark","CircleReject","CircleHelp","CircleEmpty","Gift","Clipboard","QuestionMark","FormatClear","AddCheckCirle","Reply","Inbox","Archive","Draft","Send","Folder","Spam","TrashBin","Bulb","CreditCard","Wand","Filter","ReplyAll","Forward","SecondFactorImage","NotificationIcon","HabReminderImage","VisSignupImage","PayPalLogo","ReplacementImage","exports","assertMainOrNode","BootIconsSvg","Android","FDroid","Apple","Back","Checkbox","CheckboxSelected","Contacts","Expand","Help","Logout","MoreVertical","Premium","Progress","Search","Settings","Share","Calendar","Heart","Mail","Icons","IconsModule","Icon","vnode","containerClasses","this","getContainerClasses","class","getClass","style","getStyle","_b","trust","hoverText","fill","theme","content_accent","cls","large","classes","container","progressIcon","getColors","buttonColors","navigation_button","button_selected","navigation_button_selected","button_icon_bg","getNavButtonIconBackground","navigation_button_icon","icon_selected","navigation_button_icon_selected","border","navigation_bg","content_button","content_button_selected","getNavigationMenuIcon","content_button_icon_selected","getElevatedBackground","getContentButtonIconBackground","content_button_icon","header_button_selected","content_bg","Button","constructor","_domButton","a","getType","undefined","getTitle","getMaybeLazy","getButtonClasses","join","_getStyle","onclick","oncreate","onremove","removeFlash","getWrapperClasses","borderColor","addFlash","getIcon","_getLabelElement","staticRightText","_getLabelStyle","px","border_radius","getIconClass","getIconColor","getIconBackgroundColor","button_bubble_fg","isSelected","includes","buttonClasses","wrapperClasses","trim","color","content_fg","call","noBubble","DialogHeaderBar","columnClass","middle","create","remove","map","inputLineHeight","font_size_base","inputMarginTop","font_size_small","hpad_small","TextField","onblur","active","maxWidth","labelBase","disabled","_didAutofill","injectionsLeft","labelTransitionSpeed","DefaultAnimationTime","doShowBorder","borderWidth","content_border","id","_domWrapper","_domInputWrapper","focus","_domLabel","fontSize","transform","transition","minHeight","minInputHeight","_getInputField","_getTextArea","injectionsRight","marginTop","lineHeight","autofillGuard","autocompleteAs","opacity","tabIndex","concat","alignRight","autocomplete","domInput","onDomInputCreated","addEventListener","animationName","redraw","onfocus","blur","onkeydown","keyCode","which","ctrlKey","shiftKey","keyHandler","onupdate","oninput","minWidth","Math","max","split","scrollHeight","classList","add","Function","isEmpty","pureComponent","factory","children","DropdownInfo","center","bold","info","isDropDownInfo","dropdownChild","hasOwnProperty","bottom","_domDropdown","origin","_domInput","_domContents","_isFilterable","_maxHeight","closeHandler","chooseMatch","filterString","_filterString","toLowerCase","visibleElements","downcast","_visibleChildren","filter","b","matchingButton","find","document","activeElement","_width","oninit","filterNull","wrapClick","_shortcuts","_createShortcuts","shortcuts","_inputField","placeholder","neverNull","paddingLeft","hpad_large","paddingRight","button_height","_contents","showingIcons","some","c","role","tabindex","Array","from","reduce","accumulator","offsetHeight","vpad","onscroll","ev","target","scrollTop","_getFilterHeight","DropdownButton","onkeypress","fn","r","backgroundClick","contains","parentNode","TAB","focusPrevious","focusNext","RETURN","popState","hideAnimation","handler","vpad_xs","withBackground","_","originalButtons","buttonsResolved","race","all","delay","module","import","showProgressDialog","buttonRect","DROPDOWN_MARGIN","domDropdown","contentHeight","contentWidth","leftEdgeOfElement","rightEdgeOfElement","bottomEdgeOfElement","topEdgeOfElement","upperSpace","getSafeAreaInsetTop","lowerSpace","window","innerHeight","getSafeAreaInsetBottom","leftSpace","rightSpace","innerWidth","maxHeight","transformOrigin","min","availableSpaceForDropdown","leftEdgeOfDropdown","rightEdgeOfDropdown","animations","easing","ease","out","selected","marginRight","IconButton","valueToText","noOp","selectable","selectedValueDisplay","selectedItem","console","log","lazyStringValue","String","JSON","stringify","DialogInjectionRight","componentAttrs","visible","headerAttrs","INPUT","dialogType","childComponent","_domDialog","_closeHandler","_focusedBeforeShown","_injectionRightAttrs","_focusOnLoadFunction","_defaultFocusOnLoad","_wasFocusOnLoadCalled","marginPx","hpad","sidesMargin","styles","isSingleColumnLayout","_getDialogWrapperClasses","paddingTop","marginLeft","_keyboardHeight","_getDialogStyle","animation","bgcolor","backgroundColor","alpha","requestAnimationFrame","setInjectionRight","injectionRightAttrs","inputs","querySelectorAll","querySelector","setFocusOnLoadFunction","callback","dialogWrapperStyle","dialogStyle","shortcut","keyManager","registerModalShortcuts","show","display","linear","static","messageIdOrMessageFunction","infoToAppend","setTimeout","lines","buttonAttrs","line","filename","url","closeButtonAttrs","downloadButtonAttrs","popup","open","location","confirmId","conf","confirmMultiple","onclose","positive","getContent","additionalChild","choices","choice","text","choose","saveAction","saveDialog","actionBarAttrs","res","props","createActionDialog","okAction","validator","allowCancel","allowOkWithReturn","okActionTextId","cancelActionTextId","cancelAction","doCancel","doAction","validationResult","finalizer","error_id","n","bM","allow","getAsLazy","titleId","labelIdOrLabelFunction","infoMsgId","inputValidator","showActionDialog","newValue","catch","error","isOfflineError","initialValue","identity","noHeader","errorMessage","savedState","isKeyPressed","cancel","textId","newSize","addKeyboardSizeListener","_onKeyboardSizeChanged","currentAnimationTimeout","NotificationOverlay","margin","allButtons","slice","overlayRect","closeFunction","displayOverlay","closeAndOpenNext","forEach","originClickHandler","closeFinalAttrs","lastProgress","progress","onbeforeremove","vn","cacheStorage","loginListener","connectivityModel","progressTracker","cb","lastWsState","lastUpdate","wsWasConnectedBefore","waitForFullLogin","setProgressUpdateStream","onProgressUpdate","setWsStateStream","wsConnection","progressStream","wsStream","onWsStateChange","newState","getLastUpdateTime","Date","time","getCurrentAttrs","isFullyLoggedIn","reconnectAction","tryReconnect","getFullLoginFailed","retryAsyncLogin","finally","getProgress","isUserLoggedIn","SNACKBAR_SHOW_TIME","MAX_SNACKBAR_WIDTH","SnackBar","bottomInset","bottomOffset","isUsingBottomNavigation","bottom_nav_bar","hpad_medium","snackBarMarginLR","leftOffset","isDesktopLayout","drawer_menu_width","snackBarWidth","zIndex","getSnackBarPosition","clearTimeout","autoRemoveTimer","_domIcon","focused","toggle","onchange","checked","position","cursor","z_index","tagName","toUpperCase","onChecked","onExpandedChange","expanded","showWarning","childDiv","observer","lastCalculatedHeight","childrenInDom","MutationObserver","mutations","onbeforeupdate","old","oldExpanded","currentExpanded","handleExpansionStateChanged","observe","childList","subtree","disconnect","setChildrenInDomTimeout","Attach","Sent","Confidential","renderLogo","landmarkAttrs","sizes","hpad_button","logo","columnType","headerCenter","ariaLabel","_domColumn","_ariaRole","offset","isInForeground","landmark","getOffsetForeground","setWidth","setRole","getWidth","foregroundState","NavButton","_draggedOver","_dropCounter","linkAttrs","createButtonAttributes","_c","leftInjection","_getIconClass","isNavButtonSelected","hideLabel","vertical","getLabel","_isExternalUrl","href","_getNavButtonClass","route","_getUrl","centred","disableHoverBackground","small","indexOf","attr","background","persistentBackground","stateBgHover","selector","onkeyup","SPACE","dropHandler","ondragenter","preventDefault","ondragleave","ondragover","ondrop","dataTransfer","getData","set","handleUncaughtError","getHeight","header_button","isSelectedPrefix","current","attrToFirstLine","attrToSecondLine","date","isSameDayOfDate","formats","format","simpleDate","percentage","round","ToggleButton","toggledTitle","toggled","onToggled","SwipeHandler","touchArea","isAnimating","onTouchStart","startPos","onTouchMove","getDelta","directionLock","abs","onHorizontalDrag","list_row_height","reset","onTouchEnd","gestureEnd","animating","attach","passive","detach","removeEventListener","delta","onHorizontalGestureCompleted","xDelta","yDelta","changedTouches","ListSwipeHandler","config","super","virtualElement","ve","getVirtualElement","xoffset","domElement","entity","domSwipeSpacerLeft","domSwipeSpacerRight","finish","listTargetPosition","swipeDecision","chain","inOut","duration","onSwipeLeft","onSwipeRight","getRowForPosition","ListLoadingState","innerDom","containerDom","rows","currentPosition","activeIndex","VIRTUAL_LIST_LENGTH","updateStatus","memoized","status","Idle","Done","loadingIndicatorChildDom","Loading","renderLoadingIndicator","ConnectionLost","renderConnectionLostIndicator","doUpdateWidth","debounce","clientWidth","clientHeight","swipeHandler","translateX","row","applySafeAreaInsetMarginLR","oldAttrs","lastAttrs","ResizeObserver","updateSize","createSwipeHandler","onScroll","renderSwipeItems","initializeDom","updateDomElements","renderConfig","vnodes","onLoadMore","coord","el","swipe","swipeLeft","swipeRight","clientCoordiante","touchAreaOffset","relativeYPosition","targetElementPosition","floor","itemHeight","numberRange","createRow","renderStatusRow","visibleElementHeight","loadMoreIfNecessary","draggable","dragStart","createElement","setRowEventListeners","touchStartTime","now","handleEvent","ondragstart","multiselectionAllowed","timeoutId","touchStartCoords","onSingleTogglingMultiselection","pageX","pageY","touchEnd","touch","clickedEntity","changeType","inMultiselect","isMacOS","metaKey","changeSelection","onSingleSelection","onRangeSelectionTowards","rowHeight","statusHeight","loadingStatus","index","desiredPosition","visibleElementsHeight","ceil","bufferHeight","maxStartPosition","nextPosition","pos","update","has","gap","onStopLoading","retryLoading","onRetryLoading","renderLeftSpacer","renderRightSpacer","IconMessageBox","getMessage","icon_message_box","vpad_xl","bottomContent","animateToolbar","appear","childHeight","previous","selectedSize","parseInt","editor","squire","getFontInfo","browser","renderStyleButtons","renderCustomButtons","renderAlignDropDown","renderSizeButtons","renderRemoveFormattingButton","imageButtonClickHandler","renderStyleToggleButton","hasStyle","renderListToggleButton","renderToggleButton","setStyle","listing","removeList","makeUnorderedList","makeOrderedList","customButtonAttrs","alignmentEnabled","alignButtonAttrs","alignment","setTextAlignment","alignIcon","toString","setFontSize","fontSizeEnabled","removeAllFormatting","borderBottom","_hovered","count","showFullCount","onmouseenter","onmouseleave","domButton","renderLabel","lazyMemoized","Countries","selectedIndex","scrollWindowHeight","scrollOffset","selectedTop","selectedBottom","selectedRelativeBottom","isWhitelabel","getUserController","isGlobalAdmin","onInput","idx","renderBubbleText","getBubbleDropdownAttrs","onFocus","onBlur","BACKSPACE","code","onBackspace","onEnterKey","onUpKey","onDownKey","WARNING_RED","helpLink","buttonContainerStyle","marginBottom","renderIcon","icon_size_large","renderButtons","renderHelpLink","isNotNull","loading","alignments","columnAlignments","lineAttrs","_createLine","showActionButtonColumn","columnWidths","columnHeading","cells","textIdOrFunction","actionButtonAttrs","addButtonAttrs","verticalColumnHeadings","verticalText","cellTextData","mainStyle","main","button_height_compact","options","option","_renderOption","selectedOption","onOptionSelected","helpText","_closeWizardDialogListener","_showNextWizardDialogPageListener","currentPage","nextAction","ready","goToNextPageOrCloseWizard","_getEnabledPages","hideAllPagingButtons","page","hidePagingButtonForPage","p","WizardPagingButton","pageIndex","getSelectedPageIndex","isClickable","allowedToVisitPage","navigateBackHandler","_goToPageAction","_headerBarAttrs","isEnabled","updateHeaderBarAttrs","goToPreviousPageOrClose","currentPageIndex","backButtonAttrs","skipButtonAttrs","isSkipAvailable","headerTitle","targetIndex","currentIndex","lastIndex","selectedPageIndex","enabledPages","preventGoBack","filledBg","isFocused","onWrapperCreated","onmousedown","onSearchClick","renderInputField","onClear","busy","onInputCreated","onKeyDown","flex","itemMaxWidth","_onSelected","onValueSelected","onValueChange","NotFoundPage","history","back","_viewDom","_onChangePage","onChangePage","_swipeHandler","PageSwipeHandler","previousPage","offsetWidth","nodes","nextPage","onGestureCompleted","_xoffset","transformStyle","backfaceVisibility","_onGestureCompleted","padding"],"mappings":"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"}