{
  "version": 3,
  "sources": ["../../drag_and_drop.tsx"],
  "sourcesContent": ["import {\n    AddCard,\n    AddCardValue,\n    as_CardUID,\n    Board,\n    BoardUID,\n    Card,\n    CardChangelogEntry,\n    CardPatchOpType,\n    CardUID,\n    Column,\n    ColumnCard,\n    create_CardUID,\n    EngagementType,\n    InboxCard,\n    is_BoardUID,\n    MoveCard,\n    RemoveCard,\n} from \"@cling/lib.shared.model\"\nimport * as React from \"react\"\nimport {observer} from \"mobx-react\"\nimport {report_error, report_info} from \"@cling/lib.shared.debug\"\nimport {action, observable, runInAction, makeObservable} from \"mobx\"\nimport {current_user, ui_actions, ui_state} from \"./state/index\"\nimport {assert, safe_to_string} from \"@cling/lib.shared.utils\"\nimport {log} from \"@cling/lib.shared.logging\"\nimport {board_resource} from \"@cling/lib.web.resources\"\nimport {Snackbar} from \"@cling/lib.web.mdc\"\nimport {i18n} from \"@cling/lib.web.i18n\"\nimport {optimistic_update} from \"./state/patch\"\nimport {report_user_engagement} from \"@cling/lib.web.analytics\"\n\nconst MIN_DRAG_DISTANCE = 11\nconst ADD_NEW_COLUMN_AREA_WIDTH = 50\nconst ADD_NEW_COLUMN_DELAY = 250\nconst SCROLL_DELAY = 300\n\nlet current_ghost: any\n\ntype Props = {\n    render_card: React.ComponentType<{\n        card: Card\n        dnd_ghost_ref: (ref: ReactRef<HTMLDivElement>) => void\n    }>\n}\n\nexport const DragAndDropGhost = observer(\n    class DragAndDropGhost extends React.Component<Props> {\n        static readonly instance: DragAndDropGhost\n\n        drag_and_drop?: DragAndDrop = undefined\n        dom_node: ReactRef<HTMLDivElement>\n        left?: string\n        top?: string\n        width?: string\n\n        constructor(props: any) {\n            super(props)\n            makeObservable<DragAndDropGhost, \"drag_and_drop\">(this, {\n                drag_and_drop: observable.ref,\n                on_drag_and_drop_started: action,\n                reset: action,\n            })\n        }\n\n        on_drag_and_drop_started(drag_and_drop: DragAndDrop) {\n            this.left = \"\"\n            this.top = \"\"\n            this.width = \"\"\n            this.drag_and_drop = drag_and_drop\n        }\n\n        update_ghost_ref = (ref: ReactRef<HTMLDivElement>) => {\n            this.dom_node = ref\n            if (ref) {\n                const {style} = ref\n                const {left, top, width} = this\n                if (left) {\n                    style.left = left\n                }\n                if (top) {\n                    style.top = top\n                }\n                if (width) {\n                    style.width = width\n                }\n            }\n        }\n\n        move_to = (x: number, y: number) => {\n            this.left = x + \"px\"\n            this.top = y + \"px\"\n            if (this.dom_node) {\n                const {style} = this.dom_node\n                style.left = this.left\n                style.top = this.top\n            }\n        }\n\n        set_width = (w: number) => {\n            this.width = w + \"px\"\n            if (this.dom_node) {\n                const {style} = this.dom_node\n                style.width = this.width\n            }\n        }\n\n        reset() {\n            this.left = \"\"\n            this.top = \"\"\n            this.width = \"\"\n            this.drag_and_drop = undefined\n        }\n\n        componentDidMount() {\n            if (current_ghost) {\n                report_error(\"DragAndDropGhost already mounted\")\n            }\n            // eslint-disable-next-line @typescript-eslint/no-this-alias\n            current_ghost = this\n            cling.drag_and_drop_ready = true\n        }\n\n        componentWillUnmount() {\n            current_ghost = undefined as any\n        }\n\n        render() {\n            const {drag_and_drop} = this\n            if (!drag_and_drop) {\n                return null\n            }\n            const {ghost_card} = drag_and_drop\n            return React.createElement(this.props.render_card, {\n                card: ghost_card,\n                dnd_ghost_ref: this.update_ghost_ref,\n            })\n        }\n    },\n)\n\n/**\n * @param ignore_click_at A callback, which will be called on `mouseup` if the mouse cursor\n *                        was moved at least 10 pixels while the left mouse button was pressed\n */\nexport function start_drag_card(\n    mousedown_event: React.MouseEvent<any>,\n    card_uid: CardUID,\n    ignore_click_at: (timestamp: number) => void,\n) {\n    if (!current_ghost) {\n        report_error(\"DragAndDropGhost not mounted\")\n        return\n    }\n    const dragged_card_elm = (mousedown_event.target as HTMLElement).closest(\n        \".dnd__card\",\n    ) as HTMLElement | null\n    if (!dragged_card_elm) {\n        return\n    }\n    assert(\n        dragged_card_elm.dataset.cardUid === card_uid,\n        \"dragged_card_elm.dataset.cardUid !== card_uid\",\n    )\n    let source: DragSource\n    try {\n        source = determine_source(card_uid, dragged_card_elm)\n        // Prevent that text is selected ...\n        mousedown_event.stopPropagation()\n        mousedown_event.preventDefault()\n        // Ignore margins of dragged card div ...\n        const dragged_card_rect = dragged_card_elm\n            .querySelector(\".mdc-card\")!\n            .getBoundingClientRect()\n        const dragged_card_width = dragged_card_rect.width\n        let ignore_click = false\n        let drag_and_drop: DragAndDrop\n        let move_ghost_request_id: any = 0\n        let mouse_cursor_x: number\n        let mouse_cursor_y: number\n        const {clientX: x0, clientY: y0} = mousedown_event\n        const grabbed_at = {\n            x: x0 - dragged_card_rect.left,\n            y: y0 - dragged_card_rect.top,\n        }\n        const move_ghost = () => {\n            move_ghost_request_id = 0\n            if (drag_and_drop) {\n                current_ghost.move_to(mouse_cursor_x - grabbed_at.x, mouse_cursor_y - grabbed_at.y)\n            }\n        }\n        const handle_error = <T extends Event>(f: (event: T) => void) => {\n            return (event: T) => {\n                try {\n                    f(event)\n                } catch (error) {\n                    if (drag_and_drop) {\n                        remove_event_listeners()\n                        drag_and_drop.on_error(error)\n                    } else {\n                        throw error\n                    }\n                }\n            }\n        }\n        const on_mousemove = handle_error((event: MouseEvent) => {\n            mouse_cursor_x = event.clientX\n            mouse_cursor_y = event.clientY\n            if (!move_ghost_request_id) {\n                move_ghost_request_id = requestAnimationFrame(move_ghost)\n            }\n            if (drag_and_drop) {\n                drag_and_drop.on_drag(event)\n            } else {\n                const d = Math.max(Math.abs(mouse_cursor_x - x0), Math.abs(mouse_cursor_y - y0))\n                if (d >= MIN_DRAG_DISTANCE) {\n                    ignore_click = true\n                    document.body.classList.add(\"dnd--dragging\")\n                    runInAction(() => {\n                        drag_and_drop = new DragAndDrop(current_ghost, source, grabbed_at, event)\n                        ;(cling as any).drag_and_drop = drag_and_drop\n                        ui_actions.disable_card_menus()\n                        current_ghost.set_width(dragged_card_width)\n                        current_ghost.move_to(\n                            mouse_cursor_x - grabbed_at.x,\n                            mouse_cursor_y - grabbed_at.y,\n                        )\n                    })\n                }\n            }\n        })\n        const on_mouseup = handle_error((event: MouseEvent) => {\n            remove_event_listeners()\n            if (drag_and_drop) {\n                ui_actions.enable_card_menus()\n                event.stopPropagation()\n                event.preventDefault()\n                if (move_ghost_request_id) {\n                    cancelAnimationFrame(move_ghost_request_id)\n                }\n                if (ignore_click) {\n                    ignore_click_at(event.timeStamp)\n                }\n                drag_and_drop.on_drop(event)\n            }\n        })\n        const on_keydown = handle_error((event: KeyboardEvent) => {\n            if (drag_and_drop) {\n                if (event.key === \"Escape\" || event.key === \"Esc\") {\n                    event.stopPropagation()\n                    event.preventDefault()\n                    remove_event_listeners()\n                    ui_actions.enable_card_menus()\n                    drag_and_drop.abort({reason: \"Esc key pressed\"})\n                }\n            }\n        })\n        const on_window_blur = handle_error(() => {\n            remove_event_listeners()\n            if (drag_and_drop) {\n                drag_and_drop.abort({reason: \"Browser tab lost focus\"})\n            }\n        })\n        document.addEventListener(\"mousemove\", on_mousemove, true)\n        document.addEventListener(\"mouseup\", on_mouseup, true)\n        document.addEventListener(\"keydown\", on_keydown, true)\n        addEventListener(\"blur\", on_window_blur)\n        const remove_event_listeners = () => {\n            document.removeEventListener(\"mousemove\", on_mousemove, true)\n            document.removeEventListener(\"mouseup\", on_mouseup, true)\n            document.removeEventListener(\"keydown\", on_keydown, true)\n            removeEventListener(\"blur\", on_window_blur)\n        }\n        // For testing purposes ...\n        return {on_mousemove, on_mouseup, on_keydown}\n    } catch (error) {\n        report_error(\"start_drag_card(...) failed\", error)\n        return\n    }\n}\n\ntype DragSource = Readonly<{\n    readonly board: Board\n    /**\n     * The top level card containing the dragged card as descendant when dragging started.\n     */\n    readonly top_level_card: ColumnCard | InboxCard\n    /** The parent card of the dragged card when dragging started. */\n    readonly parent_card: Card\n    /** The index of the dragged card in `this.parent_card.children` when dragging started. */\n    readonly index_of_dragged_card: number\n    readonly dragged_card: Card\n}>\n\ntype DragTarget =\n    | {\n          readonly board: Board\n          readonly new_column?: never\n          readonly top_level_card: ColumnCard | InboxCard\n          readonly parent_card: Card\n          /** The index of the dragged card in `this.parent_card.children`. */\n          readonly index_of_dragged_card: number\n      }\n    | {\n          readonly board: Board\n          readonly new_column: true\n          /* The new column card. */\n          readonly top_level_card: ColumnCard\n          /** The index of the new column card in `this.board.root.children`. */\n          readonly index_of_new_column_card: number\n          readonly parent_card?: never\n          readonly index_of_dragged_card?: never\n      }\n\ninterface GrabbedAt {\n    x: number\n    y: number\n}\n\ninterface ScrollOnDragArea {\n    is_inside: (x: number, y: number) => boolean\n    scroll: (delta: number) => void\n}\n\nfunction _scroll_horizontal() {\n    let _block_horizontal_scroll = false\n    function scroll(dir: \"left\" | \"right\") {\n        if (_block_horizontal_scroll) {\n            return\n        }\n        if (dir === \"right\") {\n            ui_state.layout_state.scroll_to_column(\n                ui_state.layout_state.first_visible_column_index + 1,\n            )\n        } else {\n            ui_state.layout_state.scroll_to_column(\n                ui_state.layout_state.first_visible_column_index - 1,\n            )\n        }\n        _block_horizontal_scroll = true\n        setTimeout(() => (_block_horizontal_scroll = false), 500)\n    }\n    return {scroll_left: () => scroll(\"left\"), scroll_right: () => scroll(\"right\")}\n}\n\nfunction _scroll_up(elm: HTMLElement, delta: number): void {\n    const scroll_top = elm.scrollTop\n    if (scroll_top > delta) {\n        elm.scrollTop = scroll_top - delta\n    } else if (scroll_top > 0) {\n        elm.scrollTop = 0\n    }\n}\n\nfunction _scroll_down(elm: HTMLElement, delta: number): void {\n    const scroll_top = elm.scrollTop\n    const max_scroll_top = elm.scrollHeight - elm.getBoundingClientRect().height\n    if (scroll_top < max_scroll_top - delta) {\n        elm.scrollTop = scroll_top + delta\n    } else if (scroll_top < max_scroll_top) {\n        elm.scrollTop = max_scroll_top\n    }\n}\n\ninterface BoundingClientRect {\n    readonly bottom: number\n    readonly height: number\n    readonly left: number\n    readonly right: number\n    readonly top: number\n    readonly width: number\n}\n\nclass DragAndDrop {\n    readonly dragged_card: Card\n    readonly ghost_card: Card\n    readonly grabbed_at: GrabbedAt\n    target: DragTarget\n    private readonly desc: string\n    private readonly dragged_card_descendants_uids: Set<CardUID>\n    private pending_add_new_column_key?: string\n    private pending_add_new_column_timeout_id: any\n    private aborted = false\n    private on_drop_called = false\n    private mouse_cursor_x = 0\n    private mouse_cursor_y = 0\n    private sync_model_timeout_id: any\n    private scroll_horizontal_on_drag_areas: Array<ScrollOnDragArea> = []\n    private active_scroll_horizontal_drag_area?: ScrollOnDragArea\n    private scroll_horizontal_start_time?: number\n    private scroll_vertical_on_drag_areas: Array<ScrollOnDragArea> = []\n    private active_scroll_vertical_drag_area?: ScrollOnDragArea\n    private scroll_vertical_start_time?: number\n    private scroll_on_drag_interval_id?: any\n    private new_column_card_uid?: CardUID\n    private ghost_rect_when_moved?: BoundingClientRect\n    private get_card_cache = new Map<string, Card>()\n\n    constructor(\n        private ghost: any,\n        public readonly source: DragSource,\n        grabbed_at?: GrabbedAt,\n        mouse_down_event?: MouseEvent,\n    ) {\n        const {board, top_level_card, parent_card, index_of_dragged_card, dragged_card} = source\n        this.dragged_card = dragged_card\n        this.desc = `dragged card ${dragged_card.uid}`\n        this.ghost_card = new Card({\n            ...dragged_card,\n            children: dragged_card.children.slice(0, dragged_card.children.length),\n        })\n        ;(this.ghost_card as any)._parent = dragged_card.parent\n        this.dragged_card_descendants_uids = new Set(dragged_card.deep_children.map((c) => c.uid))\n        this.target = {board, top_level_card, parent_card, index_of_dragged_card}\n        this.assert_consistent_state()\n        log.debug(`[dnd] Dragging card ${dragged_card.uid} ...`, {source: this.source})\n        this.grabbed_at = grabbed_at || {x: 20, y: 8}\n        ui_state.layout_state.freeze_layout()\n        if (mouse_down_event) {\n            this.on_drag(mouse_down_event)\n        }\n        // Setup scroll on drag in another time slice ...\n        setTimeout(this.setup_scroll_on_drag, 1)\n        dragged_card._is_dragged = this\n        ghost.on_drag_and_drop_started(this)\n    }\n\n    assert_consistent_state() {\n        const {dragged_card, target} = this\n        if (target.new_column) {\n            const {board, top_level_card: new_column_card, index_of_new_column_card: index} = target\n            assert(\n                board === ui_state.current_board.board,\n                \"Invalid target: new_column && board !== ui_state.current_board\",\n            )\n            assert(\n                board.root.children[index] === new_column_card,\n                \"Invalid target: board.root.children[index_of_new_column_card] !== new_column_card\",\n            )\n            assert(\n                new_column_card.parent === board.root,\n                \"Invalid state: new_column_card.parent !== board.root\",\n            )\n            assert(new_column_card.column, \"Invalid state: !new_column_card.column\")\n            assert(\n                new_column_card.uid === this.new_column_card_uid,\n                \"Invalid state: new_column_card.uid !== this.new_column_card_uid\",\n            )\n            const n = new_column_card.children.length\n            assert(n === 1, `Invalid state: new_column_card.children.length === ${n}`)\n            assert(\n                new_column_card.children[0] === dragged_card,\n                `Invalid state: new_column_card.children[0] !== dragged_card`,\n            )\n            assert(\n                dragged_card.parent === new_column_card,\n                `Invalid state: dragged_card.parent !== new_column_card`,\n            )\n        } else {\n            const {board, top_level_card, parent_card, index_of_dragged_card: index} = target\n            assert(\n                board.root.children.some((c) => c === top_level_card),\n                \"Invalid target: top_level_card is not in board.root.children\",\n            )\n            assert(\n                top_level_card.parent === board.root,\n                \"Invalid state: top_level_card.parent !== board.root\",\n            )\n            assert(\n                parent_card.children.length > index,\n                \"Invalid target: parent_card.children.length <= index_of_dragged_card\",\n            )\n            assert(\n                parent_card.children[index] === dragged_card,\n                \"Invalid target: parent_card.children[index_of_dragged_card] !== dragged_card\",\n            )\n            assert(parent_card !== board.root, \"Invalid state: parent_card === board.root\")\n            // `parent_card` must be either `top_level_card` or a descendant of `top_level_card` ...\n            let level = parent_card.level\n            assert(level > 0, `Invalid state: parent_card.level === ${level}`)\n            let temp = parent_card\n            while (level > 1) {\n                temp = temp.parent\n                --level\n                assert(temp.level === level, \"temp.parent has unexpected level\")\n            }\n            assert(\n                temp === top_level_card,\n                \"Invalid state: parent_card is not (descendant of) top_level_card\",\n            )\n        }\n    }\n\n    /**\n     * Returns `true` if the DOM reflects the current model.\n     */\n    is_DOM_in_sync_with_model(preview_elm: HTMLElement) {\n        const preview_column_elm = preview_elm.closest(\".dnd__column\") as HTMLElement\n        assert(\n            preview_column_elm,\n            `preview_elm.closest(\".dnd__column\") returned: ${preview_column_elm}`,\n        )\n        const preview_board = determine_board(preview_elm)\n        const preview_top_level_card = determine_top_level_card(preview_board, preview_column_elm)\n        const {target} = this\n        if (preview_board !== target.board) {\n            return false\n        }\n        if (preview_top_level_card !== target.top_level_card) {\n            return false\n        }\n        if (target.new_column) {\n            return true\n        }\n        try {\n            const {elm: preview_parent_elm, card: preview_parent_card} = determine_parent(\n                preview_board,\n                preview_elm,\n            )\n            if (preview_parent_card !== target.parent_card) {\n                return false\n            }\n            const model_children_uids = preview_parent_card.children.map((card) => card.uid)\n            const dragged_card_uid = this.dragged_card.uid\n            assert(\n                model_children_uids[target.index_of_dragged_card] === dragged_card_uid,\n                \"model_children_uids[target.index_of_dragged_card] !== dragged_card_uid\",\n            )\n            const temp = new Set(model_children_uids)\n            const dom_children_uids = (\n                [...preview_parent_elm.querySelectorAll(\".dnd__card\")] as HTMLElement[]\n            )\n                .map((elm) => elm.dataset.cardUid as CardUID)\n                .filter((uid) => temp.has(uid))\n            // Note: `model_children_uids` might contain more items because of archived cards,\n            //       therefore we check only the order here ...\n            const uids_above = new Set(model_children_uids.splice(0, target.index_of_dragged_card))\n            const uids_below = new Set(model_children_uids)\n            let visited_dragged_card_uid = false\n            for (const uid of dom_children_uids) {\n                if (uid === dragged_card_uid) {\n                    visited_dragged_card_uid = true\n                } else {\n                    const set = visited_dragged_card_uid ? uids_below : uids_above\n                    if (!set.has(uid)) {\n                        return false\n                    }\n                }\n            }\n            return true\n        } catch (error) {\n            log.debug(\"[dnd] DragAndDrop.is_DOM_in_sync failed\", error)\n            return false\n        }\n    }\n\n    setup_scroll_on_drag = () => {\n        this.init_scroll_horizontal_on_drag_areas()\n        this.init_scroll_vertical_on_drag_areas()\n        const scroll_on_drag_interval_handler = () => {\n            if (this.active_scroll_horizontal_drag_area) {\n                const ms = performance.now() - this.scroll_horizontal_start_time!\n                if (ms > SCROLL_DELAY) {\n                    const delta = Math.min((ms - SCROLL_DELAY) / 20, 250)\n                    this.active_scroll_horizontal_drag_area.scroll(delta)\n                }\n            }\n            if (this.active_scroll_vertical_drag_area) {\n                const ms = performance.now() - this.scroll_vertical_start_time!\n                if (ms > SCROLL_DELAY) {\n                    const delta = Math.min((ms - SCROLL_DELAY) / 20, 250)\n                    this.active_scroll_vertical_drag_area.scroll(delta)\n                }\n            }\n        }\n        this.scroll_on_drag_interval_id = setInterval(scroll_on_drag_interval_handler, 33)\n    }\n\n    init_scroll_horizontal_on_drag_areas() {\n        const {scroll_left, scroll_right} = _scroll_horizontal()\n        this.scroll_horizontal_on_drag_areas.push({\n            is_inside: (x) => {\n                const layout = ui_state.layout_state.layout\n                let min = 50\n                if (layout.aux_layout.visible) {\n                    min += layout.aux_layout.column_width\n                }\n                if (ui_state.desktop_board_chooser_state !== \"hidden\") {\n                    min += 305\n                }\n                return x < min\n            },\n            scroll: scroll_left,\n        })\n        this.scroll_horizontal_on_drag_areas.push({\n            is_inside: (x: number) => {\n                let min = ui_state.layout_state.view_port_width\n                if (!min) {\n                    return false\n                }\n                min = Math.max(min - 50, 0)\n                if (ui_state.desktop_board_chooser_state !== \"hidden\") {\n                    min += 305\n                }\n                return x > min\n            },\n            scroll: scroll_right,\n        })\n    }\n\n    init_scroll_vertical_on_drag_areas() {\n        const elements = document.getElementsByClassName(\"dnd--scroll-vertically\")\n        const n = elements.length\n        if (!n) {\n            log.warn(\"No elements with CSS class 'dnd--scroll-vertically'\")\n            return\n        }\n        for (let i = 0; i < n; ++i) {\n            const elm = elements.item(i) as HTMLElement\n            const r = elm.getBoundingClientRect()\n            const y_scroll_up = r.top + Math.min(r.height * 0.15, 100)\n            this.scroll_vertical_on_drag_areas.push({\n                is_inside: (x, y) => {\n                    const {left, right} = elm.getBoundingClientRect()\n                    return x >= left && x < right && y < y_scroll_up\n                },\n                scroll: _scroll_up.bind(null, elm),\n            })\n            const y_scroll_down = r.bottom - Math.min(r.height * 0.15, 100)\n            this.scroll_vertical_on_drag_areas.push({\n                is_inside: (x, y) => {\n                    const {left, right} = elm.getBoundingClientRect()\n                    return x >= left && x < right && y > y_scroll_down\n                },\n                scroll: _scroll_down.bind(null, elm),\n            })\n        }\n    }\n\n    on_drag(event: MouseEvent) {\n        const {aborted} = this\n        if (aborted) {\n            return\n        }\n        const x = event.clientX\n        const y = event.clientY\n        this.mouse_cursor_x = x\n        this.mouse_cursor_y = y\n        // Check if we must update `this.active_scroll_horizontal_drag_area`\n        // and `this.scroll_horizontal_start_time` ...\n        const h = this.active_scroll_horizontal_drag_area\n        if (!(h && h.is_inside(x, y))) {\n            this.active_scroll_horizontal_drag_area = undefined\n            for (const area of this.scroll_horizontal_on_drag_areas) {\n                if (area.is_inside(x, y)) {\n                    this.active_scroll_horizontal_drag_area = area\n                    this.scroll_horizontal_start_time = performance.now()\n                    break\n                }\n            }\n        }\n        // Check if we must update `this.active_scroll_vertical_drag_area`\n        // and `this.scroll_vertical_start_time` ...\n        const v = this.active_scroll_vertical_drag_area\n        if (!(v && v.is_inside(x, y))) {\n            this.active_scroll_vertical_drag_area = undefined\n            for (const area of this.scroll_vertical_on_drag_areas) {\n                if (area.is_inside(x, y)) {\n                    this.active_scroll_vertical_drag_area = area\n                    this.scroll_vertical_start_time = performance.now()\n                    break\n                }\n            }\n        }\n        // Syncing the model is CPU intensive, therefore we schedule it after 50 ms ...\n        if (!this.sync_model_timeout_id) {\n            this.sync_model_timeout_id = setTimeout(this.sync_model, 50)\n        }\n    }\n\n    on_drop(event?: MouseEvent) {\n        const t0 = performance.now()\n        try {\n            this.on_drop_called = true\n            if (this.aborted) {\n                return\n            }\n            if (this.board_changed()) {\n                this.abort({reason: \"Board changed during drag & drop\", report: true})\n                return\n            }\n            clearInterval(this.scroll_on_drag_interval_id)\n            let card_moved = false\n            runInAction(() => {\n                this.ghost.reset()\n                // Note: During testing the \"pointerUp\" action will lead to a \"mouseup\" event\n                //       with the coordinates 0, 0 ...\n                if (event && (event.clientX !== 0 || event.clientY !== 0)) {\n                    this.on_drag(event)\n                }\n                if (this.sync_model_timeout_id) {\n                    clearTimeout(this.sync_model_timeout_id)\n                    this.sync_model()\n                }\n                this.dragged_card._is_dragged = undefined\n                const {dragged_card, source, target} = this\n                card_moved =\n                    target.new_column ||\n                    source.parent_card !== target.parent_card ||\n                    source.index_of_dragged_card !== target.index_of_dragged_card\n                log.debug(`[dnd] Dropped ${this.desc}${card_moved ? \"\" : \" at source location\"}`)\n                this.cancel_pending_add_new_column()\n                if (card_moved) {\n                    this.restore_state()\n                    if (target.new_column) {\n                        const {top_level_card: new_column_card, index_of_new_column_card} = target\n                        optimistic_update(\n                            target.board.uid,\n                            new AddCard({\n                                value: new AddCardValue({\n                                    uid: new_column_card.uid,\n                                    column: new Column({}),\n                                }),\n                                target_card_uid: target.board.root.uid,\n                                target_pos: index_of_new_column_card,\n                            }),\n                        )\n                        optimistic_update(\n                            source.board.uid,\n                            new MoveCard({\n                                uid: dragged_card.uid,\n                                target_board_uid: target.board.uid,\n                                target_card_uid: new_column_card.uid,\n                                target_pos: 0,\n                            }),\n                        )\n                    } else {\n                        const {parent_card, index_of_dragged_card} = target\n                        optimistic_update(\n                            source.board.uid,\n                            new MoveCard({\n                                uid: dragged_card.uid,\n                                target_board_uid: target.board.uid,\n                                target_card_uid: parent_card.uid,\n                                target_pos: index_of_dragged_card,\n                            }),\n                        )\n                    }\n                    report_user_engagement(EngagementType.move_card)\n                    const undo_op = new MoveCard({\n                        uid: dragged_card.uid,\n                        target_board_uid: source.board.uid,\n                        target_card_uid: source.parent_card.uid,\n                        target_pos: source.index_of_dragged_card,\n                    })\n                    Snackbar.show_message(\n                        i18n.moved_cards(1 + dragged_card.num_deep_children),\n                        i18n.undo,\n                        () => {\n                            optimistic_update(target.board.uid, undo_op)\n                            if (target.new_column) {\n                                const {top_level_card: new_column_card} = target\n                                optimistic_update(\n                                    target.board.uid,\n                                    new RemoveCard({uid: new_column_card.uid}),\n                                )\n                            }\n                        },\n                    )\n                }\n            })\n        } finally {\n            const dt = performance.now() - t0\n            if (dt > 500) {\n                report_info(`DragAndDrop.on_drop() took very long: ${Math.round(dt)} ms`)\n            }\n            ui_state.layout_state.unfreeze_layout()\n            ;(cling as any).drag_and_drop = undefined\n            document.body.classList.remove(\"dnd--dragging\")\n        }\n    }\n\n    abort({reason, report, error}: {reason: string; report?: true; error?: Error}) {\n        const m = `[dnd] ${reason}${this.aborted ? \"\" : \" -- aborting drag & drop\"}`\n        if (error) {\n            report_error(m, error)\n        } else if (report) {\n            report_info(m)\n        } else {\n            log.info(m)\n        }\n        if (this.aborted) {\n            return\n        }\n        this.aborted = true\n        clearInterval(this.scroll_on_drag_interval_id)\n        this.cancel_pending_add_new_column()\n        runInAction(() => {\n            this.ghost.reset()\n            this.dragged_card._is_dragged = undefined\n            this.restore_state()\n        })\n        ui_state.layout_state.unfreeze_layout()\n        ;(cling as any).drag_and_drop = undefined\n        document.body.classList.remove(\"dnd--dragging\")\n    }\n\n    on_error(error: Error) {\n        this.abort({\n            reason: `Error while ${this.on_drop_called ? \"dropping\" : \"dragging\"} card`,\n            error,\n        })\n    }\n\n    sync_model = () => {\n        const t0 = performance.now()\n        try {\n            if (this.aborted) {\n                return\n            }\n            if (this.board_changed()) {\n                this.abort({reason: \"Board changed during drag & drop\"})\n                return\n            }\n            const ghost_elm = document.querySelector(\".dnd__ghost\") as HTMLElement\n            if (!ghost_elm) {\n                log.debug(\"[dnd] Ghost not mounted\")\n                return\n            }\n            const preview_elm = document.querySelector(\".dnd__preview\") as HTMLElement\n            if (!preview_elm) {\n                log.debug(\"[dnd] Preview not mounted\")\n                return\n            }\n            if (!this.is_DOM_in_sync_with_model(preview_elm)) {\n                log.debug(\"[dnd] DOM not in sync with model\")\n                return\n            }\n            let ghost_rect = ghost_elm.getBoundingClientRect() as BoundingClientRect\n            // The ghost might be smaller than the grabbed card, fix `grabbed_at` if needed ...\n            const {mouse_cursor_x: x, mouse_cursor_y: y, grabbed_at} = this\n            let move_ghost = false\n            if (grabbed_at.x > ghost_rect.width) {\n                grabbed_at.x = ghost_rect.width\n                move_ghost = true\n            }\n            if (grabbed_at.y < 0) {\n                grabbed_at.y = 0\n            }\n            if (grabbed_at.y > ghost_rect.height) {\n                grabbed_at.y = ghost_rect.height\n                move_ghost = true\n            }\n            const ghost_left = x - grabbed_at.x\n            const ghost_top = y - grabbed_at.y\n            const {width: ghost_width, height: ghost_height} = ghost_rect\n            ghost_rect = {\n                left: ghost_left,\n                width: ghost_width,\n                right: ghost_left + ghost_width,\n                top: ghost_top,\n                height: ghost_height,\n                bottom: ghost_top + ghost_height,\n            }\n            if (move_ghost && this.ghost) {\n                this.ghost.move_to(ghost_left, ghost_top)\n            }\n            // Prevent flickering ...\n            if (\n                this.ghost_rect_when_moved &&\n                Math.abs(this.ghost_rect_when_moved.left - ghost_rect.left) < 5 &&\n                Math.abs(this.ghost_rect_when_moved.top - ghost_rect.top) < 5\n            ) {\n                // Do nothing.\n                return\n            }\n            // Update model if needed ...\n            const {target} = this\n            const a = [...document.querySelectorAll(\".dnd__column\")] as HTMLElement[]\n            let max_i = a.length - 1\n            // We must first check, if the mouse cursor is over the aux column ...\n            if (a[max_i].id === \"dnd__aux-column\") {\n                const column_elm = a.pop()!\n                const r = column_elm.getBoundingClientRect()\n                if (x < r.right) {\n                    // Jep, drag & drop target is the aux column ...\n                    const board = determine_board(column_elm)\n                    const inbox_card = determine_top_level_card(board, column_elm)\n                    assert(inbox_card.inbox, \"Top level card of aux column is not an inbox card\")\n                    if (target.top_level_card === inbox_card) {\n                        this.move_card_in_column(\n                            board,\n                            inbox_card,\n                            column_elm,\n                            ghost_rect,\n                            preview_elm,\n                        )\n                    } else {\n                        this.move_card_to_another_column(board, inbox_card, column_elm, ghost_rect)\n                    }\n                    return\n                }\n                --max_i\n            }\n            for (let i = 0; i <= max_i; ++i) {\n                let column_elm = a[i]\n                const r = column_elm.getBoundingClientRect()\n                if ((i === 0 || x >= r.left) && (x < r.right || i === max_i)) {\n                    const board = determine_board(column_elm)\n                    let top_level_card = determine_top_level_card(board, column_elm)\n                    assert(\n                        top_level_card.column || top_level_card.inbox,\n                        \"Top level card is neither a column nor an inbox card\",\n                    )\n                    if (\n                        target.new_column &&\n                        target.top_level_card === top_level_card &&\n                        x >= r.left + r.width / 2 &&\n                        i < max_i - 1\n                    ) {\n                        // Special case: We just inserted a new column before an existing column\n                        // and the mouse cursor is over the right half of the new column -- move\n                        // the dragged card into the next column (removing the new column) ...\n                        column_elm = a[i + 1]\n                        top_level_card = determine_top_level_card(board, column_elm)\n                        this.move_card_to_another_column(\n                            board,\n                            top_level_card,\n                            column_elm,\n                            ghost_rect,\n                        )\n                        return\n                    }\n                    // Special cases for inserting a new column ...\n                    if (x < r.left + ADD_NEW_COLUMN_AREA_WIDTH / 2) {\n                        if (target.new_column) {\n                            // Do nothing.\n                        } else {\n                            this.move_card_to_new_column(board, {before: top_level_card})\n                        }\n                        return\n                    } else if (x >= r.right - ADD_NEW_COLUMN_AREA_WIDTH / 2) {\n                        if (target.new_column) {\n                            // Do nothing.\n                        } else {\n                            this.move_card_to_new_column(board, {after: top_level_card})\n                        }\n                        return\n                    }\n                    if (target.top_level_card === top_level_card) {\n                        this.move_card_in_column(\n                            board,\n                            top_level_card,\n                            column_elm,\n                            ghost_rect,\n                            preview_elm,\n                        )\n                    } else {\n                        this.move_card_to_another_column(\n                            board,\n                            top_level_card,\n                            column_elm,\n                            ghost_rect,\n                        )\n                    }\n                    return\n                }\n            }\n            // If this point is reached, we just removed the new column\n            // and the animation, which moves the remaining columns to\n            // their correct location has not finished yet -- do nothing.\n        } catch (error) {\n            this.on_error(error)\n        } finally {\n            this.sync_model_timeout_id = 0\n            const dt = performance.now() - t0\n            if (dt > 500) {\n                report_info(`DragAndDrop.sync_model() took very long: ${Math.round(dt)} ms`)\n            }\n        }\n    }\n\n    private move_card_to_new_column(board: Board, where: {before: Card}): void\n    private move_card_to_new_column(board: Board, where: {after: Card}): void\n    private move_card_to_new_column(board: Board, where: {first_column: true}): void\n    private move_card_to_new_column(\n        board: Board,\n        {before, after, first_column}: {before?: Card; after?: Card; first_column?: true},\n    ): void {\n        const key = before\n            ? `before ${before.uid}`\n            : after\n              ? `after ${after.uid}`\n              : first_column\n                ? \"first_column\"\n                : (() => {\n                      throw new Error(\"Invalid `where`\")\n                  })()\n        if (this.pending_add_new_column_key === key) {\n            return\n        }\n        const add_new_column = () => {\n            try {\n                this.pending_add_new_column_key = \"\"\n                if (this.aborted || this.on_drop_called) {\n                    report_error(\"cancel_pending_add_new_column() not called\")\n                    return\n                }\n                log.debug(`[dnd] Moving ${this.desc} to new column ...`)\n                if (!this.new_column_card_uid) {\n                    this.new_column_card_uid = create_CardUID()\n                }\n                runInAction(() => {\n                    const dragged_card = this.remove_preview()\n                    let index: number\n                    if (before) {\n                        index = board.root.children.findIndex((c) => c === before)\n                        assert(index >= 0, \"Did not find column card `before`\")\n                    } else if (after) {\n                        index = board.root.children.findIndex((c) => c === after) + 1\n                        assert(index > 0, \"Did not find column card `after`\")\n                    } else {\n                        index = 0\n                    }\n                    assert(this.new_column_card_uid)\n                    const new_column_card = new Card({\n                        uid: this.new_column_card_uid,\n                        changelog: [\n                            new CardChangelogEntry({\n                                patch_op_type: CardPatchOpType.AddCard,\n                                board_version: board.version,\n                                account_uid: current_user.account.uid,\n                                date: new Date(),\n                            }),\n                        ],\n                        column: new Column({}),\n                        children: [dragged_card],\n                    }) as ColumnCard\n                    board.root.children.splice(index, 0, new_column_card)\n                    ;(new_column_card as any)._parent = board.root\n                    ;(dragged_card as any)._parent = new_column_card\n                    this.target = {\n                        board,\n                        new_column: true,\n                        top_level_card: new_column_card,\n                        index_of_new_column_card: index,\n                    }\n                    this.assert_consistent_state()\n                    log.debug(`[dnd] Moved ${this.desc} to new column`)\n                    this.ghost_rect_when_moved = undefined\n                })\n            } catch (error) {\n                this.on_error(error)\n            }\n        }\n        // For a better UX, we do not immediately create a new column, but wait a little bit ...\n        log.debug(`[dnd] Defer moving ${this.desc} to new column ...`)\n        this.cancel_pending_add_new_column()\n        this.pending_add_new_column_key = key\n        this.pending_add_new_column_timeout_id = setTimeout(add_new_column, ADD_NEW_COLUMN_DELAY)\n    }\n\n    private cancel_pending_add_new_column() {\n        if (this.pending_add_new_column_key) {\n            log.debug(`[dnd] Canceled moving ${this.desc} to new column`)\n            this.pending_add_new_column_key = \"\"\n            clearTimeout(this.pending_add_new_column_timeout_id)\n        }\n    }\n\n    private move_card_to_another_column(\n        board: Board,\n        top_level_card: ColumnCard | InboxCard,\n        column_elm: HTMLElement,\n        ghost_rect: BoundingClientRect,\n    ) {\n        this.cancel_pending_add_new_column()\n        const {target} = this\n        const from_aux_column = target.top_level_card.inbox\n        let insert_pos = this.find_insert_position_in_column(\n            board,\n            top_level_card,\n            column_elm,\n            ghost_rect,\n        )\n        if (!insert_pos) {\n            return\n        }\n        if (insert_pos.parent_card === board.root) {\n            // Adapt `insert_pos` -- we don't replace column cards ...\n            insert_pos = {parent_card: top_level_card, index: 0}\n        }\n        const {parent_card, index} = insert_pos\n        if (target.parent_card === parent_card && target.index_of_dragged_card === index) {\n            // Do nothing.\n            return\n        }\n        log.debug(\n            `[dnd] Moving ${this.desc} to ${top_level_card.inbox ? \"aux\" : \"another\"} column ...`,\n        )\n        runInAction(() => {\n            const dragged_card = this.remove_preview()\n            parent_card.children.splice(index, 0, dragged_card)\n            ;(dragged_card as any)._parent = parent_card\n            this.target = {\n                board,\n                top_level_card,\n                parent_card,\n                index_of_dragged_card: index,\n            }\n            this.assert_consistent_state()\n            const to_aux_column = this.target.top_level_card.inbox\n            if (from_aux_column && to_aux_column) {\n                log.debug(`[dnd] Moved ${this.desc} from aux column to aux column`)\n            } else if (from_aux_column) {\n                log.debug(`[dnd] Moved ${this.desc} from aux column to another column`)\n            } else if (to_aux_column) {\n                log.debug(`[dnd] Moved ${this.desc} to aux column`)\n            } else {\n                log.debug(`[dnd] Moved ${this.desc} to another column`)\n            }\n            this.ghost_rect_when_moved = ghost_rect\n        })\n    }\n\n    private move_card_in_column(\n        board: Board,\n        top_level_card: ColumnCard | InboxCard,\n        column_elm: HTMLElement,\n        ghost_rect: BoundingClientRect,\n        preview_elm: HTMLElement,\n    ) {\n        this.cancel_pending_add_new_column()\n        const {target} = this\n        assert(target.top_level_card === top_level_card)\n        if (target.new_column) {\n            // Do nothing.\n            return\n        }\n        const insert_pos = this.find_insert_position_in_column(\n            board,\n            top_level_card,\n            column_elm,\n            ghost_rect,\n            preview_elm,\n        )\n        if (!insert_pos) {\n            return\n        }\n        const {parent_card} = insert_pos\n        if (parent_card === this.dragged_card) {\n            // Do nothing.\n            return\n        }\n        assert(target.board === board, \"target.board !== board\")\n        const {index} = insert_pos\n        if (parent_card === target.parent_card && index === target.index_of_dragged_card) {\n            // Do nothing.\n            return\n        }\n        log.debug(`[dnd] Moving ${this.desc} in ${top_level_card.inbox ? \"aux \" : \"\"}column ...`)\n        runInAction(() => {\n            const dragged_card = this.remove_preview()\n            parent_card.children.splice(index, 0, dragged_card)\n            ;(dragged_card as any)._parent = parent_card\n            this.target = {\n                board,\n                top_level_card,\n                parent_card,\n                index_of_dragged_card: index,\n            }\n            this.assert_consistent_state()\n            log.debug(`[dnd] Moved ${this.desc} in ${top_level_card.inbox ? \"aux \" : \"\"}column`)\n            this.ghost_rect_when_moved = ghost_rect\n        })\n    }\n\n    private find_insert_position_in_column(\n        board: Board,\n        top_level_card: ColumnCard | InboxCard,\n        column_elm: HTMLElement,\n        ghost_rect: BoundingClientRect,\n        preview_elm_if_preview_in_same_column?: HTMLElement,\n    ):\n        | {\n              parent_card: Card\n              index: number\n          }\n        | undefined {\n        const {top: ghost_top} = ghost_rect\n        let a = [\n            ...column_elm.querySelectorAll(\n                \".dnd__card,.dnd__collapsed-cards,.dnd__insertion-point\",\n            ),\n        ] as HTMLElement[]\n        if (preview_elm_if_preview_in_same_column) {\n            a = a.filter((x) => !this.dragged_card_descendants_uids.has(x.dataset.cardUid as any))\n        }\n        const max_i = a.length - 1\n        if (process.env.NODE_ENV !== \"production\") {\n            assert(max_i >= 0, \"At least one insertion point expected\")\n            for (let j = 0; j <= max_i; ++j) {\n                if (j < max_i) {\n                    assert(\n                        a[j].classList.contains(\"dnd__card\") ||\n                            a[j].classList.contains(\"dnd__collapsed-cards\"),\n                        \"Unexpected insertion point\",\n                    )\n                } else {\n                    assert(\n                        a[j].classList.contains(\"dnd__insertion-point\"),\n                        \"a[max_i] should be an insertion point\",\n                    )\n                }\n            }\n        }\n        const insert_as_last_visible_child_of = (parent_card: Card) => {\n            // Note: We try to insert the dragged card below the last visible card,\n            // so that it will be inserted *before* any hidden archived cards ...\n            const visible_children = ui_state.search_state.visible_children(parent_card)\n            const n = visible_children.length\n            if (n === 0) {\n                return {parent_card, index: 0}\n            }\n            const last_visible_card_uid = visible_children[n - 1].uid\n            if (last_visible_card_uid !== this.dragged_card.uid) {\n                let index = parent_card.children.findIndex((c) => c.uid === last_visible_card_uid)\n                // Because the dragged card should be inserted after the last visible children,\n                // we need to add 1 unless the dragged card is already a child of `parent_card` ...\n                if (\n                    !preview_elm_if_preview_in_same_column ||\n                    !parent_card.children.includes(this.dragged_card)\n                ) {\n                    index += 1\n                }\n                return {parent_card, index}\n            }\n        }\n        const insert_here = (best_i: number, best_elm: HTMLElement) => {\n            assert(a[best_i] === best_elm)\n            const {parent_card: preview_parent, index_of_dragged_card: preview_index} = this.target\n            const card_uid = best_elm.dataset.cardUid\n            if (best_elm.classList.contains(\"dnd__card\")) {\n                let p = determine_parent(board, best_elm).card\n                let i = p.children.findIndex((c) => c.uid === card_uid)\n                assert(i >= 0)\n                const elm_above = best_i > 0 && a[best_i - 1]\n                // The dragged card should take the place of `best_elm` ...\n                if (elm_above && elm_above === preview_elm_if_preview_in_same_column) {\n                    // Special case: We can't just remove the dragged card and insert it again\n                    // where the card represented by `best_elm` is located, because that would\n                    // leave the preview in the same place. Instead ...\n                    if (best_elm.classList.contains(\"dnd__has-visible-children\")) {\n                        p = p.children[i]\n                        i = 0\n                    } else {\n                        // Do nothing -- Because we don't adapt i, when the dragged card is\n                        // removed and inserted again, it will be inserted *after* the card\n                        // represented by `best_elm`.\n                    }\n                } else {\n                    // We might need to adapt i, because the dragged card will be removed,\n                    // before it is inserted again ...\n                    if (p === preview_parent && i > preview_index!) {\n                        i -= 1\n                    }\n                }\n                if (elm_above) {\n                    const elm_above_bottom = bounds(elm_above).bottom\n                    // Adapt the indentation level if necessary/possible ...\n                    if (\n                        ghost_top < elm_above_bottom &&\n                        (!preview_elm_if_preview_in_same_column ||\n                            best_elm === preview_elm_if_preview_in_same_column) &&\n                        elm_above.classList.contains(\"dnd__card\") &&\n                        !elm_above.classList.contains(\"dnd__has-visible-children\")\n                    ) {\n                        // The dragged card should be a sibling of the card\n                        // represented by `elm_above` ...\n                        const card_above_uid = as_CardUID(elm_above.dataset.cardUid)\n                        const card_above = this.get_card(board, card_above_uid)\n                        const parent_of_card_above = card_above.parent\n                        if (parent_of_card_above !== p) {\n                            p = parent_of_card_above\n                            i = p.children.findIndex((c) => c.uid === card_above_uid) + 1\n                        }\n                    } else if (\n                        ghost_top > elm_above_bottom &&\n                        best_elm === preview_elm_if_preview_in_same_column &&\n                        elm_above.classList.contains(\"dnd__card\")\n                    ) {\n                        // Try to decrease indent ...\n                        const card_above_uid = as_CardUID(elm_above.dataset.cardUid)\n                        const card_above = this.get_card(board, card_above_uid)\n                        const parent_of_card_above = card_above.parent\n                        if (parent_of_card_above === p) {\n                            assert(best_i < max_i)\n                            const elm_below = a[best_i + 1]\n                            if (elm_below.classList.contains(\"dnd__card\")) {\n                                const card_below_uid = as_CardUID(elm_below.dataset.cardUid)\n                                const card_below = this.get_card(board, card_below_uid)\n                                const parent_of_card_below = card_below.parent\n                                if (parent_of_card_below !== p) {\n                                    p = parent_of_card_below\n                                    i = p.children.findIndex((c) => c.uid === card_below_uid)\n                                }\n                            } else if (elm_below.classList.contains(\"dnd__insertion-point\")) {\n                                return insert_as_last_visible_child_of(top_level_card)\n                            }\n                        }\n                    }\n                }\n                return {parent_card: p, index: i}\n            } else if (best_elm.classList.contains(\"dnd__collapsed-cards\")) {\n                // The dragged card should be the first child of `best_elm` ...\n                const parent_card = determine_parent(board, best_elm).card\n                return {parent_card, index: 0}\n            } else if (best_elm.classList.contains(\"dnd__insertion-point\")) {\n                // Insert dragged card at bottom of column ...\n                return insert_as_last_visible_child_of(top_level_card)\n            } else {\n                throw new Error(\"Unexpected `best_elm`: \" + safe_to_string(best_elm))\n            }\n        }\n        // Here is the idea: Find the insertion position for the preview,\n        // where the vertical distance to the ghost is minimal ...\n        if (preview_elm_if_preview_in_same_column) {\n            // PERF: Start searching for the best insertion position at the preview ...\n            const preview_top = bounds(preview_elm_if_preview_in_same_column).top\n            let best_elm = preview_elm_if_preview_in_same_column\n            let best_i = a.indexOf(best_elm)\n            assert(best_i >= 0)\n            const d = ghost_top - preview_top\n            if (d < 0 && best_i > 0) {\n                // Check if the preview would fit better above its current position ...\n                let best_top = preview_top!\n                let i = best_i - 1\n                let elm = a[i]\n                let {top} = bounds(elm)\n                while (Math.abs(top - ghost_top) < Math.abs(best_top - ghost_top)) {\n                    best_i = i\n                    best_elm = elm\n                    best_top = top\n                    if (best_i === 0) {\n                        break\n                    }\n                    elm = a[--i]\n                    top = bounds(elm).top\n                }\n            } else {\n                assert(best_i < max_i) // ... because a[max_i] cannot be the preview\n                // Check if the preview would fit better below its current position ...\n                let best_d = d\n                let i = best_i + 1\n                let elm = a[i]\n                let {top} = bounds(elm)\n                const preview_height = top - preview_top\n                while (i < max_i) {\n                    const elm_below = a[i + 1]\n                    const top_below = bounds(elm_below).top\n                    const elm_height = top_below - top\n                    const preview_top_if_moved = top + elm_height - preview_height\n                    const d_if_moved = Math.abs(preview_top_if_moved - ghost_top)\n                    if (d_if_moved > best_d) {\n                        break\n                    }\n                    best_i = i\n                    best_elm = elm\n                    best_d = d_if_moved\n                    i += 1\n                    elm = elm_below\n                    top = top_below\n                }\n                if (i === max_i) {\n                    const d_if_moved = Math.abs(top - ghost_top)\n                    if (d_if_moved < best_d) {\n                        best_i = i\n                        best_elm = elm\n                    }\n                }\n            }\n            return insert_here(best_i, best_elm)\n        } else {\n            // Find best insert position in column without preview ...\n            let best_elm = a[0]\n            let best_r = bounds(best_elm)\n            if (ghost_top < best_r.top) {\n                // Best insert position is top of column ...\n                return {\n                    parent_card: top_level_card,\n                    index: 0,\n                }\n            }\n            for (let i = 1; i <= max_i; ++i) {\n                const elm = a[i]\n                const r = bounds(elm)\n                if (r.top < ghost_top) {\n                    best_elm = elm\n                    best_r = r\n                } else {\n                    // best_r.top < ghost_top <= r.top\n                    if (ghost_top - best_r.top < r.top - ghost_top) {\n                        // The top border of the ghost is in the upper half of `best_elm` ...\n                        return insert_here(i - 1, best_elm)\n                    } else {\n                        // The top border of the ghost is in the lower half of `best_elm` ...\n                        return insert_here(i, elm)\n                    }\n                }\n            }\n            // Best insert position is bottom of column ...\n            return insert_as_last_visible_child_of(top_level_card)\n        }\n    }\n\n    private restore_state() {\n        const target_board = this.target.board\n        const target_board_changed = target_board !== board_resource.read(target_board.uid)\n        if (!target_board_changed) {\n            try {\n                this.remove_preview()\n            } catch (error) {\n                const m = \"DragAndDrop.remove_preview() failed\"\n                report_error(m, error)\n                if (process.env.NODE_ENV === \"production\") {\n                    reload(m)\n                }\n            }\n        }\n        const {\n            dragged_card,\n            source: {board: source_board, parent_card, index_of_dragged_card},\n        } = this\n        const source_board_changed = source_board !== board_resource.read(source_board.uid)\n        if (!source_board_changed) {\n            parent_card.children.splice(index_of_dragged_card, 0, dragged_card)\n            ;(dragged_card as any)._parent = parent_card\n        }\n    }\n\n    /**\n     * Returns the dragged card.\n     */\n    private remove_preview() {\n        this.assert_consistent_state()\n        const {dragged_card, target} = this\n        if (target.new_column) {\n            const {board, index_of_new_column_card: i, top_level_card} = target\n            const new_column_card = board.root.children[i]\n            assert(\n                new_column_card === top_level_card,\n                \"board.root.children[target.index_of_new_column_card] !== target.top_level_card\",\n            )\n            assert(\n                new_column_card === top_level_card,\n                \"board.root.children[target.index_of_new_column_card] !== target.top_level_card\",\n            )\n            assert(\n                new_column_card.children[0] === this.dragged_card,\n                \"new_column_card.children[0] !== dragged_card\",\n            )\n            board.root.children.splice(i, 1)\n        } else {\n            const {parent_card, index_of_dragged_card: i} = target\n            assert(\n                parent_card!.children[i] === dragged_card,\n                \"target.parent_card.children[target.index_of_dragged_card] !== dragged_card\",\n            )\n            parent_card!.children.splice(i, 1)\n        }\n        return dragged_card\n    }\n\n    private get_card(board: Board, card_uid: CardUID): Card {\n        const cache_key = board.uid + \":\" + card_uid\n        let card = this.get_card_cache.get(cache_key)\n        if (!card) {\n            card = board.card(card_uid)\n            this.get_card_cache.set(cache_key, card)\n        }\n        return card\n    }\n\n    private board_changed() {\n        const source_board = this.source.board\n        if (source_board !== board_resource.read(source_board.uid)) {\n            return true\n        }\n        const target_board = this.target.board\n        if (\n            target_board !== source_board &&\n            target_board !== board_resource.read(target_board.uid)\n        ) {\n            return true\n        }\n    }\n}\n\nfunction bounds(elm: HTMLElement) {\n    if (elm.classList.contains(\"dnd__card\")) {\n        elm = elm.querySelector(\".card\")!\n    }\n    return elm.getBoundingClientRect()\n}\n\nfunction determine_board(elm: HTMLElement): Board {\n    const board_elm = elm.closest(\".dnd__board\") as HTMLElement\n    assert(board_elm, `elm.closest(\".dnd__board\") => ${board_elm}`)\n    const board_uid = board_elm.dataset.boardUid as BoardUID\n    assert(is_BoardUID(board_uid), `board_elm.dataset.boardUid => ${board_uid}`)\n    const board = board_resource.read(board_uid)\n    assert(board, \"board not in board_resource.cached\")\n    return board!\n}\n\nfunction determine_top_level_card(board: Board, column_elm: HTMLElement): ColumnCard | InboxCard {\n    const top_level_card_elm = column_elm.querySelector(\".dnd__top-level-card\") as HTMLElement\n    const top_level_card_uid = top_level_card_elm.dataset.cardUid\n    const top_level_card = board.root.children.find((c) => c.uid === top_level_card_uid)!\n    assert(\n        top_level_card,\n        `board.root.children.find(c => c.uid === top_level_card_uid) => ${top_level_card}`,\n    )\n    assert(top_level_card.column || top_level_card.inbox, \"Invalid top level card\")\n    return top_level_card as ColumnCard | InboxCard\n}\n\nfunction determine_parent(\n    board: Board,\n    elm: HTMLElement,\n): {\n    card: Card\n    elm: HTMLElement\n} {\n    let parent_elm: HTMLElement | undefined\n    const ancestor_uids = [] as Array<CardUID>\n    for (;;) {\n        const parent_card_elm = elm.parentElement!.closest(\".dnd__card\") as HTMLElement\n        if (!parent_card_elm) {\n            break\n        }\n        elm = parent_card_elm\n        if (!parent_elm) {\n            parent_elm = elm\n        }\n        ancestor_uids.unshift(elm.dataset.cardUid as CardUID)\n    }\n    const top_level_card_elm = elm.closest(\".dnd__top-level-card\") as HTMLElement\n    assert(\n        top_level_card_elm,\n        \"Did not find enclosing element with CSS class 'dnd__top-level-card'\",\n    )\n    if (!parent_elm) {\n        parent_elm = top_level_card_elm\n    }\n    ancestor_uids.unshift(top_level_card_elm.dataset.cardUid as CardUID)\n    let card = board.root\n    for (const uid of ancestor_uids) {\n        card = card.children.find((c) => c.uid === uid)!\n        assert(\n            card,\n            `Did not find card ${uid} in children of card ${card.uid} on board ${board.uid}`,\n        )\n    }\n    return {elm: parent_elm, card}\n}\n\nfunction determine_source(card_uid: CardUID, card_elm: HTMLElement): DragSource {\n    const board = determine_board(card_elm)\n    const column_elm = card_elm.closest(\".dnd__column\") as HTMLElement\n    assert(column_elm, `card_elm.closest(\".dnd__column\") => ${column_elm}`)\n    const top_level_card = determine_top_level_card(board, column_elm)\n    const parent_card = determine_parent(board, card_elm).card\n    const i = parent_card.children.findIndex((c) => c.uid === card_uid)\n    assert(i >= 0, `Did not find card ${card_uid} in children of card ${parent_card.uid}`)\n    const dragged_card = parent_card.children[i]\n    return {\n        board,\n        top_level_card,\n        parent_card,\n        index_of_dragged_card: i,\n        dragged_card,\n    }\n}\n\nexport default DragAndDropGhost\n"],
  "mappings": "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",
  "names": ["init_compat_module", "MIN_DRAG_DISTANCE", "ADD_NEW_COLUMN_AREA_WIDTH", "ADD_NEW_COLUMN_DELAY", "SCROLL_DELAY", "current_ghost", "_a", "DragAndDropGhost", "observer", "x", "props", "__publicField", "__name", "ref", "style", "left", "top", "width", "y", "w", "makeObservable", "observable", "action", "drag_and_drop", "report_error", "ghost_card", "_", "start_drag_card", "mousedown_event", "card_uid", "ignore_click_at", "dragged_card_elm", "assert", "source", "determine_source", "dragged_card_rect", "dragged_card_width", "ignore_click", "move_ghost_request_id", "mouse_cursor_x", "mouse_cursor_y", "x0", "y0", "grabbed_at", "move_ghost", "handle_error", "f", "event", "error", "remove_event_listeners", "on_mousemove", "runInAction", "DragAndDrop", "ui_actions", "on_mouseup", "on_keydown", "on_window_blur", "_scroll_horizontal", "_block_horizontal_scroll", "scroll", "dir", "ui_state", "_scroll_up", "elm", "delta", "scroll_top", "_scroll_down", "max_scroll_top", "_DragAndDrop", "ghost", "mouse_down_event", "scroll_on_drag_interval_handler", "ms", "t0", "ghost_elm", "log", "preview_elm", "ghost_rect", "ghost_left", "ghost_top", "ghost_width", "ghost_height", "target", "a", "max_i", "column_elm", "r", "board", "determine_board", "inbox_card", "determine_top_level_card", "i", "top_level_card", "dt", "report_info", "parent_card", "index_of_dragged_card", "dragged_card", "Card", "c", "new_column_card", "index", "n", "level", "temp", "preview_column_elm", "preview_board", "preview_top_level_card", "preview_parent_elm", "preview_parent_card", "determine_parent", "model_children_uids", "card", "dragged_card_uid", "dom_children_uids", "uid", "uids_above", "uids_below", "visited_dragged_card_uid", "scroll_left", "scroll_right", "layout", "min", "elements", "y_scroll_up", "right", "y_scroll_down", "aborted", "h", "area", "v", "card_moved", "index_of_new_column_card", "optimistic_update", "AddCard", "AddCardValue", "Column", "MoveCard", "report_user_engagement", "undo_op", "Snackbar", "i18n", "RemoveCard", "reason", "report", "m", "before", "after", "first_column", "key", "add_new_column", "create_CardUID", "CardChangelogEntry", "current_user", "from_aux_column", "insert_pos", "to_aux_column", "preview_elm_if_preview_in_same_column", "insert_as_last_visible_child_of", "visible_children", "last_visible_card_uid", "insert_here", "best_i", "best_elm", "preview_parent", "preview_index", "p", "elm_above", "elm_above_bottom", "bounds", "card_above_uid", "as_CardUID", "parent_of_card_above", "elm_below", "card_below_uid", "parent_of_card_below", "safe_to_string", "preview_top", "d", "best_top", "best_d", "preview_height", "top_below", "elm_height", "preview_top_if_moved", "d_if_moved", "best_r", "target_board", "board_resource", "source_board", "cache_key", "board_elm", "board_uid", "is_BoardUID", "top_level_card_uid", "parent_elm", "ancestor_uids", "parent_card_elm", "top_level_card_elm", "card_elm", "drag_and_drop_default"]
}