"use strict";
const vue = require("vue");
const BTableSimple_vue_vue_type_script_setup_true_lang = require("./BTableSimple.vue_vue_type_script_setup_true_lang-fbqLNWG6.js");
const useDefaults = require("./useDefaults-YXpmugKp.js");
const object = require("./object-DlOVrM-t.js");
const tableUtils = require("./tableUtils-MbGcRaD0.js");
const useId = require("./useId-Dl8Hi5_U.js");
const stringUtils = require("./stringUtils-DVq7fDaW.js");
const constants = require("./constants-DxId_i-P.js");
const event = require("./event-BbcvB460.js");
const keys = require("./keys-D70E9HED.js");
const debounce = require("./debounce-EDygIUUU.js");
const index = require("./index-JJEBhaXq.js");
const isTableItem = (value) => typeof value === "object" && value !== null;
const isTableField = (value) => typeof value === "object" && value !== null && "key" in value;
const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
  __name: "BTbody",
  props: {
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BTbody");
    const computedClasses = vue.computed(() => ({
      [`thead-${props.variant}`]: props.variant !== null
    }));
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createElementBlock("tbody", {
        class: vue.normalizeClass(computedClasses.value)
      }, [
        vue.renderSlot(_ctx.$slots, "default")
      ], 2);
    };
  }
});
const _hoisted_1$3 = ["colspan", "rowspan", "data-label"];
const _hoisted_2$3 = { key: 0 };
const _sfc_main$6 = /* @__PURE__ */ vue.defineComponent({
  __name: "BTd",
  props: {
    colspan: { default: void 0 },
    rowspan: { default: void 0 },
    stackedHeading: { default: void 0 },
    stickyColumn: { type: Boolean, default: false },
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BTd");
    const computedClasses = vue.computed(() => ({
      [`table-${props.variant}`]: props.variant !== null,
      "b-table-sticky-column": props.stickyColumn,
      "table-b-table-default": props.stickyColumn && props.variant === null
    }));
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createElementBlock("td", {
        class: vue.normalizeClass(computedClasses.value),
        colspan: vue.unref(props).colspan,
        rowspan: vue.unref(props).rowspan,
        "data-label": vue.unref(props).stackedHeading
      }, [
        vue.unref(props).stackedHeading ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$3, [
          vue.renderSlot(_ctx.$slots, "default")
        ])) : vue.renderSlot(_ctx.$slots, "default", { key: 1 })
      ], 10, _hoisted_1$3);
    };
  }
});
const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
  __name: "BTfoot",
  props: {
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BTfoot");
    const computedClasses = vue.computed(() => ({
      [`table-${props.variant}`]: props.variant !== null
    }));
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createElementBlock("tfoot", {
        class: vue.normalizeClass(computedClasses.value)
      }, [
        vue.renderSlot(_ctx.$slots, "default")
      ], 2);
    };
  }
});
const _hoisted_1$2 = ["scope", "colspan", "rowspan", "data-label"];
const _hoisted_2$2 = { key: 0 };
const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
  __name: "BTh",
  props: {
    colspan: { default: void 0 },
    rowspan: { default: void 0 },
    stackedHeading: { default: void 0 },
    stickyColumn: { type: Boolean, default: false },
    variant: { default: null },
    scope: { default: void 0 }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BTh");
    const computedClasses = vue.computed(() => ({
      [`table-${props.variant}`]: props.variant !== null,
      "b-table-sticky-column": props.stickyColumn,
      "table-b-table-default": props.stickyColumn && props.variant === null
    }));
    const localScope = vue.computed(
      () => props.scope ? props.scope : props.colspan ? "colgroup" : props.rowspan ? "rowgroup" : "col"
    );
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createElementBlock("th", {
        scope: localScope.value,
        class: vue.normalizeClass(computedClasses.value),
        colspan: vue.unref(props).colspan,
        rowspan: vue.unref(props).rowspan,
        "data-label": vue.unref(props).stackedHeading
      }, [
        vue.unref(props).stackedHeading !== void 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$2, [
          vue.renderSlot(_ctx.$slots, "default")
        ])) : vue.renderSlot(_ctx.$slots, "default", { key: 1 })
      ], 10, _hoisted_1$2);
    };
  }
});
const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
  __name: "BThead",
  props: {
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BThead");
    const computedClasses = vue.computed(() => ({
      [`table-${props.variant}`]: props.variant !== null
    }));
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createElementBlock("thead", {
        class: vue.normalizeClass(computedClasses.value)
      }, [
        vue.renderSlot(_ctx.$slots, "default")
      ], 2);
    };
  }
});
const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
  __name: "BTr",
  props: {
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BTr");
    const computedClasses = vue.computed(() => ({
      [`table-${props.variant}`]: props.variant !== null
    }));
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createElementBlock("tr", {
        class: vue.normalizeClass(computedClasses.value)
      }, [
        vue.renderSlot(_ctx.$slots, "default")
      ], 2);
    };
  }
});
const TABLE_TAG_NAMES = ["TD", "TH", "TR"];
const eventFilter = [
  "a",
  "a *",
  // Include content inside links
  "button",
  "button *",
  // Include content inside buttons
  "input:not(.disabled):not([disabled])",
  "select:not(.disabled):not([disabled])",
  "textarea:not(.disabled):not([disabled])",
  '[role="link"]',
  '[role="link"] *',
  '[role="button"]',
  '[role="button"] *',
  "[tabindex]:not(.disabled):not([disabled])"
].join(",");
const filterEvent = (event2) => {
  if (!event2 || !event2.target) {
    return false;
  }
  const el = event2.target;
  if ("disabled" in el && el.disabled || TABLE_TAG_NAMES.indexOf(el.tagName) !== -1) {
    return false;
  }
  if (el.closest(".dropdown-menu")) return true;
  const label = el.tagName === "LABEL" ? el : el.closest("label");
  if (label) {
    const labelFor = label.getAttribute("for");
    const input = labelFor ? document.getElementById(labelFor) : label.querySelector("input, select, textarea");
    if (input && !input.disabled) {
      return true;
    }
  }
  return el.matches(eventFilter);
};
const useTableFieldsMapper = ({
  fields,
  items,
  stackedProps
}) => {
  const computedFields = vue.computed(() => {
    const fieldsValue = vue.toValue(fields);
    const itemsValue = vue.toValue(items);
    const stacked = {
      stacked: vue.toValue(stackedProps.stacked),
      labelStacked: vue.toValue(stackedProps.labelStacked)
    };
    if (!fieldsValue.length && itemsValue.length) {
      const [firstItem] = itemsValue;
      if (firstItem && (isTableItem(firstItem) || Array.isArray(firstItem))) {
        return {
          items: Object.keys(firstItem).map((k) => {
            const label = stringUtils.startCase(k);
            return {
              key: k,
              label,
              tdAttr: tableUtils.getDataLabelAttr(stacked, label)
            };
          })
        };
      }
      return { items: [{ key: "" }], opts: { noHeader: true } };
    }
    return {
      items: fieldsValue.map((f) => {
        if (isTableField(f)) {
          const label2 = f.label ?? stringUtils.startCase(f.key);
          const dataLabelAttr = tableUtils.getDataLabelAttr(stacked, label2);
          const tdAttr = typeof f.tdAttr === "function" ? (obj) => ({
            ...dataLabelAttr,
            ...f.tdAttr(obj)
          }) : dataLabelAttr || f.tdAttr ? { ...dataLabelAttr, ...f.tdAttr } : void 0;
          return {
            ...f,
            tdAttr
          };
        }
        const label = stringUtils.startCase(f);
        return {
          key: f,
          label,
          tdAttr: tableUtils.getDataLabelAttr(stacked, label)
        };
      })
    };
  });
  const total = vue.computed(() => computedFields.value.items.length);
  const showHeaders = vue.computed(
    () => (
      // We only hide the header if all fields have _noHeader set to true. Which would be our doing
      // This usually happens under a circumstance of displaying an array of primitives
      // Under any other circumstance, I'm not sure how this would apply
      !(total.value > 0 && computedFields.value.opts?.noHeader === true)
    )
  );
  return {
    total,
    showHeaders,
    fields: vue.computed(() => computedFields.value.items)
  };
};
const useItemTracker = ({
  allItems,
  selectedItems,
  primaryKey
}) => {
  const isActivated = vue.computed(() => selectedItems.value.length > 0);
  const pKey = vue.readonly(vue.toRef(primaryKey));
  const get = (item) => {
    if (typeof item === "object" && item !== null && pKey.value) {
      return tableUtils.getWithGetter(item, pKey.value);
    }
    return item;
  };
  const add = (item) => {
    const value = get(item);
    selectedItems.value = [...selectedItems.value, value];
  };
  const set = (items) => {
    selectedItems.value = pKey.value ? items.map(get) : items;
  };
  const setAll = () => set([...vue.toValue(allItems)]);
  const remove = (item) => {
    const value = get(item);
    selectedItems.value = selectedItems.value.filter((i) => i !== value);
  };
  const clear = () => {
    selectedItems.value = [];
  };
  const has = (item) => {
    const value = get(item);
    return selectedItems.value.includes(value);
  };
  vue.watch(pKey, () => {
    clear();
  });
  const objectsMap = vue.computed(() => {
    if (!pKey.value) return /* @__PURE__ */ new Map();
    return new Map(vue.toValue(allItems).map((item) => [get(item), item]));
  });
  const getFromPrimaryKey = (value) => {
    if (!pKey.value) return void 0;
    return objectsMap.value.get(value);
  };
  const resolvedItems = vue.computed(() => {
    if (!pKey.value) return selectedItems.value;
    const arr = [];
    selectedItems.value.forEach((item) => {
      const resolved = getFromPrimaryKey(item);
      if (resolved !== void 0) {
        arr.push(resolved);
      }
    });
    return arr;
  });
  return {
    getFromPrimaryKey,
    resolvedItems,
    isActivated,
    get,
    add,
    remove,
    clear,
    set,
    has,
    setAll
  };
};
const useItemExpansion = ({
  allItems,
  primaryKey,
  expandedItems
}) => {
  const utils = useItemTracker({
    primaryKey,
    allItems,
    selectedItems: expandedItems
  });
  const toggle = (item) => {
    if (utils.has(item)) {
      utils.remove(item);
    } else {
      utils.add(item);
    }
  };
  return {
    ...utils,
    toggle
  };
};
const useTableKeyboardNavigation = ({
  items,
  id
}, events) => {
  const keyboardNavigation = vue.inject(keys.tableKeyboardNavigationKey, null);
  const shouldHeaderBeFocusable = (field) => !!(keyboardNavigation?.headerNavigation.value && field.sortable === true);
  const shouldRowBeFocusable = vue.computed(
    () => !!(keyboardNavigation?.rowNavigation.value && vue.toValue(items).length > 0)
  );
  const headerClicked = (field, event2, isFooter = false) => {
    events.onHeadClicked({ key: field.key, field, event: event2, isFooter });
  };
  const handleHeaderKeydown = (field, event$1, isFooter = false) => {
    const { target, code } = event$1;
    if (target && target.tagName !== "TH" && document.activeElement === target) return;
    if (code === "Enter" || code === "NumpadEnter" || code === "Space") {
      event.stopEvent(event$1);
      headerClicked(field, event$1, isFooter);
    }
  };
  const handleRowKeydown = (item, itemIndex, event$1) => {
    const { target, code, shiftKey } = event$1;
    if (target && target.tagName !== "TR" && document.activeElement === target) return;
    if (code === "Enter" || code === "NumpadEnter" || code === "Space") {
      event.stopEvent(event$1);
      events.onRowClicked({ item, index: itemIndex, event: event$1 });
      return;
    }
    if (code === constants.CODE_DOWN || code === constants.CODE_UP || code === constants.CODE_HOME || code === constants.CODE_END) {
      event.stopEvent(event$1);
      handleRowNavigation(code, shiftKey, itemIndex);
    }
  };
  const handleRowNavigation = (code, shiftKey, currentIndex) => {
    const rows = Array.from(
      document.querySelectorAll(`#${vue.toValue(id)} tbody tr[tabindex]`)
    );
    if (rows.length === 0) return;
    let targetIndex = currentIndex;
    if (code === constants.CODE_DOWN) {
      if (shiftKey) {
        targetIndex = rows.length - 1;
      } else {
        targetIndex = Math.min(currentIndex + 1, rows.length - 1);
      }
    } else if (code === constants.CODE_UP) {
      if (shiftKey) {
        targetIndex = 0;
      } else {
        targetIndex = Math.max(currentIndex - 1, 0);
      }
    } else if (code === constants.CODE_END) {
      targetIndex = rows.length - 1;
    } else if (code === constants.CODE_HOME) {
      targetIndex = 0;
    }
    if (targetIndex !== currentIndex && rows[targetIndex]) {
      rows[targetIndex].focus();
    }
  };
  const handleMiddleClick = (item, itemIndex, event2) => {
    if (event2.button === 1 && !filterEvent(event2)) {
      events.onRowMiddleClicked({ item, index: itemIndex, event: event2 });
    }
  };
  return {
    shouldHeaderBeFocusable,
    headerClicked,
    handleHeaderKeydown,
    shouldRowBeFocusable,
    handleRowKeydown,
    handleMiddleClick
  };
};
const _hoisted_1$1 = { key: 0 };
const _hoisted_2$1 = {
  key: 0,
  class: "b-table-stacked-label"
};
const _hoisted_3 = { class: "d-inline-flex flex-nowrap align-items-center gap-1" };
const _hoisted_4 = { key: 3 };
const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
  __name: "BTableLite",
  props: /* @__PURE__ */ vue.mergeModels({
    align: { default: void 0 },
    caption: { default: void 0 },
    detailsTdClass: { default: void 0 },
    fieldColumnClass: { type: [Function, String, Object, Array], default: void 0 },
    fields: { default: () => [] },
    footClone: { type: Boolean, default: false },
    footRowVariant: { default: void 0 },
    footVariant: { default: void 0 },
    headRowVariant: { default: void 0 },
    headVariant: { default: void 0 },
    items: { default: () => [] },
    labelStacked: { type: Boolean, default: false },
    modelValue: { default: void 0 },
    primaryKey: { type: [String, Function], default: void 0 },
    tbodyClass: { default: void 0 },
    tbodyTrAttrs: { type: [Function, Object], default: void 0 },
    tbodyTrClass: { type: [Function, String, Array, Object], default: void 0 },
    tfootClass: { default: void 0 },
    tfootTrClass: { default: void 0 },
    theadClass: { default: void 0 },
    theadTrClass: { default: void 0 },
    bordered: { type: Boolean, default: void 0 },
    borderless: { type: Boolean, default: void 0 },
    borderVariant: { default: void 0 },
    captionTop: { type: Boolean, default: void 0 },
    dark: { type: Boolean, default: void 0 },
    fixed: { type: Boolean, default: void 0 },
    hover: { type: Boolean, default: void 0 },
    id: { default: void 0 },
    noBorderCollapse: { type: Boolean, default: void 0 },
    outlined: { type: Boolean, default: void 0 },
    responsive: { type: [Boolean, String], default: void 0 },
    small: { type: Boolean, default: void 0 },
    stacked: { type: [Boolean, String], default: void 0 },
    stickyHeader: { type: [Boolean, String, Number], default: void 0 },
    striped: { type: Boolean, default: void 0 },
    stripedColumns: { type: Boolean, default: void 0 },
    variant: { default: void 0 },
    tableAttrs: {},
    tableClass: { default: void 0 }
  }, {
    "expandedItems": {
      default: () => []
    },
    "expandedItemsModifiers": {}
  }),
  emits: /* @__PURE__ */ vue.mergeModels(["head-clicked", "row-clicked", "row-dblclicked", "row-contextmenu", "row-hovered", "row-unhovered", "row-middle-clicked"], ["update:expandedItems"]),
  setup(__props, { expose: __expose, emit: __emit }) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BTableLite");
    const emit = __emit;
    const slots = vue.useSlots();
    const expandedItems = vue.useModel(
      __props,
      "expandedItems"
    );
    const computedId = useId.useId(() => props.id);
    const expandedItemsController = useItemExpansion({
      allItems: () => props.items,
      primaryKey: vue.toRef(() => props.primaryKey),
      expandedItems
    });
    const keyboardController = useTableKeyboardNavigation(
      {
        items: () => props.items,
        id: computedId
      },
      {
        onHeadClicked: (obj) => {
          emit("head-clicked", obj);
        },
        onRowClicked: (obj) => {
          emit("row-clicked", obj);
        },
        onRowMiddleClicked: (obj) => {
          emit("row-middle-clicked", obj);
        }
      }
    );
    const {
      fields: computedFields,
      total: computedFieldsTotal,
      showHeaders: showComputedHeaders
    } = useTableFieldsMapper({
      fields: () => props.fields,
      items: () => props.items,
      stackedProps: {
        labelStacked: () => props.labelStacked,
        stacked: () => props.stacked
      }
    });
    const calculatedFooterSlot = (key) => slots[`foot(${key})`] ? `foot(${key})` : slots["foot()"] ? "foot()" : slots[`head(${key})`] ? `head(${key})` : "head()";
    const computedTableClasses = vue.computed(() => [
      props.tableClass,
      {
        [`align-${props.align}`]: props.align !== void 0
      }
    ]);
    const getFieldColumnClasses = (field) => [
      field.class,
      field.thClass,
      {
        "b-table-sticky-column": field.stickyColumn
      },
      props.fieldColumnClass ? typeof props.fieldColumnClass === "function" ? props.fieldColumnClass(field) : props.fieldColumnClass : null
    ];
    const getFieldRowClasses = (field, tr) => [
      field.class,
      typeof field.tdClass === "function" ? field.tdClass(tableUtils.getByFieldKey(tr, field), field.key, tr) : field.tdClass,
      (isTableItem(tr) ? tr._cellVariants?.[field.key] : false) ? `table-${tr._cellVariants?.[field.key]}` : null,
      {
        "b-table-sticky-column": field.stickyColumn
      }
    ];
    const getRowClasses = (item, type) => props.tbodyTrClass ? typeof props.tbodyTrClass === "function" ? props.tbodyTrClass(item, type) : props.tbodyTrClass : null;
    const itemAttributes = (item, field) => field.tdAttr && typeof field.tdAttr === "function" ? field.tdAttr({ value: tableUtils.getByFieldKey(item, field), key: field.key, item }) : field.tdAttr;
    const callThAttr = (item, field, type) => field.thAttr && typeof field.thAttr === "function" ? field.thAttr({ value: tableUtils.getByFieldKey(item, field), key: field.key, item, type }) : field.thAttr;
    const callTbodyTrAttrs = (item, type) => props.tbodyTrAttrs ? typeof props.tbodyTrAttrs === "function" ? props.tbodyTrAttrs(item, type) : props.tbodyTrAttrs : null;
    const generateTableRowId = (primaryKeyValue) => `${computedId.value}__row_${primaryKeyValue}`;
    const getCellComponent = (field) => {
      if (field?.isRowHeader) {
        return _sfc_main$4;
      }
      return _sfc_main$6;
    };
    const footerProps = vue.computed(() => ({
      variant: props.footVariant ?? props.headVariant,
      class: props.tfootClass ?? props.theadClass
    }));
    const computedSimpleProps = vue.computed(() => ({
      ...object.pick(props, tableUtils.bTableSimpleProps),
      tableClass: computedTableClasses.value,
      id: computedId.value
    }));
    __expose({
      expansion: {
        ...expandedItemsController,
        expandedItems: vue.readonly(expandedItems)
      }
    });
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createBlock(BTableSimple_vue_vue_type_script_setup_true_lang._sfc_main, vue.normalizeProps(vue.guardReactiveProps(computedSimpleProps.value)), {
        default: vue.withCtx(() => [
          slots["table-colgroup"] ? (vue.openBlock(), vue.createElementBlock("colgroup", _hoisted_1$1, [
            vue.renderSlot(_ctx.$slots, "table-colgroup", { fields: vue.unref(computedFields) })
          ])) : vue.createCommentVNode("", true),
          vue.withDirectives(vue.createVNode(_sfc_main$3, {
            variant: vue.unref(props).headVariant,
            class: vue.normalizeClass(vue.unref(props).theadClass)
          }, {
            default: vue.withCtx(() => [
              vue.renderSlot(_ctx.$slots, "thead-top", {
                columns: vue.unref(computedFieldsTotal),
                fields: vue.unref(computedFields)
              }),
              vue.createVNode(_sfc_main$2, {
                variant: vue.unref(props).headRowVariant,
                class: vue.normalizeClass(vue.unref(props).theadTrClass)
              }, {
                default: vue.withCtx(() => [
                  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(computedFields), (field) => {
                    return vue.openBlock(), vue.createBlock(_sfc_main$4, vue.mergeProps({
                      key: field.key,
                      scope: field.scope,
                      class: getFieldColumnClasses(field),
                      title: field.headerTitle,
                      variant: field.variant,
                      abbr: field.headerAbbr,
                      style: field.thStyle,
                      tabindex: vue.unref(keyboardController).shouldHeaderBeFocusable(field) ? "0" : void 0
                    }, { ref_for: true }, callThAttr(null, field, "top"), {
                      onClick: ($event) => vue.unref(keyboardController).headerClicked(field, $event),
                      onKeydown: ($event) => vue.unref(keyboardController).handleHeaderKeydown(field, $event)
                    }), {
                      default: vue.withCtx(() => [
                        vue.renderSlot(_ctx.$slots, slots[`head(${field.key})`] ? `head(${field.key})` : "head()", {
                          label: field.label,
                          column: field.key,
                          field,
                          isFoot: false
                        }, () => [
                          vue.createTextVNode(vue.toDisplayString(vue.unref(tableUtils.getTableFieldHeadLabel)(field)), 1)
                        ])
                      ]),
                      _: 2
                    }, 1040, ["scope", "class", "title", "variant", "abbr", "style", "tabindex", "onClick", "onKeydown"]);
                  }), 128))
                ]),
                _: 3
              }, 8, ["variant", "class"]),
              slots["thead-sub"] ? (vue.openBlock(), vue.createBlock(_sfc_main$2, { key: 0 }, {
                default: vue.withCtx(() => [
                  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(computedFields), (field) => {
                    return vue.openBlock(), vue.createBlock(_sfc_main$6, {
                      key: field.key,
                      scope: "col",
                      variant: field.variant,
                      class: vue.normalizeClass([field.class, field.thClass])
                    }, {
                      default: vue.withCtx(() => [
                        vue.renderSlot(_ctx.$slots, "thead-sub", {
                          items: vue.unref(props).items,
                          fields: vue.unref(computedFields),
                          field
                        }, () => [
                          vue.createTextVNode(vue.toDisplayString(field.label), 1)
                        ])
                      ]),
                      _: 2
                    }, 1032, ["variant", "class"]);
                  }), 128))
                ]),
                _: 3
              })) : vue.createCommentVNode("", true)
            ]),
            _: 3
          }, 8, ["variant", "class"]), [
            [vue.vShow, vue.unref(showComputedHeaders)]
          ]),
          vue.createVNode(_sfc_main$7, {
            class: vue.normalizeClass(vue.unref(props).tbodyClass)
          }, {
            default: vue.withCtx(() => [
              vue.renderSlot(_ctx.$slots, "custom-body", {
                fields: vue.unref(computedFields),
                items: vue.unref(props).items,
                columns: vue.unref(computedFieldsTotal)
              }, () => [
                !vue.unref(props).stacked && slots["top-row"] ? (vue.openBlock(), vue.createBlock(_sfc_main$2, vue.mergeProps({
                  key: 0,
                  class: getRowClasses(null, "row-top")
                }, callTbodyTrAttrs(null, "row-top")), {
                  default: vue.withCtx(() => [
                    vue.renderSlot(_ctx.$slots, "top-row", {
                      columns: vue.unref(computedFieldsTotal),
                      fields: vue.unref(computedFields)
                    })
                  ]),
                  _: 3
                }, 16, ["class"])) : vue.createCommentVNode("", true),
                (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(props).items, (item, itemIndex) => {
                  return vue.openBlock(), vue.createElementBlock(vue.Fragment, {
                    key: vue.unref(props).primaryKey && vue.unref(isTableItem)(item) && vue.unref(tableUtils.getWithGetter)(item, vue.unref(props).primaryKey) ? vue.unref(tableUtils.getWithGetter)(item, vue.unref(props).primaryKey) : itemIndex
                  }, [
                    vue.createVNode(_sfc_main$2, vue.mergeProps({
                      id: vue.unref(props).primaryKey && vue.unref(isTableItem)(item) && vue.unref(tableUtils.getWithGetter)(item, vue.unref(props).primaryKey) ? generateTableRowId(vue.unref(tableUtils.getWithGetter)(item, vue.unref(props).primaryKey)) : void 0,
                      class: getRowClasses(item, "row"),
                      variant: vue.unref(isTableItem)(item) ? item._rowVariant : void 0,
                      tabindex: vue.unref(keyboardController).shouldRowBeFocusable.value ? "0" : void 0
                    }, { ref_for: true }, callTbodyTrAttrs(item, "row"), {
                      onClick: ($event) => !vue.unref(filterEvent)($event) && emit("row-clicked", { item, index: itemIndex, event: $event }),
                      onDblclick: ($event) => !vue.unref(filterEvent)($event) && emit("row-dblclicked", { item, index: itemIndex, event: $event }),
                      onContextmenu: ($event) => !vue.unref(filterEvent)($event) && emit("row-contextmenu", { item, index: itemIndex, event: $event }),
                      onMouseenter: ($event) => !vue.unref(filterEvent)($event) && emit("row-hovered", { item, index: itemIndex, event: $event }),
                      onMouseleave: ($event) => !vue.unref(filterEvent)($event) && emit("row-unhovered", { item, index: itemIndex, event: $event }),
                      onMousedown: ($event) => vue.unref(keyboardController).handleMiddleClick(item, itemIndex, $event),
                      onKeydown: ($event) => vue.unref(keyboardController).handleRowKeydown(item, itemIndex, $event)
                    }), {
                      default: vue.withCtx(() => [
                        (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(computedFields), (field) => {
                          return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(getCellComponent(field)), vue.mergeProps({
                            key: field.key,
                            variant: (vue.unref(isTableItem)(item) ? item._cellVariants?.[field.key] : false) ? null : field.variant,
                            class: getFieldRowClasses(field, item)
                          }, { ref_for: true }, itemAttributes(item, field)), {
                            default: vue.withCtx(() => [
                              vue.unref(props).stacked && vue.unref(props).labelStacked ? (vue.openBlock(), vue.createElementBlock("label", _hoisted_2$1, vue.toDisplayString(vue.unref(tableUtils.getTableFieldHeadLabel)(field)), 1)) : vue.createCommentVNode("", true),
                              vue.renderSlot(_ctx.$slots, slots[`cell(${field.key})`] ? `cell(${field.key})` : "cell()", {
                                value: vue.unref(tableUtils.formatItem)(item, field),
                                unformatted: vue.unref(tableUtils.getByFieldKey)(item, field),
                                index: itemIndex,
                                item,
                                field,
                                items: vue.unref(props).items,
                                toggleExpansion: () => vue.unref(expandedItemsController).toggle(item),
                                expansionShowing: vue.unref(expandedItemsController).has(item)
                              }, () => [
                                !slots[`cell(${field.key})`] && !slots["cell()"] ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
                                  vue.createTextVNode(vue.toDisplayString(vue.unref(tableUtils.formatItem)(item, field)), 1)
                                ], 64)) : vue.createCommentVNode("", true)
                              ])
                            ]),
                            _: 2
                          }, 1040, ["variant", "class"]);
                        }), 128))
                      ]),
                      _: 2
                    }, 1040, ["id", "class", "variant", "tabindex", "onClick", "onDblclick", "onContextmenu", "onMouseenter", "onMouseleave", "onMousedown", "onKeydown"]),
                    vue.unref(expandedItemsController).has(item) && slots["row-expansion"] ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
                      vue.createVNode(_sfc_main$2, {
                        "aria-hidden": "true",
                        role: "presentation",
                        class: "d-none"
                      }),
                      vue.createVNode(_sfc_main$2, vue.mergeProps({
                        class: getRowClasses(item, "row-expansion"),
                        variant: vue.unref(isTableItem)(item) ? item._rowVariant : void 0
                      }, { ref_for: true }, callTbodyTrAttrs(item, "row-expansion")), {
                        default: vue.withCtx(() => [
                          vue.createVNode(_sfc_main$6, {
                            colspan: vue.unref(computedFieldsTotal),
                            class: vue.normalizeClass(__props.detailsTdClass)
                          }, {
                            default: vue.withCtx(() => [
                              vue.renderSlot(_ctx.$slots, "row-expansion", {
                                item,
                                toggleExpansion: () => vue.unref(expandedItemsController).toggle(item),
                                fields: vue.unref(computedFields),
                                index: itemIndex
                              })
                            ]),
                            _: 2
                          }, 1032, ["colspan", "class"])
                        ]),
                        _: 2
                      }, 1040, ["class", "variant"])
                    ], 64)) : vue.createCommentVNode("", true)
                  ], 64);
                }), 128)),
                !vue.unref(props).stacked && slots["bottom-row"] ? (vue.openBlock(), vue.createBlock(_sfc_main$2, vue.mergeProps({
                  key: 1,
                  class: ["bottom-row", getRowClasses(null, "row-bottom")]
                }, callTbodyTrAttrs(null, "row-bottom")), {
                  default: vue.withCtx(() => [
                    vue.renderSlot(_ctx.$slots, "bottom-row", {
                      columns: vue.unref(computedFieldsTotal),
                      fields: vue.unref(computedFields)
                    })
                  ]),
                  _: 3
                }, 16, ["class"])) : vue.createCommentVNode("", true)
              ])
            ]),
            _: 3
          }, 8, ["class"]),
          vue.unref(props).footClone ? (vue.openBlock(), vue.createBlock(_sfc_main$5, vue.normalizeProps(vue.mergeProps({ key: 1 }, footerProps.value)), {
            default: vue.withCtx(() => [
              vue.createVNode(_sfc_main$2, {
                variant: vue.unref(props).footRowVariant ?? vue.unref(props).headRowVariant,
                class: vue.normalizeClass(vue.unref(props).tfootTrClass ?? vue.unref(props).theadTrClass)
              }, {
                default: vue.withCtx(() => [
                  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(computedFields), (field) => {
                    return vue.openBlock(), vue.createBlock(_sfc_main$4, vue.mergeProps({
                      key: field.key,
                      scope: "col",
                      class: getFieldColumnClasses(field),
                      title: field.headerTitle,
                      abbr: field.headerAbbr,
                      style: field.thStyle,
                      variant: field.variant,
                      tabindex: vue.unref(keyboardController).shouldHeaderBeFocusable(field) ? "0" : void 0
                    }, { ref_for: true }, callThAttr(null, field, "bottom"), {
                      onClick: ($event) => vue.unref(keyboardController).headerClicked(field, $event, true),
                      onKeydown: ($event) => vue.unref(keyboardController).handleHeaderKeydown(field, $event, true)
                    }), {
                      default: vue.withCtx(() => [
                        vue.createElementVNode("div", _hoisted_3, [
                          vue.createElementVNode("div", null, [
                            vue.renderSlot(_ctx.$slots, calculatedFooterSlot(field.key), {
                              label: field.label,
                              column: field.key,
                              field,
                              isFoot: true
                            }, () => [
                              vue.createTextVNode(vue.toDisplayString(vue.unref(tableUtils.getTableFieldHeadLabel)(field)), 1)
                            ])
                          ])
                        ])
                      ]),
                      _: 2
                    }, 1040, ["class", "title", "abbr", "style", "variant", "tabindex", "onClick", "onKeydown"]);
                  }), 128))
                ]),
                _: 3
              }, 8, ["variant", "class"])
            ]),
            _: 3
          }, 16)) : slots["custom-foot"] ? (vue.openBlock(), vue.createBlock(_sfc_main$5, vue.normalizeProps(vue.mergeProps({ key: 2 }, footerProps.value)), {
            default: vue.withCtx(() => [
              vue.renderSlot(_ctx.$slots, "custom-foot", {
                fields: vue.unref(computedFields),
                items: vue.unref(props).items,
                columns: vue.unref(computedFieldsTotal)
              })
            ]),
            _: 3
          }, 16)) : vue.createCommentVNode("", true),
          slots["table-caption"] || vue.unref(props).caption ? (vue.openBlock(), vue.createElementBlock("caption", _hoisted_4, [
            vue.renderSlot(_ctx.$slots, "table-caption", {}, () => [
              vue.createTextVNode(vue.toDisplayString(vue.unref(props).caption), 1)
            ])
          ])) : vue.createCommentVNode("", true)
        ]),
        _: 3
      }, 16);
    };
  }
});
const useTableMapper = ({
  fields,
  items,
  stackedProps,
  provider,
  events,
  pagination
}) => {
  const sortByModelResolved = vue.readonly(vue.toRef(pagination.sort.by));
  const isSortableResolved = vue.readonly(vue.toRef(pagination.sort.isSortable));
  const filterResolved = vue.readonly(vue.toRef(pagination.filter.filter));
  const usesProviderResolved = vue.readonly(vue.toRef(provider.usesProvider));
  const isFilterableTable = vue.computed(() => filterResolved.value !== void 0);
  const computedFields = vue.computed(
    () => vue.toValue(fields).map((el) => {
      if (!isTableField(el)) {
        const label = stringUtils.startCase(el);
        return {
          key: el,
          label,
          tdAttr: tableUtils.getDataLabelAttr(
            {
              stacked: vue.toValue(stackedProps.stacked),
              labelStacked: vue.toValue(stackedProps.labelStacked)
            },
            label
          )
        };
      }
      const value = sortByModelResolved.value?.find((sb) => el.key === sb.key);
      const sortValue = !el.sortable || isSortableResolved.value === false ? void 0 : value === void 0 ? "none" : value.order === "desc" ? "descending" : value.order === "asc" ? "ascending" : "none";
      return {
        ...el,
        thAttr: {
          "aria-sort": sortValue,
          ...el.thAttr
        },
        thClass: [
          el.thClass,
          {
            "b-table-sort-icon-left": vue.toValue(pagination.sort.iconLeft) && sortValue !== void 0
          }
        ]
      };
    })
  );
  const getFormatter = (value) => typeof value.sortByFormatted === "function" ? value.sortByFormatted : value.formatter;
  const getStringValue = (ob, key) => {
    if (!isTableItem(ob)) return String(ob);
    const sortField = computedFields.value.find((el) => {
      if (isTableField(el)) return el.key === key;
      return false;
    });
    const val = isTableField(sortField) && sortField.accessor ? tableUtils.getWithGetter(ob, sortField.accessor) : tableUtils.getWithGetter(ob, key);
    if (isTableField(sortField) && !!sortField.sortByFormatted) {
      const formatter = getFormatter(sortField);
      if (formatter) {
        return String(tableUtils.formatItem(ob, { ...sortField, formatter }));
      }
    }
    return typeof val === "object" && val !== null ? JSON.stringify(val) : val?.toString() ?? "";
  };
  const fieldByKey = vue.computed(() => {
    const map = /* @__PURE__ */ new Map();
    for (const f of computedFields.value) if (isTableField(f)) map.set(f.key, f);
    return map;
  });
  const computedItems = vue.computed(() => {
    const filterableValue = vue.toValue(pagination.filter.filterable);
    const filterFunctionValue = vue.unref(pagination.filter.filterFunction);
    const itemsValue = vue.toValue(items);
    const sortByItems = sortByModelResolved.value?.filter((el) => !!el.order);
    const mapItem = (item) => {
      if (typeof item === "object" && item !== null && Object.keys(item).some((key) => key.includes("."))) {
        let newItem = {};
        for (const key in item) {
          if (key.includes(".")) {
            newItem = object.set(newItem, key, item[key]);
          } else {
            newItem[key] = item[key];
          }
        }
        return newItem;
      }
      return item;
    };
    const filterItem = (item) => {
      if (!isTableItem(item)) return true;
      return Object.entries(item).some(([key, val]) => {
        if (val === null || val === void 0 || key[0] === "_" || !filterableValue?.includes(key) && !!filterableValue?.length)
          return false;
        if (typeof filterFunctionValue === "function") {
          return filterFunctionValue(item, filterResolved.value);
        }
        const realVal = () => {
          const filterField = computedFields.value.find((el) => {
            if (isTableField(el)) return el.key === key;
            return false;
          });
          if (isTableField(filterField) && !!filterField.filterByFormatted) {
            const formatter = getFormatter(filterField);
            if (formatter) {
              return String(formatter({ value: val, key: String(filterField.key), item }));
            }
          }
          return typeof val === "object" ? JSON.stringify(Object.values(val)) : val.toString();
        };
        const itemValue = realVal();
        return itemValue.toLowerCase().includes(filterResolved.value?.toLowerCase() ?? "");
      });
    };
    const noProviderFilteringValue = vue.toValue(provider.noProviderFiltering);
    const mappedItems = itemsValue.reduce((acc, val) => {
      const item = mapItem(val);
      const shouldFilter = isFilterableTable.value && (!usesProviderResolved.value || noProviderFilteringValue);
      if (!shouldFilter || filterItem(item)) acc.push(item);
      return acc;
    }, []);
    if (sortByItems?.length && (isSortableResolved.value === true && !usesProviderResolved.value && !vue.toValue(pagination.sort.noLocalSorting) || isSortableResolved.value === true && usesProviderResolved.value && vue.toValue(provider.noProviderSorting))) {
      const sortCompareValue = vue.unref(pagination.sort.sortCompare);
      return mappedItems.sort((a, b) => {
        for (let i = 0; i < sortByItems.length; i++) {
          const { key, order } = sortByItems[i];
          const field = fieldByKey.value.get(key);
          const comparer = field?.sortCompare || sortCompareValue;
          const comparison = comparer ? comparer(a, b, key) : getStringValue(a, key).localeCompare(getStringValue(b, key), void 0, {
            numeric: true
          });
          if (comparison !== 0) {
            return order === "asc" ? comparison : -comparison;
          }
        }
        return 0;
      });
    }
    return mappedItems;
  });
  const computedDisplayItems = vue.computed(() => {
    const perPageNumber = vue.toValue(pagination.perPage);
    const currentPageNumber = vue.toValue(pagination.currentPage);
    if (Number.isNaN(perPageNumber) || usesProviderResolved.value && !vue.toValue(provider.noProviderPaging)) {
      return computedItems.value;
    }
    return computedItems.value.slice(
      (currentPageNumber - 1) * (perPageNumber || Number.POSITIVE_INFINITY),
      currentPageNumber * (perPageNumber || Number.POSITIVE_INFINITY)
    );
  });
  vue.watch(computedDisplayItems, (v) => {
    events.onChange([...v]);
  });
  return {
    items: computedItems,
    displayItems: computedDisplayItems,
    getStringValue,
    fields: computedFields,
    isFilterableTable
  };
};
const useTableKeyboardNavigationInjector = ({
  isSortable,
  selectable,
  noSelectOnClick
}) => {
  const keyboardRowNavigation = vue.computed(() => !!(vue.toValue(selectable) && !vue.toValue(noSelectOnClick)));
  const keyboardHeaderNavigation = vue.computed(() => !!vue.toValue(isSortable));
  vue.provide(keys.tableKeyboardNavigationKey, {
    rowNavigation: keyboardRowNavigation,
    headerNavigation: keyboardHeaderNavigation
  });
};
const useTableSelectedItems = ({
  selectable,
  selectMode,
  selectedItems,
  events,
  primaryKey,
  allItems
}) => {
  const selectableResolved = vue.readonly(vue.toRef(selectable));
  const selectModeResolved = vue.readonly(vue.toRef(selectMode));
  const allItemsResolved = vue.computed(() => vue.toValue(allItems));
  const utils = useItemTracker({
    allItems: allItemsResolved,
    primaryKey,
    selectedItems
  });
  vue.watch(selectedItems, (newValue, oldValue) => {
    Array.from(oldValue).filter((item) => !newValue.includes(item)).forEach((item) => {
      events.onRowUnselected(item);
    });
    Array.from(newValue).filter((item) => !oldValue.includes(item)).forEach((item) => {
      events.onRowSelected(item);
    });
  });
  const handleRowSelection = ({
    item,
    index: index2,
    shiftClicked = false,
    ctrlClicked = false,
    metaClicked = false
  }) => {
    if (!selectableResolved.value) return;
    if (selectModeResolved.value === "single" || selectModeResolved.value === "multi") {
      if (shiftClicked || ctrlClicked) return;
      if (utils.has(item)) {
        utils.remove(item);
      } else {
        if (selectModeResolved.value === "single") {
          utils.set([item]);
        } else {
          utils.add(item);
        }
      }
    } else {
      if (ctrlClicked || metaClicked) {
        if (utils.has(item)) {
          utils.remove(item);
        } else {
          utils.add(item);
        }
      } else if (shiftClicked) {
        const lastSelectedItem = selectedItems.value[selectedItems.value.length - 1];
        const lastSelectedIndex = allItemsResolved.value.findIndex(
          (i) => utils.get(i) === lastSelectedItem
        );
        if (lastSelectedIndex === -1) {
          utils.set([item]);
          return;
        }
        const selectStartIndex = Math.min(lastSelectedIndex, index2);
        const selectEndIndex = Math.max(lastSelectedIndex, index2);
        const items = allItemsResolved.value.slice(selectStartIndex, selectEndIndex + 1);
        utils.set(items);
      } else {
        utils.set([item]);
      }
    }
  };
  return {
    ...utils,
    handleRowSelection,
    clear: () => {
      if (!selectableResolved.value) return;
      utils.clear();
    },
    setAll: () => {
      if (!selectableResolved.value || selectModeResolved.value === "single") return;
      utils.setAll();
    },
    add: (item) => {
      if (!selectableResolved.value || utils.has(item)) return;
      if (selectModeResolved.value === "single") {
        utils.set([item]);
      } else {
        utils.add(item);
      }
    },
    remove: (item) => {
      if (!selectableResolved.value) return;
      utils.remove(item);
    },
    has: (item) => {
      if (!selectableResolved.value) return false;
      return utils.has(item);
    }
  };
};
const useTableProvider = ({
  items,
  provider,
  busy,
  currentPage,
  debounce: debounce$1,
  perPage,
  noProvider,
  noProviderFiltering,
  noProviderPaging,
  noProviderSorting,
  filter,
  sortBy,
  events
}) => {
  const providerResolved = vue.readonly(vue.toRef(provider));
  const currentPageResolved = vue.readonly(vue.toRef(currentPage));
  const perPageResolved = vue.readonly(vue.toRef(perPage));
  const sortByResolved = vue.readonly(vue.toRef(sortBy));
  const filterResolved = vue.readonly(vue.toRef(filter));
  const usesProvider = vue.computed(() => providerResolved.value !== void 0);
  let abortController = null;
  const callItemsProvider = async () => {
    if (!usesProvider.value || providerResolved.value === void 0) return;
    if (abortController) {
      abortController.abort();
    }
    abortController = new AbortController();
    const { signal } = abortController;
    busy.value = true;
    try {
      const response = providerResolved.value({
        currentPage: currentPageResolved.value,
        filter: filterResolved.value,
        sortBy: sortByResolved.value,
        perPage: perPageResolved.value,
        signal
      });
      const returnValue = response instanceof Promise ? await response : response;
      if (signal.aborted) return;
      if (returnValue === void 0) return;
      items.value = returnValue;
    } catch (error) {
      if (error instanceof Error && error.name === "AbortError") return;
      throw error;
    } finally {
      if (!signal.aborted) {
        busy.value = false;
      }
    }
  };
  const debouncedCallItemsProvider = debounce.useDebounceFn(callItemsProvider, debounce$1.wait, {
    maxWait: debounce$1.maxWait
  });
  const providerPropsWatch = async (prop, val, oldVal) => {
    if (object.deepEqual(val, oldVal)) return;
    const inNoProvider = (key) => vue.toValue(noProvider)?.includes(key) === true;
    const noProvideWhenPaging = (prop === "currentPage" || prop === "perPage") && (inNoProvider("paging") || vue.toValue(noProviderPaging) === true);
    const noProvideWhenFiltering = prop === "filter" && (inNoProvider("filtering") || vue.toValue(noProviderFiltering) === true);
    const noProvideWhenSorting = (prop === "sortBy" || prop === "sortDesc") && (inNoProvider("sorting") || vue.toValue(noProviderSorting) === true);
    if (noProvideWhenPaging || noProvideWhenFiltering || noProvideWhenSorting) return;
    if (usesProvider.value === true) {
      await debouncedCallItemsProvider();
    }
    if (!(prop === "currentPage" || prop === "perPage")) {
      events.onFiltered();
    }
  };
  vue.watch(filterResolved, (filter2, oldFilter) => {
    providerPropsWatch("filter", filter2, oldFilter);
  });
  vue.watch(currentPageResolved, (val, oldVal) => {
    providerPropsWatch("currentPage", val, oldVal);
  });
  vue.watch(perPageResolved, (val, oldVal) => {
    providerPropsWatch("perPage", val, oldVal);
  });
  vue.watch(
    sortByResolved,
    (val, oldVal) => {
      providerPropsWatch("sortBy", val, oldVal);
    },
    { deep: true }
  );
  vue.watch(providerResolved, (newValue) => {
    if (newValue === void 0) {
      items.value = [];
      return;
    }
    callItemsProvider();
  });
  vue.onMounted(callItemsProvider);
  return {
    usesProvider,
    callItemsProvider
  };
};
const useTableSort = ({
  fields,
  sortBy,
  initialSortDirection,
  multisort,
  mustSort,
  events
}) => {
  const isSortable = vue.computed(
    () => sortBy.value !== void 0 || vue.toValue(fields).some(
      (field) => typeof field === "object" && field !== null && field.sortable === true
    )
  );
  const handleFieldSorting = (field) => {
    if (!isSortable.value) return;
    const fieldKey = typeof field === "object" && field !== null ? field.key : field;
    const fieldSortable = typeof field === "object" && field !== null ? field.sortable : false;
    if (!(isSortable.value === true && fieldSortable === true)) return;
    const getLastSortDirection = () => {
      const lastSorted = [...sortBy.value ?? []].reverse().find((sort) => sort.order !== void 0 && sort.key !== fieldKey);
      return lastSorted?.order ?? "asc";
    };
    const getInitialSortDirection = () => {
      if (typeof field === "object" && field !== null && field.initialSortDirection) {
        if (field.initialSortDirection === "last") {
          return getLastSortDirection();
        }
        return field.initialSortDirection;
      }
      const initialSortDirectionValue = vue.toValue(initialSortDirection);
      if (initialSortDirectionValue) {
        if (initialSortDirectionValue === "last") {
          return getLastSortDirection();
        }
        return initialSortDirectionValue;
      }
      return "asc";
    };
    const resolveOrder = (val) => {
      const mustSortValue = vue.toValue(mustSort);
      if (val === void 0) return getInitialSortDirection();
      const initial = getInitialSortDirection();
      const must = mustSortValue === true || !!mustSortValue && mustSortValue.includes(fieldKey);
      if (val === "asc") {
        if (initial === "desc") {
          return must ? "desc" : void 0;
        }
        return "desc";
      }
      if (val === "desc") {
        if (initial === "desc") {
          return "asc";
        }
        return must ? "asc" : void 0;
      }
      return void 0;
    };
    const index2 = sortBy.value?.findIndex((el) => el.key === fieldKey) ?? -1;
    const originalValue = sortBy.value?.[index2];
    const updatedValue = (
      // If value is new, we use the field's initialSortDirection or default to ascending
      // Otherwise we make a temp copy of the value
      index2 === -1 || !originalValue ? { key: fieldKey, order: getInitialSortDirection() } : { ...originalValue }
    );
    const handleMultiSort = () => {
      const tmp = [...sortBy.value ?? []];
      const val = updatedValue;
      if (index2 === -1) {
        tmp.push(val);
      } else {
        const order = resolveOrder(val.order);
        if (order) {
          val.order = order;
          tmp.splice(index2, 1, val);
        } else {
          val.order = void 0;
          tmp.splice(index2, 1);
        }
      }
      sortBy.value = tmp;
      return val;
    };
    const handleSingleSort = () => {
      const order = index2 === -1 ? updatedValue.order : resolveOrder(updatedValue.order);
      const val = {
        ...updatedValue,
        order
      };
      sortBy.value = order ? [val] : [];
      return val;
    };
    events.onSorted(vue.toValue(multisort) === true ? handleMultiSort() : handleSingleSort());
  };
  return {
    isSortable,
    handleFieldSorting
  };
};
const _hoisted_1 = {
  role: "alert",
  "aria-live": "polite"
};
const _hoisted_2 = { class: "text-center my-2" };
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  __name: "BTable",
  props: /* @__PURE__ */ vue.mergeModels({
    provider: { type: Function, default: void 0 },
    noProvider: { default: void 0 },
    noProviderPaging: { type: Boolean, default: false },
    noProviderSorting: { type: Boolean, default: false },
    noProviderFiltering: { type: Boolean, default: false },
    sortCompare: { type: Function, default: void 0 },
    mustSort: { type: [Boolean, Array], default: false },
    initialSortDirection: { default: "asc" },
    selectable: { type: Boolean, default: false },
    multisort: { type: Boolean, default: false },
    stickySelect: { type: Boolean, default: false },
    selectHead: { type: [Boolean, String], default: true },
    selectMode: { default: "multi" },
    selectionVariant: { default: "primary" },
    perPage: { default: Number.POSITIVE_INFINITY },
    currentPage: { default: 1 },
    filter: { default: void 0 },
    filterFunction: { type: Function, default: void 0 },
    filterable: { default: void 0 },
    noLocalSorting: { type: Boolean, default: false },
    noSelectOnClick: { type: Boolean, default: false },
    noSortableIcon: { type: Boolean, default: false },
    sortIconLeft: { type: Boolean, default: false },
    emptyFilteredText: { default: "There are no records matching your request" },
    emptyText: { default: "There are no records to show" },
    showEmpty: { type: Boolean, default: false },
    align: { default: void 0 },
    caption: { default: void 0 },
    detailsTdClass: { default: void 0 },
    fieldColumnClass: { type: [Function, String, Object, Array], default: void 0 },
    fields: { default: () => [] },
    footClone: { type: Boolean, default: void 0 },
    footRowVariant: { default: void 0 },
    footVariant: { default: void 0 },
    headRowVariant: { default: void 0 },
    headVariant: { default: void 0 },
    labelStacked: { type: Boolean, default: void 0 },
    modelValue: { default: void 0 },
    expandedItems: {},
    primaryKey: { type: [String, Function], default: void 0 },
    tbodyClass: { default: void 0 },
    tbodyTrAttrs: {},
    tbodyTrClass: { type: [Function, String, Array, Object], default: void 0 },
    tfootClass: { default: void 0 },
    tfootTrClass: { default: void 0 },
    theadClass: { default: void 0 },
    theadTrClass: { default: void 0 },
    bordered: { type: Boolean, default: void 0 },
    borderless: { type: Boolean, default: void 0 },
    borderVariant: { default: void 0 },
    captionTop: { type: Boolean, default: void 0 },
    dark: { type: Boolean, default: void 0 },
    fixed: { type: Boolean, default: void 0 },
    hover: { type: Boolean, default: void 0 },
    id: { default: void 0 },
    noBorderCollapse: { type: Boolean, default: void 0 },
    outlined: { type: Boolean, default: void 0 },
    responsive: { type: [Boolean, String], default: void 0 },
    small: { type: Boolean, default: void 0 },
    stacked: { type: [Boolean, String], default: void 0 },
    stickyHeader: { type: [Boolean, String, Number], default: void 0 },
    striped: { type: Boolean, default: void 0 },
    stripedColumns: { type: Boolean, default: void 0 },
    variant: { default: void 0 },
    tableAttrs: {},
    debounce: { default: 0 },
    debounceMaxWait: { default: Number.NaN }
  }, {
    "sortBy": {
      default: void 0
    },
    "sortByModifiers": {},
    "busy": { type: Boolean, ...{
      default: false
    } },
    "busyModifiers": {},
    "selectedItems": {
      default: () => []
    },
    "selectedItemsModifiers": {},
    "expandedItems": {
      default: () => []
    },
    "expandedItemsModifiers": {},
    "items": {
      default: () => []
    },
    "itemsModifiers": {}
  }),
  emits: /* @__PURE__ */ vue.mergeModels(["filtered", "row-selected", "row-unselected", "sorted", "change", "head-clicked", "row-clicked", "row-dblclicked", "row-contextmenu", "row-hovered", "row-unhovered", "row-middle-clicked"], ["update:sortBy", "update:busy", "update:selectedItems", "update:expandedItems", "update:items"]),
  setup(__props, { expose: __expose, emit: __emit }) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BTable");
    const emit = __emit;
    const slots = vue.useSlots();
    const dynamicCellSlots = vue.computed(
      () => Object.keys(slots).filter((key) => key.startsWith("cell("))
    );
    const dynamicFootSlots = vue.computed(
      () => Object.keys(slots).filter((key) => key.startsWith("foot("))
    );
    const sortByModel = vue.useModel(__props, "sortBy");
    const busyModel = vue.useModel(__props, "busy");
    const selectedItemsModel = vue.useModel(
      __props,
      "selectedItems"
    );
    const expandedItems = vue.useModel(
      __props,
      "expandedItems"
    );
    const itemsModel = vue.useModel(__props, "items");
    const computedId = useId.useId(() => props.id);
    const perPageNumber = index.useToNumber(() => props.perPage, { method: "parseInt" });
    const currentPageNumber = index.useToNumber(() => props.currentPage, { method: "parseInt" });
    const debounceNumber = index.useToNumber(() => props.debounce ?? 0, { nanToZero: true });
    const debounceMaxWaitNumber = index.useToNumber(() => props.debounceMaxWait ?? Number.NaN);
    const sortController = useTableSort({
      fields: () => props.fields,
      sortBy: sortByModel,
      events: {
        onSorted: (v) => {
          emit("sorted", v);
        }
      },
      initialSortDirection: () => props.initialSortDirection,
      mustSort: () => props.mustSort,
      multisort: () => props.multisort
    });
    const providerController = useTableProvider({
      items: itemsModel,
      events: {
        onFiltered: () => {
          emit("filtered", computedItems.value);
        }
      },
      busy: busyModel,
      provider: vue.toRef(() => props.provider),
      debounce: {
        maxWait: debounceMaxWaitNumber,
        wait: debounceNumber
      },
      currentPage: currentPageNumber,
      perPage: perPageNumber,
      filter: () => props.filter,
      noProvider: () => props.noProvider,
      noProviderFiltering: () => props.noProviderFiltering,
      noProviderPaging: () => props.noProviderPaging,
      noProviderSorting: () => props.noProviderSorting,
      sortBy: sortByModel
    });
    const expandedItemsController = useItemExpansion({
      allItems: itemsModel,
      primaryKey: vue.toRef(() => props.primaryKey),
      expandedItems
    });
    const {
      items: computedItems,
      displayItems: computedDisplayItems,
      getStringValue,
      fields: computedFields,
      isFilterableTable
    } = useTableMapper({
      fields: () => props.fields,
      provider: {
        noProviderFiltering: () => props.noProviderFiltering,
        noProviderPaging: () => props.noProviderPaging,
        noProviderSorting: () => props.noProviderSorting,
        usesProvider: providerController.usesProvider
      },
      events: {
        onChange: (v) => {
          emit("change", v);
        }
      },
      items: itemsModel,
      pagination: {
        perPage: perPageNumber,
        currentPage: currentPageNumber,
        filter: {
          filter: () => props.filter,
          filterFunction: vue.toRef(() => props.filterFunction),
          filterable: () => props.filterable
        },
        sort: {
          iconLeft: () => props.sortIconLeft,
          isSortable: sortController.isSortable,
          noLocalSorting: () => props.noLocalSorting,
          by: sortByModel,
          sortCompare: vue.toRef(() => props.sortCompare)
        }
      },
      stackedProps: {
        stacked: () => props.stacked,
        labelStacked: () => props.labelStacked
      }
    });
    const selectedItemsController = useTableSelectedItems({
      selectable: () => props.selectable,
      primaryKey: vue.toRef(() => props.primaryKey),
      selectedItems: selectedItemsModel,
      allItems: computedItems,
      selectMode: () => props.selectMode,
      events: {
        onRowSelected: (item) => {
          emit("row-selected", item);
        },
        onRowUnselected: (item) => {
          emit("row-unselected", item);
        }
      }
    });
    useTableKeyboardNavigationInjector({
      isSortable: sortController.isSortable,
      selectable: () => props.selectable,
      noSelectOnClick: () => props.noSelectOnClick
    });
    const tableClasses = vue.computed(() => ({
      "b-table-busy": busyModel.value,
      "b-table-selectable": props.selectable,
      "user-select-none": props.selectable && !props.noSelectOnClick && selectedItemsController.isActivated.value,
      "b-table-fixed": props.fixed,
      "b-table-no-border-collapse": props.noBorderCollapse,
      "b-table-no-sort-icon": props.noSortableIcon
    }));
    const getBusyRowClasses = vue.computed(() => [
      props.tbodyTrClass ? typeof props.tbodyTrClass === "function" ? props.tbodyTrClass(null, "table-busy") : props.tbodyTrClass : null
    ]);
    const getFieldColumnClasses = (field) => [
      {
        "b-table-sortable-column": sortController.isSortable.value && field.sortable
      }
    ];
    const getRowClasses = (item, type) => [
      {
        [`selected table-${props.selectionVariant}`]: props.selectable && !!item && selectedItemsController.has(item)
      },
      props.tbodyTrClass ? typeof props.tbodyTrClass === "function" ? props.tbodyTrClass(item, type) : props.tbodyTrClass : null
    ];
    const boundBTableLiteEmits = {
      onHeadClicked: ({ key, field, event: event2, isFooter = false }) => {
        emit("head-clicked", { key, field, event: event2, isFooter });
        sortController.handleFieldSorting(field);
      },
      onRowClicked: ({ item, index: index2, event: event2 }) => {
        if (props.noSelectOnClick === false) {
          selectedItemsController.handleRowSelection({
            item,
            index: index2,
            shiftClicked: event2.shiftKey,
            ctrlClicked: event2.ctrlKey,
            metaClicked: event2.metaKey
          });
        }
        emit("row-clicked", { item, index: index2, event: event2 });
      },
      onRowDblclicked: (...args) => emit("row-dblclicked", ...args),
      onRowContextmenu: (...args) => emit("row-contextmenu", ...args),
      onRowHovered: (...args) => emit("row-hovered", ...args),
      onRowUnhovered: (...args) => emit("row-unhovered", ...args),
      onRowMiddleClicked: (...args) => emit("row-middle-clicked", ...args)
    };
    const computedLiteProps = vue.computed(() => ({
      ...object.pick(props, [...tableUtils.bTableLiteProps, ...tableUtils.bTableSimpleProps]),
      tableAttrs: {
        ariaBusy: busyModel.value
      },
      items: computedDisplayItems.value,
      fields: computedFields.value,
      tableClass: tableClasses.value,
      tbodyTrClass: getRowClasses,
      fieldColumnClass: getFieldColumnClasses,
      id: computedId.value,
      ...boundBTableLiteEmits
    }));
    const emptySlotScope = vue.computed(() => ({
      emptyFilteredText: props.emptyFilteredText,
      emptyText: props.emptyText,
      fields: computedFields.value,
      items: computedItems.value
    }));
    const showEmptyFiltered = vue.computed(
      () => isFilterableTable.value && props.filter !== void 0 && props.filter !== ""
    );
    __expose({
      expansion: {
        ...expandedItemsController,
        expandedItems: vue.readonly(expandedItems)
      },
      selection: {
        ...selectedItemsController,
        selectedItems: vue.readonly(selectedItemsModel)
      },
      items: computedItems,
      displayItems: computedDisplayItems,
      getStringValue,
      refresh: providerController.callItemsProvider
    });
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createBlock(_sfc_main$1, vue.mergeProps(computedLiteProps.value, {
        "expanded-items": expandedItems.value,
        "onUpdate:expandedItems": _cache[0] || (_cache[0] = ($event) => expandedItems.value = $event)
      }), vue.createSlots({
        "custom-body": vue.withCtx((scope) => [
          busyModel.value && slots["table-busy"] ? (vue.openBlock(), vue.createBlock(_sfc_main$2, {
            key: 0,
            class: vue.normalizeClass(["b-table-busy-slot", getBusyRowClasses.value])
          }, {
            default: vue.withCtx(() => [
              vue.createVNode(_sfc_main$6, {
                colspan: scope.fields.length
              }, {
                default: vue.withCtx(() => [
                  vue.renderSlot(_ctx.$slots, "table-busy")
                ]),
                _: 3
              }, 8, ["colspan"])
            ]),
            _: 2
          }, 1032, ["class"])) : !busyModel.value && vue.unref(props).showEmpty === true && vue.unref(computedItems).length === 0 ? (vue.openBlock(), vue.createBlock(_sfc_main$2, {
            key: 1,
            class: "b-table-empty-row"
          }, {
            default: vue.withCtx(() => [
              vue.createVNode(_sfc_main$6, {
                colspan: vue.unref(computedFields).length
              }, {
                default: vue.withCtx(() => [
                  vue.createElementVNode("div", _hoisted_1, [
                    vue.createElementVNode("div", _hoisted_2, [
                      showEmptyFiltered.value ? vue.renderSlot(_ctx.$slots, "empty-filtered", vue.normalizeProps(vue.mergeProps({ key: 0 }, emptySlotScope.value)), () => [
                        vue.createTextVNode(vue.toDisplayString(vue.unref(props).emptyFilteredText), 1)
                      ]) : vue.renderSlot(_ctx.$slots, "empty", vue.normalizeProps(vue.mergeProps({ key: 1 }, emptySlotScope.value)), () => [
                        vue.createTextVNode(vue.toDisplayString(vue.unref(props).emptyText), 1)
                      ])
                    ])
                  ])
                ]),
                _: 3
              }, 8, ["colspan"])
            ]),
            _: 3
          })) : vue.createCommentVNode("", true)
        ]),
        _: 2
      }, [
        slots["table-colgroup"] ? {
          name: "table-colgroup",
          fn: vue.withCtx((scope) => [
            vue.renderSlot(_ctx.$slots, "table-colgroup", vue.normalizeProps(vue.guardReactiveProps(scope)))
          ]),
          key: "0"
        } : void 0,
        slots["thead-top"] ? {
          name: "thead-top",
          fn: vue.withCtx((scope) => [
            vue.renderSlot(_ctx.$slots, "thead-top", vue.mergeProps(scope, {
              clearSelected: vue.unref(selectedItemsController).clear,
              selectAllRows: vue.unref(selectedItemsController).setAll,
              fields: vue.unref(computedFields)
            }))
          ]),
          key: "1"
        } : void 0,
        slots["thead-sub"] ? {
          name: "thead-sub",
          fn: vue.withCtx((scope) => [
            vue.renderSlot(_ctx.$slots, "thead-sub", vue.mergeProps(scope, { fields: vue.unref(computedFields) }))
          ]),
          key: "2"
        } : void 0,
        slots["top-row"] ? {
          name: "top-row",
          fn: vue.withCtx((scope) => [
            vue.renderSlot(_ctx.$slots, "top-row", vue.mergeProps(scope, { fields: vue.unref(computedFields) }))
          ]),
          key: "3"
        } : void 0,
        slots["row-expansion"] ? {
          name: "row-expansion",
          fn: vue.withCtx((scope) => [
            vue.renderSlot(_ctx.$slots, "row-expansion", vue.mergeProps(scope, {
              fields: vue.unref(computedFields),
              selectRow: () => vue.unref(selectedItemsController).add(scope.item),
              unselectRow: () => vue.unref(selectedItemsController).remove(scope.item),
              rowSelected: vue.unref(selectedItemsController).has(scope.item)
            }))
          ]),
          key: "4"
        } : void 0,
        slots["bottom-row"] ? {
          name: "bottom-row",
          fn: vue.withCtx((scope) => [
            vue.renderSlot(_ctx.$slots, "bottom-row", vue.mergeProps(scope, { fields: vue.unref(computedFields) }))
          ]),
          key: "5"
        } : void 0,
        slots["custom-foot"] ? {
          name: "custom-foot",
          fn: vue.withCtx((scope) => [
            vue.renderSlot(_ctx.$slots, "custom-foot", vue.mergeProps(scope, { fields: vue.unref(computedFields) }))
          ]),
          key: "6"
        } : void 0,
        slots["table-caption"] ? {
          name: "table-caption",
          fn: vue.withCtx(() => [
            vue.renderSlot(_ctx.$slots, "table-caption")
          ]),
          key: "7"
        } : void 0,
        vue.renderList(dynamicCellSlots.value, (name) => {
          return {
            name,
            fn: vue.withCtx((scope) => [
              vue.renderSlot(_ctx.$slots, name, vue.mergeProps(scope, {
                selectRow: () => vue.unref(selectedItemsController).add(scope.item),
                unselectRow: () => vue.unref(selectedItemsController).remove(scope.item),
                rowSelected: vue.unref(selectedItemsController).has(scope.item)
              }))
            ])
          };
        }),
        vue.renderList(dynamicFootSlots.value, (name) => {
          return {
            name,
            fn: vue.withCtx((scope) => [
              vue.renderSlot(_ctx.$slots, name, vue.mergeProps(scope, {
                selectAllRows: vue.unref(selectedItemsController).setAll,
                clearSelected: vue.unref(selectedItemsController).clear
              }))
            ])
          };
        }),
        vue.renderList(vue.unref(computedFields), (field) => {
          return {
            name: `head(${String(field.key)})`,
            fn: vue.withCtx((scope) => [
              vue.renderSlot(
                _ctx.$slots,
                slots[`head(${String(field.key)})`] ? `head(${String(field.key)})` : "head()",
                vue.mergeProps(scope, {
                  selectAllRows: vue.unref(selectedItemsController).setAll,
                  clearSelected: vue.unref(selectedItemsController).clear
                }),
                () => [
                  vue.createTextVNode(vue.toDisplayString(vue.unref(tableUtils.getTableFieldHeadLabel)(field)), 1)
                ]
              )
            ])
          };
        })
      ]), 1040, ["expanded-items"]);
    };
  }
});
exports._sfc_main = _sfc_main;
exports._sfc_main$1 = _sfc_main$1;
exports._sfc_main$2 = _sfc_main$7;
exports._sfc_main$3 = _sfc_main$6;
exports._sfc_main$4 = _sfc_main$5;
exports._sfc_main$5 = _sfc_main$4;
exports._sfc_main$6 = _sfc_main$3;
exports._sfc_main$7 = _sfc_main$2;
//# sourceMappingURL=BTable.vue_vue_type_script_setup_true_lang-C1eq5oli.js.map
