import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
import { useDraggable, useDroppable, useSensors, useSensor, PointerSensor, DndContext, DragOverlay } from "@dnd-kit/core";
import { ChevronRight } from "lucide-react";
import { cva } from "class-variance-authority";
import { dropIndicatorRow, dropIndicatorInside, dragSourceClass } from "../../lib/drag-visual.js";
import { cn } from "../../lib/utils.js";
import { Checkbox } from "../Checkbox/checkbox.js";
import { ICON_SIZE, ItemPrefix, ItemIcon, ItemSuffix, ItemInlineAction, RowSizeProvider, ROW_PADDING_BY_SIZE } from "../../patterns/element-anatomy/item-anatomy.js";
const CONTEXT_PX_VAR = {
  sidebar: "var(--layout-space-loose)",
  // md=16px, lg=24px(density 連動)
  menu: "12px"
  // px-3,對齊 MenuItem / DropdownMenu
};
const INDENT_STEP = { sm: 24, md: 24, lg: 28 };
const TreeViewContext = React.createContext(null);
function useTreeView() {
  const ctx = React.useContext(TreeViewContext);
  if (!ctx) throw new Error("TreeItem must be used within TreeView");
  return ctx;
}
const DepthContext = React.createContext(0);
function useNodeRegistry() {
  const nodesRef = React.useRef(/* @__PURE__ */ new Map());
  const registerNode = React.useCallback(
    (id, parentId, hasChildren, label, icon) => {
      nodesRef.current.set(id, { id, parentId, hasChildren, label, icon });
    },
    []
  );
  const unregisterNode = React.useCallback((id) => {
    nodesRef.current.delete(id);
  }, []);
  const getNodeInfo = React.useCallback((id) => nodesRef.current.get(id), []);
  return { nodesRef, registerNode, unregisterNode, getNodeInfo };
}
const TreeView = React.forwardRef(
  ({
    size = "md",
    context = "sidebar",
    selectionMode = "single",
    expandOnSelect = false,
    draggable = false,
    onDragEnd: onDragEndProp,
    expandedIds: controlledExpanded,
    onExpandedChange,
    selectedIds: controlledSelected,
    onSelectedChange,
    defaultExpandedIds = [],
    defaultSelectedIds = [],
    className,
    children,
    ...props
  }, ref) => {
    const [internalExpanded, setInternalExpanded] = React.useState(
      () => new Set(defaultExpandedIds)
    );
    const expandedIds = controlledExpanded ?? internalExpanded;
    const setExpandedIds = React.useCallback(
      (updater) => {
        const update = (prev) => {
          const next = updater(prev);
          onExpandedChange == null ? void 0 : onExpandedChange(next);
          return next;
        };
        if (controlledExpanded) {
          update(controlledExpanded);
        } else {
          setInternalExpanded(update);
        }
      },
      [controlledExpanded, onExpandedChange]
    );
    const [internalSelected, setInternalSelected] = React.useState(
      () => new Set(defaultSelectedIds)
    );
    const selectedIds = controlledSelected ?? internalSelected;
    const setSelectedIds = React.useCallback(
      (updater) => {
        const update = (prev) => {
          const next = updater(prev);
          onSelectedChange == null ? void 0 : onSelectedChange(next);
          return next;
        };
        if (controlledSelected) {
          update(controlledSelected);
        } else {
          setInternalSelected(update);
        }
      },
      [controlledSelected, onSelectedChange]
    );
    const [focusedId, setFocusedId] = React.useState(null);
    const activeDescendantPrefix = React.useId();
    const isKeyboardRef = React.useRef(false);
    const [draggingId, setDraggingId] = React.useState(null);
    const [dropTarget, setDropTarget] = React.useState(null);
    const autoExpandTimerRef = React.useRef(null);
    React.useEffect(() => () => {
      if (autoExpandTimerRef.current) clearTimeout(autoExpandTimerRef.current);
    }, []);
    const toggleExpandRef = React.useRef(() => {
    });
    const sensors = useSensors(
      useSensor(PointerSensor, { activationConstraint: { distance: 5 } })
    );
    const handleDragStart = React.useCallback((event) => {
      setDraggingId(String(event.active.id));
    }, []);
    const handleDragOver = React.useCallback((event) => {
      var _a, _b, _c, _d, _e;
      const { over, active } = event;
      if (!over || over.id === active.id) {
        if (autoExpandTimerRef.current) {
          clearTimeout(autoExpandTimerRef.current);
          autoExpandTimerRef.current = null;
        }
        setDropTarget(null);
        return;
      }
      const rowEl = document.querySelector(`[data-tree-row="${over.id}"]`);
      const targetEl = document.querySelector(`[data-tree-id="${over.id}"]`);
      if (!rowEl || !targetEl) {
        setDropTarget(null);
        return;
      }
      const startX = ((_a = event.activatorEvent) == null ? void 0 : _a.clientX) ?? 0;
      const startY = ((_b = event.activatorEvent) == null ? void 0 : _b.clientY) ?? 0;
      const currentX = startX + (((_c = event.delta) == null ? void 0 : _c.x) ?? 0);
      const currentY = startY + (((_d = event.delta) == null ? void 0 : _d.y) ?? 0);
      const rect = rowEl.getBoundingClientRect();
      const offsetY = currentY - rect.top;
      const height = rect.height || 32;
      const ratio = Math.max(0, Math.min(1, offsetY / height));
      const hasChildren = targetEl.dataset.treeHasChildren === "true";
      const targetDepth = Number(targetEl.getAttribute("aria-level") ?? 1) - 1;
      const treeEl2 = treeRef.current;
      const treeLeft = (treeEl2 == null ? void 0 : treeEl2.getBoundingClientRect().left) ?? 0;
      const indentStep = INDENT_STEP[size];
      const pointerIndentLevel = Math.max(0, Math.floor((currentX - treeLeft) / indentStep));
      let position;
      let finalDepth = targetDepth;
      if (hasChildren) {
        if (ratio < 0.25) {
          position = "before";
        } else if (ratio > 0.75) {
          position = pointerIndentLevel > targetDepth ? "inside" : "after";
        } else {
          position = "inside";
        }
      } else {
        if (ratio < 0.5) {
          position = "before";
        } else {
          position = "after";
          if (pointerIndentLevel < targetDepth) {
            const groupEl = targetEl.closest('[role="group"]');
            const parentTreeItem = (_e = groupEl == null ? void 0 : groupEl.parentElement) == null ? void 0 : _e.closest('[role="treeitem"]');
            const parentId = parentTreeItem == null ? void 0 : parentTreeItem.getAttribute("data-tree-id");
            if (parentId && parentId !== String(active.id)) {
              const parentDepth = Number((parentTreeItem == null ? void 0 : parentTreeItem.getAttribute("aria-level")) ?? 1) - 1;
              finalDepth = parentDepth;
              setDropTarget({ id: parentId, position: "after", depth: parentDepth });
              return;
            }
          }
        }
      }
      setDropTarget({ id: String(over.id), position, depth: finalDepth });
      if (position === "inside" && hasChildren && !expandedIds.has(String(over.id))) {
        if (autoExpandTimerRef.current) clearTimeout(autoExpandTimerRef.current);
        autoExpandTimerRef.current = setTimeout(() => {
          toggleExpandRef.current(String(over.id));
        }, 500);
      } else {
        if (autoExpandTimerRef.current) {
          clearTimeout(autoExpandTimerRef.current);
          autoExpandTimerRef.current = null;
        }
      }
    }, [expandedIds]);
    const dropTargetRef = React.useRef(dropTarget);
    dropTargetRef.current = dropTarget;
    const handleDragEnd = React.useCallback((event) => {
      if (autoExpandTimerRef.current) {
        clearTimeout(autoExpandTimerRef.current);
        autoExpandTimerRef.current = null;
      }
      const { active, over } = event;
      const dt = dropTargetRef.current;
      if (over && active.id !== over.id && dt) {
        onDragEndProp == null ? void 0 : onDragEndProp({
          sourceId: String(active.id),
          targetId: String(over.id),
          position: dt.position
        });
      }
      setDraggingId(null);
      setDropTarget(null);
    }, [onDragEndProp]);
    const handleDragCancel = React.useCallback(() => {
      if (autoExpandTimerRef.current) {
        clearTimeout(autoExpandTimerRef.current);
        autoExpandTimerRef.current = null;
      }
      setDraggingId(null);
      setDropTarget(null);
    }, []);
    const { registerNode, unregisterNode, getNodeInfo } = useNodeRegistry();
    const toggleExpand = React.useCallback(
      (id) => {
        setExpandedIds((prev) => {
          const next = new Set(prev);
          if (next.has(id)) next.delete(id);
          else next.add(id);
          return next;
        });
      },
      [setExpandedIds]
    );
    toggleExpandRef.current = toggleExpand;
    const select = React.useCallback(
      (id) => {
        if (selectionMode === "none") return;
        setSelectedIds((prev) => {
          if (selectionMode === "single") {
            return /* @__PURE__ */ new Set([id]);
          }
          const next = new Set(prev);
          if (next.has(id)) next.delete(id);
          else next.add(id);
          return next;
        });
      },
      [selectionMode, setSelectedIds]
    );
    const contextValue = React.useMemo(
      () => ({
        size,
        context,
        selectionMode,
        expandOnSelect,
        draggable,
        isKeyboardRef,
        activeDescendantPrefix,
        draggingId,
        dropTarget,
        expandedIds,
        selectedIds,
        focusedId,
        toggleExpand,
        select,
        setFocusedId,
        registerNode,
        unregisterNode,
        getNodeInfo
      }),
      [
        size,
        context,
        selectionMode,
        expandOnSelect,
        draggable,
        isKeyboardRef,
        activeDescendantPrefix,
        draggingId,
        dropTarget,
        expandedIds,
        selectedIds,
        focusedId,
        toggleExpand,
        select,
        setFocusedId,
        registerNode,
        unregisterNode,
        getNodeInfo
      ]
    );
    const treeRef = React.useRef(null);
    React.useImperativeHandle(ref, () => treeRef.current);
    const handleMouseDown = React.useCallback(() => {
      isKeyboardRef.current = false;
    }, []);
    const handleKeyDown = React.useCallback(
      (e) => {
        isKeyboardRef.current = true;
        if (!treeRef.current) return;
        const items = Array.from(
          treeRef.current.querySelectorAll('[role="treeitem"]:not([hidden])')
        );
        const currentIndex = items.findIndex(
          (el) => el.dataset.treeId === focusedId
        );
        if (currentIndex < 0 && items.length > 0 && ["ArrowDown", "ArrowUp", "Home", "End"].includes(e.key)) {
          setFocusedId(items[0].dataset.treeId ?? null);
          e.preventDefault();
          return;
        }
        const currentEl = items[currentIndex];
        switch (e.key) {
          case "ArrowDown": {
            e.preventDefault();
            const next = items[currentIndex + 1];
            if (next) setFocusedId(next.dataset.treeId ?? null);
            break;
          }
          case "ArrowUp": {
            e.preventDefault();
            const prev = items[currentIndex - 1];
            if (prev) setFocusedId(prev.dataset.treeId ?? null);
            break;
          }
          case "ArrowRight": {
            e.preventDefault();
            const id = currentEl == null ? void 0 : currentEl.dataset.treeId;
            if (!id) break;
            const isExpanded = expandedIds.has(id);
            const hasChildren = (currentEl == null ? void 0 : currentEl.dataset.treeHasChildren) === "true";
            if (hasChildren && !isExpanded) {
              toggleExpand(id);
            } else if (hasChildren && isExpanded) {
              const next = items[currentIndex + 1];
              if (next) setFocusedId(next.dataset.treeId ?? null);
            }
            break;
          }
          case "ArrowLeft": {
            e.preventDefault();
            const id = currentEl == null ? void 0 : currentEl.dataset.treeId;
            if (!id) break;
            const isExpanded = expandedIds.has(id);
            const hasChildren = (currentEl == null ? void 0 : currentEl.dataset.treeHasChildren) === "true";
            if (hasChildren && isExpanded) {
              toggleExpand(id);
            } else {
              const parentId = currentEl == null ? void 0 : currentEl.dataset.treeParentId;
              if (parentId) setFocusedId(parentId);
            }
            break;
          }
          case "Home": {
            e.preventDefault();
            if (items[0]) setFocusedId(items[0].dataset.treeId ?? null);
            break;
          }
          case "End": {
            e.preventDefault();
            const last = items[items.length - 1];
            if (last) setFocusedId(last.dataset.treeId ?? null);
            break;
          }
          case "Enter":
          case " ": {
            e.preventDefault();
            const id = currentEl == null ? void 0 : currentEl.dataset.treeId;
            if (id) select(id);
            break;
          }
        }
      },
      [focusedId, expandedIds, toggleExpand, select, setFocusedId]
    );
    const treeEl = /* @__PURE__ */ jsx(
      "div",
      {
        ref: treeRef,
        role: "tree",
        "aria-multiselectable": selectionMode === "multiple" || void 0,
        "aria-activedescendant": focusedId ? `${activeDescendantPrefix}treeitem-${focusedId}` : void 0,
        className: cn(
          // TreeView root 不加任何 py——呼吸空間由外層容器負責:
          //   - 在 SidebarGroup 內: SidebarGroup py-2 提供
          //   - 在 DropdownMenuContent 內: content py-2 提供
          //   - 獨立使用(story demo): consumer 自己加 py-2
          // 這樣才能跟 DropdownMenu / MenuGroup 的結構一致(group 是容器,row 是內容)。
          "flex flex-col",
          className
        ),
        style: {
          ["--tree-px"]: CONTEXT_PX_VAR[context],
          ...props.style
        },
        onKeyDown: handleKeyDown,
        onMouseDown: handleMouseDown,
        tabIndex: 0,
        ...props,
        children
      }
    );
    return /* @__PURE__ */ jsx(TreeViewContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(RowSizeProvider, { value: size, children: /* @__PURE__ */ jsxs(
      DndContext,
      {
        sensors: draggable ? sensors : void 0,
        onDragStart: handleDragStart,
        onDragOver: handleDragOver,
        onDragEnd: handleDragEnd,
        onDragCancel: handleDragCancel,
        children: [
          treeEl,
          draggable && /* @__PURE__ */ jsx(DragOverlay, { dropAnimation: null, children: draggingId ? (() => {
            const info = getNodeInfo(draggingId);
            const IconComp = info == null ? void 0 : info.icon;
            return /* @__PURE__ */ jsxs("div", { className: cn(
              "flex items-center gap-2 rounded-lg bg-surface border border-border pointer-events-none",
              "shadow-[var(--elevation-200)]",
              size === "lg" ? "text-body-lg leading-compact px-4 py-2" : "text-body leading-compact px-3 py-1.5"
            ), children: [
              IconComp && /* @__PURE__ */ jsx(IconComp, { size: ICON_SIZE[size], className: "shrink-0", "aria-hidden": true }),
              /* @__PURE__ */ jsx("span", { className: "text-foreground truncate max-w-[200px]", children: (info == null ? void 0 : info.label) ?? draggingId })
            ] });
          })() : null })
        ]
      }
    ) }) });
  }
);
TreeView.displayName = "TreeView";
const treeItemVariants = cva(
  [
    // items-start:多行 label 時 prefix 留在第一行(item-layout 規則)
    "flex items-start gap-2 w-full",
    "cursor-pointer select-none",
    "transition-colors duration-150",
    "outline-none",
    // Label 字重 500(跟 SidebarMenuButton 一致)
    "font-medium"
  ],
  {
    variants: {
      // 消費 ROW_PADDING_BY_SIZE SSOT(item-anatomy.tsx)— drift risk 消除
      size: ROW_PADDING_BY_SIZE
    },
    defaultVariants: {
      size: "md"
    }
  }
);
const TreeItem = React.forwardRef(
  ({ id, label, icon: Icon, checkbox, inlineActions, inlineActionsSlot, actionsReveal = "hover", indicator, disabled, children, className, ...props }, ref) => {
    const ctx = useTreeView();
    const depth = React.useContext(DepthContext);
    const {
      size,
      selectionMode,
      expandOnSelect,
      draggable,
      expandedIds,
      selectedIds,
      focusedId,
      draggingId,
      dropTarget,
      toggleExpand,
      select,
      setFocusedId,
      registerNode,
      unregisterNode,
      isKeyboardRef,
      activeDescendantPrefix
    } = ctx;
    const hasChildren = React.Children.count(children) > 0;
    const isExpanded = expandedIds.has(id);
    const isSelected = selectedIds.has(id);
    const isFocused = focusedId === id;
    const showRing = isFocused && isKeyboardRef.current;
    const isDragging = draggingId === id;
    const isDropTarget = (dropTarget == null ? void 0 : dropTarget.id) === id;
    const iconPx = ICON_SIZE[size];
    const indentPx = depth * INDENT_STEP[size];
    const { attributes: dragAttrs, listeners: dragListeners, setNodeRef: setDragRef } = useDraggable({
      id,
      disabled: !draggable || disabled
    });
    const { setNodeRef: setDropRef } = useDroppable({
      id,
      disabled: !draggable || disabled
    });
    const parentId = React.useContext(ParentIdContext);
    React.useEffect(() => {
      registerNode(id, parentId, hasChildren, label, Icon);
      return () => unregisterNode(id);
    }, [id, parentId, hasChildren, label, Icon, registerNode, unregisterNode]);
    const itemRef = React.useRef(null);
    React.useImperativeHandle(ref, () => itemRef.current);
    React.useEffect(() => {
      if (isFocused && itemRef.current) {
        itemRef.current.scrollIntoView({ block: "nearest" });
      }
    }, [isFocused]);
    const handleRowClick = React.useCallback(
      (e) => {
        if (disabled) return;
        e.stopPropagation();
        setFocusedId(id);
        select(id);
        if (expandOnSelect && hasChildren) {
          toggleExpand(id);
        }
      },
      [id, disabled, select, setFocusedId, expandOnSelect, hasChildren, toggleExpand]
    );
    const handleChevronClick = React.useCallback(
      (e) => {
        e.stopPropagation();
        if (disabled) return;
        toggleExpand(id);
      },
      [id, disabled, toggleExpand]
    );
    const chevronSlot = /* @__PURE__ */ jsx(ItemPrefix, { style: { width: iconPx }, children: hasChildren ? /* @__PURE__ */ jsx(
      "button",
      {
        type: "button",
        tabIndex: -1,
        onClick: handleChevronClick,
        className: cn(
          "flex items-center justify-center rounded-md",
          "text-fg-muted hover:text-foreground hover:bg-neutral-hover",
          "transition-all duration-150",
          isExpanded && "rotate-90",
          disabled && "text-fg-disabled pointer-events-none"
        ),
        style: { width: iconPx, height: iconPx },
        "aria-hidden": true,
        children: /* @__PURE__ */ jsx(ChevronRight, { size: iconPx })
      }
    ) : (
      // Leaf placeholder
      /* @__PURE__ */ jsx("span", { style: { width: iconPx }, "aria-hidden": true })
    ) });
    return /* @__PURE__ */ jsx(ParentIdContext.Provider, { value: id, children: /* @__PURE__ */ jsxs(
      "div",
      {
        ref: (node) => {
          itemRef.current = node;
          if (typeof ref === "function") ref(node);
          else if (ref) ref.current = node;
        },
        id: `${activeDescendantPrefix}treeitem-${id}`,
        role: "treeitem",
        "aria-expanded": hasChildren ? isExpanded : void 0,
        "aria-selected": selectionMode !== "none" ? isSelected : void 0,
        "aria-level": depth + 1,
        "aria-disabled": disabled || void 0,
        "data-tree-id": id,
        "data-tree-parent-id": parentId ?? "",
        "data-tree-has-children": hasChildren,
        tabIndex: -1,
        className: cn("w-full min-w-0 relative", isDragging && dragSourceClass),
        children: [
          isDropTarget && (dropTarget == null ? void 0 : dropTarget.position) === "before" && /* @__PURE__ */ jsx(
            "div",
            {
              className: dropIndicatorRow.before,
              style: { left: `calc(var(--tree-px) + ${indentPx}px)` }
            }
          ),
          /* @__PURE__ */ jsxs(
            "div",
            {
              ref: (node) => {
                if (draggable) setDragRef(node);
                setDropRef(node);
              },
              "data-tree-row": id,
              className: cn(
                "group/tree-item",
                treeItemVariants({ size }),
                // 2026-05-26 SSOT lock(user explicit「multi 已有 checkbox 強信號,text 不該再變色」):
                // ── Single mode ──
                //   - default text 預設 fg-secondary muted(hierarchy navigation 慣例,跟 Sidebar 一致)
                //   - selected → text-foreground emphasis + bg-neutral-selected(無 checkbox,需 text+bg 雙信號)
                // ── Multi mode ──
                //   - default text 維持 fg-secondary muted(跟 single 對齊 hierarchy)
                //   - selected → 視覺信號只在 checkbox(auto-render below),text 不變、bg 不變
                //   - 對齊 SelectMenu multi pattern(menu-item.tsx:194-195 selected → bg only;multi → checkbox only)
                !disabled && !isSelected && "text-fg-secondary",
                !disabled && isSelected && selectionMode === "single" && "text-foreground",
                isDropTarget && (dropTarget == null ? void 0 : dropTarget.position) === "inside" && dropIndicatorInside,
                !disabled && "hover:bg-neutral-hover hover:text-foreground",
                !disabled && isSelected && selectionMode === "single" && "bg-neutral-selected",
                showRing && "ring-2 ring-ring ring-inset",
                disabled && "pointer-events-none text-fg-disabled cursor-default",
                className
              ),
              style: {
                paddingLeft: indentPx > 0 ? `calc(var(--tree-px) + ${indentPx}px)` : "var(--tree-px)",
                paddingRight: "var(--tree-px)"
              },
              onClick: handleRowClick,
              ...draggable ? { ...dragListeners, ...dragAttrs } : {},
              ...props,
              children: [
                chevronSlot,
                (checkbox || selectionMode === "multiple") && /* @__PURE__ */ jsx(ItemPrefix, { className: "pointer-events-none", children: checkbox || /* @__PURE__ */ jsx(Checkbox, { checked: isSelected, disabled, "aria-hidden": "true" }) }),
                indicator ? /* @__PURE__ */ jsx(ItemPrefix, { style: { width: iconPx }, children: indicator }) : Icon ? /* @__PURE__ */ jsx(ItemIcon, { icon: Icon, className: disabled ? "text-fg-disabled" : void 0 }) : null,
                /* @__PURE__ */ jsx("span", { className: cn("flex-1 min-w-0 truncate", disabled && "text-fg-disabled"), children: label }),
                disabled ? null : inlineActionsSlot ? /* @__PURE__ */ jsx(ItemSuffix, { hoverReveal: actionsReveal === "hover", hoverGroup: "tree-item", children: inlineActionsSlot }) : inlineActions && inlineActions.length > 0 ? /* @__PURE__ */ jsx(ItemSuffix, { hoverReveal: actionsReveal === "hover", hoverGroup: "tree-item", children: inlineActions.map((action, i) => /* @__PURE__ */ jsx(ItemInlineAction, { action }, action.label + i)) }) : null
              ]
            }
          ),
          isDropTarget && (dropTarget == null ? void 0 : dropTarget.position) === "after" && /* @__PURE__ */ jsx(
            "div",
            {
              className: dropIndicatorRow.after,
              style: { left: `calc(var(--tree-px) + ${indentPx}px)` }
            }
          ),
          hasChildren && /* @__PURE__ */ jsx(CollapsiblePrimitive.Root, { open: isExpanded, children: /* @__PURE__ */ jsx(
            CollapsiblePrimitive.Content,
            {
              className: "overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down",
              children: /* @__PURE__ */ jsx(DepthContext.Provider, { value: depth + 1, children: /* @__PURE__ */ jsx("div", { role: "group", className: "flex flex-col w-full", children }) })
            }
          ) })
        ]
      }
    ) });
  }
);
TreeItem.displayName = "TreeItem";
const ParentIdContext = React.createContext(null);
const treeViewMeta = {
  component: "TreeView",
  family: 1,
  // Family 1(Menu item layout)消費者 — 對齊 tree-view.spec.md frontmatter family: 1
  variants: {},
  sizes: {},
  states: ["default", "hover", "active", "focus-visible", "disabled"],
  tokens: {
    bg: ["bg-neutral-hover", "bg-primary", "bg-primary-subtle", "bg-surface"],
    fg: ["text-fg-disabled", "text-fg-muted", "text-fg-secondary", "text-foreground"],
    ring: ["ring-ring"]
  },
  defaultSize: "md"
};
export {
  TreeItem,
  TreeView,
  treeItemVariants,
  treeViewMeta
};
//# sourceMappingURL=tree-view.js.map
