UNPKG

@base-framework/ui

Version:

This is a UI package that adds components and atoms that use Tailwind CSS and a theme based on Shadcn.

1,848 lines 50.3 kB
import { Button as x, Div as o, On as v, Span as D, Th as O, UseParent as F, I as E, Thead as Q, Tr as X, Table as I, P as p, Li as S, Time as q, Nav as C, Ul as w, Section as z, Canvas as K } from "@base-framework/atoms";
import { Atom as d, Component as u, Data as L, DateTime as G, router as b, NavLink as $, DataTracker as N, Jot as V, base as M, Dom as R } from "@base-framework/base";
import { B as T, I as _ } from "./buttons-CHEs54Wl.js";
import { Icons as k } from "./icons.es.js";
import { TableBody as J, DataTableBody as Z, ScrollableTableBody as ee, List as te, IntervalTimer as se } from "@base-framework/organisms";
import { C as ae, I as ie, H as ne } from "./inputs-DYxmO1rQ.js";
import { A as oe, P as le } from "./range-calendar-UXMh98a5.js";
d((t, e) => ({
  class: "flex items-center px-4 py-2",
  ...t,
  children: e
}));
d(({ value: t, label: e }) => x({
  class: "inline-flex flex-auto items-center justify-center whitespace-nowrap rounded-md px-8 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
  onState: ["performance", { active: t }],
  dataSet: ["performance", ["state", t, "active"]],
  click: (s, { state: a }) => a.performance = t
}, e));
class at extends u {
  /**
   * This will declare the props for the compiler.
   *
   * @returns {void}
   */
  declareProps() {
    this.class = "";
  }
  /**
   * This will render the component.
   *
   * @returns {object}
   */
  render() {
    return o({ class: this.class || "" }, this.children);
  }
}
const re = (t) => {
  const e = new Date(t, 11, 31), s = new Date(t, 0, 1);
  return e.getDay() === 4 || // December 31 is a Thursday
  s.getDay() === 4;
}, ce = (t) => {
  const e = new Date(t.valueOf()), s = (e.getDay() + 6) % 7;
  e.setDate(e.getDate() - s + 3);
  const a = e.getFullYear(), i = new Date(a, 0, 4);
  i.setDate(i.getDate() - (i.getDay() + 6) % 7);
  const n = Math.ceil((e - i) / 6048e5) + 1;
  return n > 52 && !re(a) ? {
    weekNumber: 1,
    year: a + 1
  } : {
    weekNumber: n,
    year: a
  };
}, de = (t, e, s) => {
  if (s === 0) return [];
  const a = new Date(t, e, 0).getDate();
  return Array.from(
    { length: s },
    (i, n) => new Date(t, e - 1, a - s + n + 1)
  );
}, he = (t, e, s) => Array.from({ length: s }, (a, i) => new Date(t, e + 1, i + 1)), W = (t, e) => {
  const s = new Date(e, 0, 4), a = (s.getDay() + 6) % 7, i = new Date(s);
  i.setDate(s.getDate() - a);
  const n = new Date(i);
  return n.setDate(i.getDate() + (t - 1) * 7), n;
}, it = (t, e) => {
  const s = new Date(t, e, 1).getDay(), a = new Date(t, e + 1, 0).getDate(), i = [];
  let n = [];
  for (let l = 1 - s; l <= a; l++) {
    const c = new Date(t, e, l);
    n.push(l > 0 ? c : null), (n.length === 7 || l === a) && (i.push([...n]), n = []);
  }
  return i;
}, nt = (t, e) => {
  const s = new Date(t, e + 1, 0).getDate(), a = [];
  let i = [];
  for (let n = 1; n <= s; n++)
    i.push(new Date(t, e, n)), i.length === 7 && (a.push(i), i = []);
  return i.length > 0 && a.push(i), a;
}, ue = (t, e, s) => {
  const a = /* @__PURE__ */ new Date();
  return a.getDate() === t && a.getMonth() === e && a.getFullYear() === s;
}, fe = ({ day: t, month: e, year: s, weekNumber: a, selectWeek: i }) => {
  const n = ue(t, e, s);
  return x({
    text: t || "",
    disabled: !t,
    class: `
			px-2 py-1 text-center rounded-md
			${n ? "bg-accent text-accent-foreground" : ""}
			hover:bg-primary hover:text-primary-foreground
		`,
    click: () => i(a, s)
  });
}, me = (t, e) => {
  const s = new Date(t, e, 1).getDay(), a = new Date(t, e + 1, 0).getDate(), i = de(t, e, s), n = Array.from({ length: a }, (h, g) => new Date(t, e, g + 1)), l = (i.length + n.length) % 7, c = l === 0 ? 0 : 7 - l, r = he(t, e, c), f = [...i, ...n, ...r], m = [];
  for (let h = 0; h < f.length; h += 7) {
    const g = f.slice(h, h + 7), y = g.find((Y) => Y) || new Date(t, e, 1), { weekNumber: A, year: U } = ce(y);
    m.push({
      weekNumber: A,
      year: U,
      days: g
    });
  }
  return m;
}, ge = ({ selectWeek: t }) => v("month", (e, s, { data: a }) => {
  const { year: i, month: n, currentDate: l } = a, c = me(i, n);
  return o(
    { class: "grid grid-cols-8 gap-1 text-sm px-4 py-2" },
    [
      // Header row: "Week" label + day-of-week labels
      o({ class: "text-xs text-center col-span-1 text-muted-foreground flex items-center" }, "Week"),
      o(
        {
          class: "grid grid-cols-7 col-span-7 text-center text-muted-foreground items-center"
        },
        ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map(
          (r) => D({ class: "px-1 py-1", text: r })
        )
      ),
      // Render each "week" row
      ...c.map(
        ({ weekNumber: r, days: f, year: m }) => o({
          class: "grid grid-cols-8 col-span-8 items-center ring-primary rounded-sm px-1",
          onSet: ["currentWeek", {
            ring: r
          }]
        }, [
          // Left column: ISO week number
          o({
            class: "font-medium text-center col-span-1 rounded-sm cursor-pointer",
            click: () => t(r, m),
            // If you have a 'currentWeek' state, you can highlight it with 'onSet'
            onSet: ["currentWeek", {
              "text-primary-foreground": r,
              "bg-primary": r
            }],
            text: r ? `W${r}` : ""
          }),
          // The 7 cells for each day in the row
          o(
            { class: "grid grid-cols-7 col-span-7 text-center" },
            f.map(
              (h) => fe({
                year: h?.getFullYear() || null,
                month: h?.getMonth() || null,
                day: h?.getDate() || null,
                weekNumber: r,
                selectWeek: t
              })
            )
          )
        ])
      )
    ]
  );
}), P = ({ label: t, click: e }) => T(
  {
    class: `
			inline-flex items-center justify-center h-7 w-7 bg-transparent p-0
			opacity-50 hover:opacity-100 text-muted-foreground absolute
			${t === "Previous" ? "left-1" : "right-1"}
			focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2
		  `,
    click: e,
    "aria-label": `${t} month`,
    variant: "icon",
    icon: t === "Previous" ? k.chevron.single.left : k.chevron.single.right
  }
), pe = ({ next: t, previous: e }) => o({ class: "flex flex-auto min-h-12 text-sm font-medium relative justify-center items-center" }, [
  D("[[monthName]] [[year]]"),
  P({
    label: "Previous",
    click: e
  }),
  P({
    label: "Next",
    click: t
  })
]);
class ot extends u {
  /**
   * This will declare the props for the compiler.
   *
   * @returns {void}
   */
  declareProps() {
    this.selectedDate = null, this.selectedWeek = null, this.selectedCallBack = null;
  }
  /**
   * Initializes the calendar data.
   *
   * @returns {Data}
   */
  setData() {
    const e = /* @__PURE__ */ new Date(), s = this.selectedWeek || this.calculateCurrentWeek(e), a = W(s, e.getFullYear());
    return new L({
      monthName: this.getMonthName(a.getMonth()),
      year: a.getFullYear(),
      month: a.getMonth(),
      currentDate: a.getDate(),
      currentWeek: s
    });
  }
  /**
   * Determines the current selected date.
   *
   * @param {Date} today
   * @returns {Date}
   */
  getSelectedDate(e) {
    const s = this.selectedDate ? new Date(this.selectedDate) : e;
    return new Date(s.getFullYear(), s.getMonth(), s.getDate());
  }
  /**
   * Calculates the ISO week number for a given date.
   *
   * @param {Date} date
   * @returns {number}
   */
  calculateCurrentWeek(e) {
    const s = new Date(e.valueOf()), a = (e.getDay() + 6) % 7;
    s.setDate(s.getDate() - a + 3);
    const i = s.valueOf();
    return s.setMonth(0, 1), s.getDay() !== 4 && s.setMonth(0, 1 + (4 - s.getDay() + 7) % 7), 1 + Math.ceil((i - s) / 6048e5);
  }
  /**
   * Gets the name of the month.
   *
   * @param {number} month
   * @returns {string}
   */
  getMonthName(e) {
    return G.monthNames[e];
  }
  /**
   * Updates the calendar to show the previous month.
   *
   * @returns {void}
   */
  goToPreviousMonth() {
    const e = this.data;
    let { year: s, month: a } = e;
    a === 0 ? (a = 11, s--) : a--, this.setDate(a, s);
  }
  /**
   * Updates the calendar to show the next month.
   *
   * @returns {void}
   */
  goToNextMonth() {
    const e = this.data;
    let { year: s, month: a } = e;
    a === 11 ? (a = 0, s++) : a++, this.setDate(a, s);
  }
  /**
   * Sets the selected date.
   *
   * @param {number} month
   * @param {number} year
   * @param {number|null} [date=null]
   * @returns {void}
   */
  setDate(e, s, a) {
    this.data.set({
      year: s,
      month: e,
      monthName: this.getMonthName(e)
    }), a && (this.data.currentDate = a);
  }
  /**
   * Handles week selection.
   *
   * @param {number} weekNumber
   * @returns {void}
   */
  selectWeek(e, s) {
    this.data.currentWeek = e;
    const a = W(e, s);
    this.setDate(a.getMonth(), a.getFullYear(), a.getDate()), typeof this.selectedCallBack == "function" && this.selectedCallBack(e);
  }
  /**
   * Renders the WeekCalendar component.
   *
   * @returns {object}
   */
  render() {
    return o({ class: "week-calendar-container border rounded-md p-3" }, [
      pe({
        next: () => this.goToNextMonth(),
        previous: () => this.goToPreviousMonth()
      }),
      ge({
        selectWeek: (e, s) => this.selectWeek(e, s)
      })
    ]);
  }
}
const we = (t, e) => {
  const s = t.toggleAllSelectedRows();
  e.state.checked = !s;
}, ye = (t) => O({ class: `cursor-pointer py-3 px-4 text-base w-10 ${t.class || ""}` }, [
  F((e) => new ae({ class: "mr-2", onChange: (s, a) => we(e, a) }))
]), be = ({ align: t, sortable: e, key: s, label: a, sort: i, class: n }) => {
  const l = t || "justify-start";
  return O({
    class: `cursor-pointer py-3 px-4 text-base ${n || ""}`,
    click: e && (() => i(s))
  }, [
    o({ class: `flex flex-auto w-full items-center ${l}` }, [
      D(a),
      e && E({ class: "ml-2", html: k.arrows.upDown })
    ])
  ]);
}, B = (t) => Q([
  X({
    class: "text-muted-foreground border-b",
    map: [
      t.headers,
      (e) => e.label === "checkbox" ? ye({ toggle: t.toggle }) : be({
        align: e.align,
        sortable: e.sortable,
        key: e.key,
        label: e.label,
        sort: t.sort
      })
    ]
  })
]), ke = ({ key: t, rows: e, selectRow: s, rowItem: a, emptyState: i, skeleton: n, columnCount: l }) => new J({
  cache: "list",
  key: t,
  items: e,
  rowItem: (c) => a(c, s),
  class: "divide-y divide-border",
  emptyState: i,
  skeleton: n,
  columnCount: l
});
class H extends u {
  /**
   * Initializes component data.
   *
   * @returns {Data}
   */
  setData() {
    let e = this.rows && this.rows.length > 0;
    return (this.loadMoreItems || this.tableData) && !e && (e = null), new L({
      selectedRows: [],
      // @ts-ignore
      hasItems: e,
      selected: !1
    });
  }
  /**
   * This will toggle all selected rows.
   *
   * @returns {boolean}
   */
  toggleAllSelectedRows() {
    const e = this.list.getRows(), s = this.data.selectedRows.length === e.length, a = s ? [] : e;
    return this.data.selectedRows = a, this.updateSelected(), this.updateTable(!s), s;
  }
  /**
   * This will update the selected state.
   *
   * @returns {void}
   */
  updateSelected() {
    const e = this.data.get("selectedRows");
    this.data.selected = e.length > 0;
  }
  /**
   * This will get the selected rows.
   *
   * @returns {Array<object>}
   */
  getSelectedRows() {
    return this.data.get("selectedRows");
  }
  /**
   * This will update the table rows.
   *
   * @protected
   * @param {boolean} selected
   * @returns {void}
   */
  updateTable(e) {
    const s = this.list.getRows();
    s.forEach((a) => a.selected = e), this.list.setRows(s);
  }
  /**
   * Handles row selection.
   *
   * @param {object} row
   */
  selectRow(e) {
    const s = e.selected ?? !1;
    e.selected = !s;
    const a = this.data.get("selectedRows"), i = e.selected ? [...a, e] : a.filter((n) => n !== e);
    this.data.selectedRows = i, this.updateSelected();
  }
  /**
   * Gets the number of header columns.
   *
   * @returns {number}
   */
  getHeaderColCount() {
    return this.customHeader ? this.customHeader?.children[0]?.children?.length : this.headers ? this.headers.length : 3;
  }
  /**
   * Renders the DataTable component.
   *
   * @returns {object}
   */
  render() {
    const e = this.border !== !1 ? "border" : "", s = this.getHeaderColCount();
    return o({ class: "w-full flex flex-auto flex-col" }, [
      v("hasItems", (a) => a === !1 && this.emptyState ? this.emptyState() : null),
      o({ class: `w-full rounded-md ${e} overflow-x-auto`, onSet: ["hasItems", { hidden: !1 }] }, [
        I({ class: "w-full" }, [
          // @ts-ignore
          this.headers && B({ headers: this.headers, sort: (a) => this.sortRows(a) }),
          // @ts-ignore
          this.customHeader ?? null,
          ke({
            // @ts-ignore
            key: this.key,
            // @ts-ignore
            rows: this.rows,
            // @ts-ignore
            selectRow: this.selectRow.bind(this),
            // @ts-ignore
            rowItem: this.rowItem,
            // @ts-ignore
            emptyState: this.emptyState,
            // @ts-ignore
            skeleton: this.skeleton,
            columnCount: s
          })
        ])
      ])
    ]);
  }
  /**
   * This will remove items from the list.
   *
   * @public
   * @param {array} items
   * @returns {void}
   */
  remove(e) {
    this.list.remove(e);
  }
  /**
   * This will set the items in the list.
   *
   * @public
   * @param {array} rows
   * @returns {void}
   */
  setRows(e) {
    this.list.setRows(e);
  }
  /**
   * This will append items to the list.
   *
   * @public
   * @param {array|object} items
   * @returns {void}
   */
  append(e) {
    this.list.append(e);
  }
  /**
   * This will mingle the new items with the old items.
   *
   * @public
   * @param {Array<Object>} newItems
   * @param {boolean} withDelete
   * @returns {void}
   */
  mingle(e, s = !1) {
    this.list.mingle(e, s);
  }
  /**
   * This will prepend items to the list.
   *
   * @public
   * @param {array|object} items
   * @returns {void}
   */
  prepend(e) {
    this.list.prepend(e);
  }
  /**
   * This will remove the selected rows.
   *
   * @returns {void}
   */
  beforeDestroy() {
    this.data.selectedRows = [];
  }
}
const xe = (t) => new Z({
  cache: "list",
  loadMoreItems: t.loadMoreItems,
  offset: t.offset,
  limit: t.limit,
  key: t.key,
  tableData: t.tableData,
  items: t.items,
  rowItem: (e) => t.rowItem(e, t.selectRow),
  class: "divide-y divide-border",
  skeleton: t.skeleton,
  columnCount: t.columnCount
});
class ve extends H {
  /**
   * Renders the DataTable component.
   *
   * @returns {object}
   */
  render() {
    const e = this.border !== !1 ? "border" : "", s = this.getHeaderColCount();
    return o({ class: "w-full flex flex-auto flex-col" }, [
      v("hasItems", (a) => a === !1 && this.emptyState ? this.emptyState() : null),
      o({ class: `w-full rounded-md ${e} overflow-x-auto`, onSet: ["hasItems", { hidden: !1 }] }, [
        I({ class: "w-full" }, [
          // @ts-ignore
          this.headers && B({ headers: this.headers, sort: (a) => this.sortRows(a) }),
          // @ts-ignore
          this.customHeader ?? null,
          xe({
            // @ts-ignore
            loadMoreItems: this.loadMoreItems,
            // @ts-ignore
            offset: this.offset,
            // @ts-ignore
            limit: this.limit,
            // @ts-ignore
            class: this.class,
            // @ts-ignore
            tableData: this.tableData,
            // @ts-ignore
            key: this.key,
            // @ts-ignore
            items: this.rows,
            // @ts-ignore
            selectRow: this.selectRow.bind(this),
            // @ts-ignore
            rowItem: this.rowItem,
            // @ts-ignore
            skeleton: this.skeleton,
            columnCount: s
          })
        ])
      ])
    ]);
  }
  /**
   * Refreshes the list.
   *
   * @returns {void}
   */
  refresh() {
    this.list.refresh();
  }
}
const lt = d((t) => new ve(
  {
    cache: t.cache ?? "list",
    tableData: t.data,
    loadMoreItems: t.loadMoreItems,
    offset: t.offset,
    limit: t.limit,
    class: t.class,
    key: t.key,
    rows: t.rows,
    rowItem: t.rowItem,
    headers: t.headers,
    customHeader: t.customHeader,
    border: t.border,
    emptyState: t.emptyState,
    skeleton: t.skeleton
  }
)), De = (t) => new ee({
  cache: "list",
  scrollContainer: t.scrollContainer,
  loadMoreItems: t.loadMoreItems,
  offset: t.offset,
  limit: t.limit,
  key: t.key,
  tableData: t.tableData,
  items: t.items,
  rowItem: (e) => t.rowItem(e, t.selectRow),
  class: "divide-y divide-border",
  skeleton: t.skeleton,
  columnCount: t.columnCount
});
class Se extends H {
  /**
   * Renders the DataTable component.
   *
   * @returns {object}
   */
  render() {
    const e = this.border !== !1 ? "border" : "", s = this.getHeaderColCount();
    return o({ class: "w-full flex flex-auto flex-col" }, [
      v("hasItems", (a) => a === !1 && this.emptyState ? this.emptyState() : null),
      o({ class: `w-full rounded-md ${e} overflow-x-auto`, onSet: ["hasItems", { hidden: !1 }] }, [
        I({ class: "w-full" }, [
          // @ts-ignore
          this.headers && B({ headers: this.headers, sort: (a) => this.sortRows(a) }),
          // @ts-ignore
          this.customHeader ?? null,
          De({
            // @ts-ignore
            scrollContainer: this.scrollContainer,
            // @ts-ignore
            loadMoreItems: this.loadMoreItems,
            // @ts-ignore
            offset: this.offset,
            // @ts-ignore
            limit: this.limit,
            // @ts-ignore
            class: this.class,
            // @ts-ignore
            tableData: this.tableData,
            // @ts-ignore
            key: this.key,
            // @ts-ignore
            items: this.rows,
            // @ts-ignore
            selectRow: this.selectRow.bind(this),
            // @ts-ignore
            rowItem: this.rowItem,
            // @ts-ignore
            skeleton: this.skeleton,
            columnCount: s
          })
        ])
      ])
    ]);
  }
  /**
   * Refreshes the list.
   *
   * @returns {void}
   */
  refresh() {
    this.list.refresh();
  }
}
const rt = d((t) => new Se(
  {
    cache: t.cache ?? "list",
    tableData: t.data,
    scrollContainer: t.scrollContainer,
    loadMoreItems: t.loadMoreItems,
    offset: t.offset,
    limit: t.limit,
    class: t.class,
    key: t.key,
    rows: t.rows,
    rowItem: t.rowItem,
    headers: t.headers,
    customHeader: t.customHeader,
    border: t.border,
    emptyState: t.emptyState,
    skeleton: t.skeleton
  }
)), Ce = d(({ name: t, email: e }) => o({ class: "min-w-0 flex-auto" }, [
  p({ class: "text-base font-semibold leading-6 m-0" }, t),
  p({ class: "truncate text-sm leading-5 text-muted-foreground m-0" }, e)
])), Ie = () => o({ class: "flex items-center gap-x-1.5" }, [
  o({ class: "flex-none rounded-full bg-emerald-500/20 p-1" }, [
    o({ class: "h-1.5 w-1.5 rounded-full bg-emerald-500" })
  ]),
  p({ class: "text-xs leading-5 text-gray-500" }, "Online")
]), Le = (t) => p({ class: "text-xs leading-5 text-muted-foreground" }, [
  D("Last seen "),
  q({ datetime: t }, "3h ago")
]), Te = (t, e) => t === "online" ? Ie() : Le(e), Be = d(({ role: t, lastSeen: e, status: s }) => o({ class: "hidden shrink-0 sm:flex sm:flex-col sm:items-end" }, [
  p({ class: "text-sm leading-6 m-0" }, t),
  Te(s, e)
])), Me = (t) => t.split(" ").map((s) => s[0]).join(""), Re = d((t) => S({ class: "fadeIn flex justify-between gap-x-6 py-4 px-4 rounded-md hover:bg-muted/50" }, [
  o({ class: "flex min-w-0 gap-x-4" }, [
    oe({ src: t.image, alt: t.name, fallbackText: Me(t.name) }),
    Ce({ name: t.name, email: t.email })
  ]),
  Be({
    role: t.role,
    lastSeen: t.lastSeen,
    status: t.status
  })
])), ct = d((t) => new te({
  cache: "list",
  key: "name",
  items: t.users,
  role: "list",
  class: "divide-y divide-border",
  rowItem: Re
})), We = (t, e) => e.includes(t), Pe = (t, e, s) => t.exact ? s === e : We(e, s), Oe = ({ text: t, href: e, exact: s, hidden: a }) => new $({
  text: t,
  href: e,
  exact: s,
  dataSet: ["selected", ["state", !0, "active"]],
  class: `${a ? "hidden" : "inline-flex"} items-center justify-center whitespace-nowrap px-3 py-1.5 text-sm font-medium transition-all rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-ring focus-visible:ring-offset-background hover:bg-primary hover:text-primary-foreground disabled:opacity-50 disabled:pointer-events-none data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm`
});
class dt extends u {
  /**
   * This will declare the props for the compiler.
   *
   * @returns {void}
   */
  declareProps() {
    this.options = [], this.class = "";
  }
  /**
   * This will configure the links.
   */
  beforeSetup() {
    this.links = [];
  }
  /**
   * This will render the component.
   *
   * @returns {object}
   */
  render() {
    return C(
      { class: `flex items-center justify-center p-2 text-muted-foreground rounded-md ${this.class || ""}` },
      [
        w({
          class: "flex space-x-4",
          map: [this.options, (e) => this.addLink(e)],
          watch: {
            value: ["[[path]]", b.data],
            callBack: this.updateLinks.bind(this)
          }
        })
      ]
    );
  }
  /**
   * This will update the links.
   *
   * @returns {void}
   */
  afterSetup() {
    const e = b.data.path;
    this.updateLinks(e);
  }
  /**
   * This will update the links based on the current path.
   *
   * @param {string} path
   * @returns {void}
   */
  updateLinks(e) {
    let s = !1;
    this.deactivateAllLinks();
    for (const a of this.links) {
      if (!a.rendered)
        continue;
      Pe(a, a.getLinkPath(), e) ? (this.updateLink(a, !0), s = !0) : this.updateLink(a, !1);
    }
    !s && this.links[0] && this.updateLink(this.links[0], !0);
  }
  /**
   * This will deactivate all links.
   *
   * @returns {void}
   */
  deactivateAllLinks() {
    for (const e of this.links)
      this.updateLink(e, !1);
  }
  /**
   * This will update the link's active state.
   *
   * @param {object} link
   * @param {boolean} selected
   * @returns {void}
   */
  updateLink(e, s) {
    e.update(s);
  }
  /**
   * This will add a link to the navigation.
   *
   * @param {object} option
   * @returns {object}
   */
  addLink({ label: e, href: s, exact: a, hidden: i }) {
    const n = Oe({ text: e, href: s, exact: a, hidden: i });
    return this.links.push(n), n;
  }
  /**
   * This will clear the links.
   *
   * @returns {void}
   */
  beforeDestroy() {
    this.links = [];
  }
}
const ht = d((t) => {
  const e = t.margin || "m-4 ml-0";
  return t.allowHistory = t.allowHistory === !0, o({ class: `flex-none ${e}` }, [
    T({ variant: "back", class: "ghost", ...t })
  ]);
});
class j extends u {
  /**
   * This will declare the props for the compiler.
   *
   * @returns {void}
   */
  declareProps() {
    this.class = "";
  }
  /**
   * This will render the component.
   *
   * @returns {object}
   */
  render() {
    return o(
      {
        class: this.getClassName(),
        onSet: ["loading", {
          loading: !0
        }]
      },
      [
        this.addBody()
      ]
    );
  }
  /**
   * This will get the overlay className.
   *
   * @returns {string}
   */
  getClassName() {
    return "overlay fixed top-[0px] left-0 bottom-0 right-0 flex-col bg-background z-20 lg:z-10 flex flex-auto lg:left-[64px] lg:top-0 overflow-y-visible will-change-contents " + (this.class || "");
  }
  /**
   * This will setup and render the component.
   *
   * @param {object} container
   * @returns {void}
   */
  setContainer(e) {
    this.container = app.root;
  }
  /**
   * This will setup the overlay states.
   *
   * @returns {object}
   */
  setupStates() {
    return {
      loading: !1
    };
  }
  /**
   * This will set the loading state.= to true.
   *
   * @returns {void}
   */
  addLoading() {
    this.state.loading = !0;
  }
  /**
   * This will set the loading state to false.
   *
   * @returns {void}
   */
  removeLoading() {
    this.state.loading = !1;
  }
  /**
   * This will add the body of the overlay.
   *
   * @returns {object}
   */
  addBody() {
    return o({ class: "body fadeIn flex flex-auto flex-col" }, this.getContents());
  }
  /**
   * This will get the body contents.
   *
   * @returns {array|null}
   */
  getContents() {
    return this.children;
  }
}
N.addType("dockableOverlay", (t) => {
  if (!t)
    return;
  const e = t.component;
  e && e.rendered === !0 && e.state.docked === !1 && e.destroy();
});
class ut extends j {
  /**
   * This will stop presistence.
   *
   * @returns {void}
   */
  onCreated() {
    this.dockSize = this.maxSize || 1024;
  }
  /**
   * This will render the component.
   *
   * @returns {object}
   */
  render() {
    const e = this.container;
    return o(
      {
        onState: [
          ["loading", {
            loading: !0
          }],
          ["docked", (s, a) => {
            s ? (a.className = this.getDockedClassName(), e.appendChild(a), document.documentElement.style.overflowY = "auto") : (a.className = this.getClassName(), app.root.appendChild(a), document.documentElement.style.overflowY = "hidden");
          }]
        ]
      },
      [
        this.addBody()
      ]
    );
  }
  /**
   * This will get the docked className.
   *
   * @returns {string}
   */
  getDockedClassName() {
    return "flex flex-auto flex-col bg-background flex will-change-contents " + (this.class || "");
  }
  /**
   * This will setup and render the component.
   *
   * @param {object} container
   * @returns {void}
   */
  setup(e) {
    this.container = e, this.initialize();
  }
  /**
   * This will setup the overlay states.
   *
   * @returns {object}
   */
  setupStates() {
    return {
      loading: !1,
      docked: this.canDock()
    };
  }
  /**
   * This will check the dock size.
   *
   * @returns {void}
   */
  afterSetup() {
    N.add(
      this.container,
      "dockableOverlay",
      {
        component: this
      }
    ), this.onResize();
  }
  /**
   * This will setup the overlay events.
   *
   * @returns {Array<object>}
   */
  setupEvents() {
    return [
      ["resize", globalThis, () => this.onResize()]
    ];
  }
  /**
   * This will check if the overlay can dock.
   *
   * @returns {boolean}
   */
  canDock() {
    return globalThis.innerWidth >= this.dockSize;
  }
  /**
   * This will handle the overlay resize.
   *
   * @returns {void}
   */
  onResize() {
    this.state.docked = this.canDock();
  }
  /**
   * This will resume scrolling when the overlay is being removed.
   *
   * @returns {void}
   */
  beforeDestroy() {
    document.documentElement.style.overflowY = "auto";
  }
}
class ft extends j {
  /**
   * This will get the overlay type.
   *
   * @returns {string}
   */
  getClassName() {
    return "overlay relative inline top-[0px] left-0 bottom-0 right-0 flex-col bg-background z-20 lg:left-[64px] lg:top-0 will-change-contents " + (this.class || "");
  }
  /**
   * This will setup and render the component.
   *
   * @param {object} container
   * @returns {void}
   */
  setup(e) {
    this.container = e, this.initialize();
  }
}
const ze = d(({ index: t, click: e, state: s }, a) => S({
  class: "p-2 cursor-pointer hover:bg-muted/50",
  onState: [
    [s, "selectedIndex", {
      "bg-accent": t,
      "text-white": t
    }]
  ],
  click: () => e(t)
}, a)), $e = d(({ selectOption: t, state: e }) => w({
  class: "border rounded-md list-none m-0 p-0 max-h-[400px] overflow-y-auto",
  for: ["filteredOptions", (s, a) => ze({ index: a, click: t, state: e }, s.label)]
})), Ne = d((t) => o({ class: "relative flex items-center" }, [
  ie({
    cache: "input",
    class: t.class ?? "",
    placeholder: t.placeholder ?? "Search...",
    bind: t.bind ?? [t.state, "searchQuery"],
    keyup: (e, s) => {
      s.state && (s.state.open = !1), typeof t.filterOptions == "function" && t.filterOptions(), s.dropdown && s.dropdown.updatePosition(), t.keyup && t.keyup(e, s);
    },
    pointerup: (e, s) => {
      typeof s.toggleDropdown == "function" && s.toggleDropdown();
    },
    keydown: (e) => [
      typeof t.handleKeyDown == "function" && t.handleKeyDown(e)
    ]
  }),
  t.icon && o({ class: "absolute flex right-0 mr-2" }, [
    _(t.icon)
  ])
])), He = (t) => o({
  class: "relative flex fle-auto flex-col",
  onState: ["open", (e, s, a) => {
    if (e)
      return new le({
        cache: "dropdown",
        parent: a,
        button: a.input,
        size: "xl"
      }, [
        $e(t)
      ]);
  }]
}), mt = V(
  {
    /**
     * This will set up the data object.
     *
     * @returns {object} - The data object.
     */
    setData() {
      const t = this.options || [];
      return new L({
        options: t,
        filteredOptions: t
      });
    },
    /**
     * This will set up the state object.
     *
     * @returns {object} - The state object.
     */
    state() {
      return {
        searchQuery: "",
        selectedIndex: -1,
        open: !1
      };
    },
    /**
     * This will set the selected index by query.
     *
     * @returns {void}
     */
    setSelectedIndexByQuery() {
      const t = this.data.filteredOptions;
      let { searchQuery: e } = this.state;
      e = e.toLowerCase();
      const s = t.findIndex((a) => a.label.toLowerCase() === e);
      s >= 0 && (this.state.selectedIndex = s);
    },
    /**
     * This will filter the options.
     *
     * @returns {void}
     */
    filterOptions() {
      const t = this.state.searchQuery.toLowerCase();
      if (t === "" || t.length === 0) {
        this.data.filteredOptions = this.data.options;
        return;
      }
      const e = this.data.get("options");
      this.data.filteredOptions = e.filter(
        (s) => s.label.toLowerCase().includes(t)
      );
    },
    /**
     * This will get the selected value.
     *
     * @returns {object}
     */
    getValue() {
      const { selectedIndex: t } = this.state;
      return t < 0 ? null : this.data.get(`filteredOptions[${t}]`);
    },
    /**
     * This will select an option.
     *
     * @param {number} index - The index of the option.
     * @returns {void}
     */
    selectOption(t) {
      this.state.selectedIndex = t;
      const e = this.data.get(`filteredOptions[${t}]`);
      this.state.searchQuery = e.label, this.state.open = !1, typeof this.onSelect == "function" && this.onSelect(e);
    },
    /**
     * Toggles the dropdown open state.
     */
    toggleDropdown() {
      this.state.toggle("open"), this.state.open && this.setSelectedIndexByQuery();
    },
    /**
     * This will handle key down events.
     *
     * @param {object} event - The event object.
     * @returns {void}
     */
    handleKeyDown(t) {
      const e = this.data.filteredOptions, { selectedIndex: s } = this.state;
      t.key === "ArrowDown" ? (t.preventDefault(), this.state.selectedIndex = Math.min(s + 1, e.length - 1)) : t.key === "ArrowUp" ? (t.preventDefault(), this.state.selectedIndex = Math.max(s - 1, 0)) : t.key === "Enter" && s >= 0 && (t.preventDefault(), this.selectOption(s));
    },
    /**
     * This will render the component.
     *
     * @returns {object} - The rendered component.
     */
    render() {
      return o({ class: "relative w-full max-w-md" }, [
        Ne({
          // @ts-ignore
          state: this.state,
          // @ts-ignore
          icon: this.icon,
          // @ts-ignore
          placeholder: this.placeholder,
          // @ts-ignore
          filterOptions: this.filterOptions.bind(this),
          // @ts-ignore
          handleKeyDown: this.handleKeyDown.bind(this)
        }),
        He({
          // @ts-ignore
          state: this.state,
          // @ts-ignore
          setSelected: this.setSelectedIndexByQuery.bind(this),
          // @ts-ignore
          selectOption: this.selectOption.bind(this)
        })
      ]);
    }
  }
), je = (t) => S(
  {
    class: "inline-flex flex-auto items-center justify-center whitespace-nowrap rounded-sm text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm",
    dataSet: ["selected", ["state", t.value, "active"]]
  },
  [
    x({
      class: "flex flex-auto justify-center items-center px-3 py-1.5 rounded-md",
      onSet: ["selected", { selected: t.value }],
      click: (e) => t.callBack(t.value)
    }, t.label)
  ]
), Ae = (t, e) => (t.callBack = e, je(t)), Ue = (t) => C({ class: `tab items-center justify-center rounded-md bg-muted p-1 text-muted-foreground ${t.class}` }, [
  w({ class: "flex flex-auto flex-row", map: [t.options, (e) => Ae(e, t.callBack)] })
]);
class gt extends u {
  /**
   * This will declare the props for the compiler.
   *
   * @returns {void}
   */
  declareProps() {
    this.options = [], this.class = "", this.callBack = null;
  }
  /**
   * This will render the component.
   *
   * @returns {object}
   */
  render() {
    const e = this.select.bind(this);
    return o({ class: "" }, [
      Ue({
        class: this.class,
        options: this.options,
        callBack: e
      }),
      z({
        class: "tab-content",
        onState: ["selected", this.updateContent.bind(this)]
      })
    ]);
  }
  /**
   * This will get the first value.
   *
   * @returns {*}
   */
  getFirstValue() {
    return this.options[0]?.value;
  }
  /**
   * This will update the component.
   *
   * @returns {void}
   */
  update() {
    const e = this.state.get("selected");
    this.select(null), this.select(e);
  }
  /**
   * This will select a value.
   *
   * @param {*} value
   * @returns {void}
   */
  select(e) {
    this.state.selected = e;
  }
  /**
   * This will update the content.
   *
   * @param {*} value
   * @returns {object}
   */
  updateContent(e) {
    const s = this.options;
    if (!s || s.length < 1)
      return;
    const a = s[0];
    for (const i of s)
      if (i.value === e)
        return i.layout;
    return a.layout;
  }
  /**
   * This will setup the states.
   *
   * @returns {object}
   */
  setupStates() {
    const e = this.callBack, s = typeof e;
    return {
      selected: {
        state: this.getFirstValue(),
        callBack(a) {
          s === "function" && e(a);
        }
      }
    };
  }
}
const Ye = (t) => S(
  {
    class: "inline-flex flex-auto items-center justify-center whitespace-nowrap rounded-sm text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm",
    dataSet: ["selected", ["state", t.value, "active"]]
  },
  [
    x({
      class: "flex flex-auto justify-center items-center px-3 py-1.5 rounded-md disabled:opacity-50 disabled:cursor-not-allowed",
      onSet: ["selected", { selected: t.value }],
      click: (e) => t.callBack(t.value),
      disabled: t.disabled
    }, t.label)
  ]
), Fe = (t, e) => (t.callBack = e, Ye(t)), Ee = (t) => C({ class: `tab items-center justify-center rounded-md bg-muted p-1 text-muted-foreground ${t.class}` }, [
  w({ class: "flex flex-auto flex-row", map: [t.options, (e) => Fe(e, t.callBack)] })
]);
class pt extends u {
  /**
   * This will declare the props for the compiler.
   *
   * @returns {void}
   */
  declareProps() {
    this.options = [], this.class = "", this.onSelect = null;
  }
  /**
   * This will render the component.
   *
   * @returns {object}
   */
  render() {
    const e = this.select.bind(this);
    return Ee({
      class: this.class,
      options: this.options,
      callBack: e
    });
  }
  /**
   * This will select a value.
   *
   * @param {*} value
   * @returns {void}
   */
  select(e) {
    this.state.selected = e, typeof this.onSelect == "function" && this.onSelect(e, this.parent);
  }
  /**
   * This will setup the states.
   *
   * @returns {object}
   */
  setupStates() {
    return {
      selected: this.options[0]?.value || null
    };
  }
}
const Qe = (t, e) => new RegExp(`${t}($|/|\\.).*`).test(e), Xe = (t, e) => {
  const s = t.getLinkPath();
  return t.exact ? e === s : Qe(s, e);
}, qe = ({ text: t, href: e, exact: s }) => new $({
  text: t,
  href: e,
  exact: s,
  dataSet: ["selected", ["state", !0, "active"]],
  class: "inline-flex flex-auto items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm"
});
class Ke extends u {
  /**
   * This will declare the props for the compiler.
   *
   * @returns {void}
   */
  declareProps() {
    this.options = [], this.class = "", this.onSelect = null;
  }
  /**
   * This will configure the links.
   */
  beforeSetup() {
    this.links = [];
  }
  /**
   * This will render the component.
   *
   * @returns {object}
   */
  render() {
    return C({ class: `tab items-center justify-center rounded-md bg-muted p-1 text-muted-foreground ${this.class}` }, [
      w({
        class: "flex flex-auto flex-row",
        map: [this.options, (e) => this.addLink(e)],
        watch: {
          value: ["[[path]]", b.data],
          callBack: this.updateLinks.bind(this)
        }
      })
    ]);
  }
  /**
   * This will update the links.
   *
   * @returns {void}
   */
  afterSetup() {
    const e = b.data.path;
    this.updateLinks(e);
  }
  /**
   * This will update the links.
   *
   * @param {string} value
   * @returns {void}
   */
  updateLinks(e) {
    let s = !1, a = this.links[0];
    this.deactivateAllLinks();
    for (const i of this.links)
      if (i.rendered !== !1 && (s = Xe(i, e), s === !0)) {
        this.updateLink(i, !0);
        break;
      }
    s !== !0 && a && this.updateLink(a, !0);
  }
  /**
   * This will deactivate all links.
   *
   * @returns {void}
   */
  deactivateAllLinks() {
    for (const e of this.links)
      this.updateLink(e, !1);
  }
  /**
   * This will update the link.
   *
   * @param {object} link
   * @param {boolean} selected
   * @returns {void}
   */
  updateLink(e, s) {
    e.update(s);
  }
  /**
   * This will add a link.
   *
   * @param {object} option
   * @returns {object}
   */
  addLink({ label: e, href: s, exact: a }) {
    const i = qe({ text: e, href: s, exact: a });
    return this.links.push(i), i;
  }
  /**
   * This will remove all the links.
   *
   * @returns {void}
   */
  beforeDestroy() {
    this.links = [];
  }
}
class wt extends u {
  /**
   * This will declare the props for the compiler.
   *
   * @returns {void}
   */
  declareProps() {
    this.options = [], this.class = "";
  }
  /**
   * This will render the component.
   *
   * @returns {object}
   */
  render() {
    return o({ class: "tab-panel" }, [
      new Ke({
        class: this.class,
        options: this.options
      }),
      z({
        class: "tab-content",
        switch: this.addGroup()
      })
    ]);
  }
  /**
   * This will add the group.
   *
   * @returns {array}
   */
  addGroup() {
    let e;
    const s = [], a = this.options;
    for (let i = 0, n = a.length; i < n; i++)
      e = a[i], s.push(
        {
          uri: e.uri || e.href,
          component: e.component,
          title: e.title || null,
          persist: !0
        }
      );
    return s;
  }
}
class Ge extends u {
  /**
   * Runs before rendering, sets up defaults, a timer for drawing,
   * and basic canvas properties.
   *
   * @returns {void}
   */
  onCreated() {
    this.lineWidth = this.lineWidth || 3, this.lineColor = this.lineColor || "#000000", this.canvas = null, this.ctx = null, this.status = "stopped";
    const e = 1e3 / 60;
    this.timer = new se(e, this.draw.bind(this)), this.width = 0, this.height = 0, this.signed = !1, this.mouse = { x: 0, y: 0, status: "up" }, this.margin = this.margin || { x: 40, y: 60 }, this.targetSize = this.targetSize || { width: 740, height: 345 }, this.baseLineWidth = this.baseLineWidth || 2, this.baseStrokeColor = this.baseStrokeColor || "#000000";
  }
  /**
   * Renders a <canvas> element.
   *
   * @returns {object} Layout definition for the canvas.
   */
  render() {
    return K({
      style: "touch-action: none; -webkit-user-select: none; -webkit-touch-callout: none;"
    });
  }
  /**
   * Called before the component is destroyed. Stops the timer
   * to prevent memory leaks or ongoing animation.
   *
   * @returns {void}
   */
  beforeDestroy() {
    this.stopTimer();
  }
  /**
   * Called after component setup. Initializes canvas context,
   * schedules a resize, and draws the initial content.
   *
   * @returns {void}
   */
  afterSetup() {
    this.canvas = this.panel, this.ctx = this.canvas.getContext("2d"), globalThis.setTimeout(() => {
      this.resize(), this.draw();
    }, 1);
  }
  /**
   * Defines the DOM events to set up for this canvas component.
   *
   * @returns {Array} An array of [eventName, element, callback] definitions.
   */
  setupEvents() {
    const e = this.panel, s = this.pointerPosition.bind(this), a = this.pointerUp.bind(this), i = this.pointerDown.bind(this), n = this.resize.bind(this), l = { passive: !1 };
    return [
      ["pointermove", e, s, l],
      ["pointerup", e, a],
      ["pointerdown", e, i, l],
      ["pointerout", e, a],
      ["resize", globalThis, n]
    ];
  }
  /**
   * Calculates and saves the current pointer position in canvas coordinates.
   *
   * @param {Event} e The event object (mouse or touch).
   * @returns {void}
   */
  getEventPosition(e) {
    let s, a;
    const i = this.canvas, n = i.width / parseInt(i.style.width), l = i.getBoundingClientRect();
    if (e.touches && e.touches.length) {
      const f = e.touches[0];
      s = f.clientX, a = f.clientY;
    } else
      s = e.x || e.clientX, a = e.y || e.clientY;
    const c = parseInt((s - l.left) * n), r = parseInt((a - l.top) * n);
    this.mouse.x = c, this.mouse.y = r;
  }
  /**
   * Called when the pointer goes down on the canvas.
   * Begins a new path, sets the mouse status, and starts the timer.
   *
   * @param {Event} e The event object.
   * @returns {void}
   */
  pointerDown(e) {
    e.preventDefault(), e.stopPropagation(), this.getEventPosition(e);
    const { ctx: s, mouse: a } = this;
    s.beginPath(), s.moveTo(a.x, a.y), a.status = "down", this.startTimer();
  }
  /**
   * Called when the pointer goes up or leaves the canvas area.
   * Closes the path and stops the drawing timer.
   *
   * @param {Event} e The event object.
   * @returns {void}
   */
  pointerUp(e) {
    e.preventDefault(), e.stopPropagation(), this.ctx.closePath(), this.mouse.status = "up", this.stopTimer();
  }
  /**
   * Tracks pointer movement, updates position in real time.
   *
   * @param {Event} e The event object.
   * @returns {void}
   */
  pointerPosition(e) {
    this.getEventPosition(e), this.mouse.status === "down" && (e.preventDefault(), e.stopPropagation());
  }
  /**
   * Resizes the canvas, preserves existing drawing by converting
   * it to a data URL, then re-drawing.
   *
   * @returns {void}
   */
  resize() {
    const { canvas: e, ctx: s } = this, a = e.toDataURL();
    if (this.scale(), this.setupBackground(s), a !== "data:,") {
      const i = new globalThis.Image();
      M.on("load", i, function n() {
        s.drawImage(i, 0, 0), M.off("load", i, n);
      }), i.src = a;
    }
    this.draw();
  }
  /**
   * Returns a JPEG data URL of the current canvas content.
   *
   * @returns {string} The signature image as a data URL.
   */
  getImage() {
    return this.canvas.toDataURL("image/jpeg", 0.7);
  }
  /**
   * (Deprecated approach) Resize the canvas to the container size
   * without scaling logic.
   *
   * @returns {void}
   */
  noScaleResize() {
    const e = R.getSize(container);
    this.width = canvas.width = e.width, this.height = canvas.height = e.height;
  }
  /**
   * Scales the canvas to fit within its container, preserving aspect ratio
   * relative to this.targetSize.
   *
   * @returns {void}
   */
  scale() {
    const e = this.canvas, s = this.container, a = R.getSize(s), i = this.targetSize, n = i.width, l = i.height;
    let c = n + "px", r = l + "px";
    if (this.width = e.width = n, this.height = e.height = l, a.width !== 0 && a.height !== 0) {
      const f = a.width, m = a.height, h = f / n, g = m / l, y = Math.min(h, g);
      c = n * y + "px", r = l * y + "px";
    }
    e.style.width = c, e.style.height = r;
  }
  /**
   * Main drawing loop. If the mouse is down, adds a line
   * from the last point to the current pointer position.
   *
   * @returns {void}
   */
  draw() {
    this.mouse.status === "down" && this.addLine(this.ctx, this.mouse.x, this.mouse.y, this.lineColor);
  }
  /**
   * Draws the baseline at the bottom of the canvas.
   *
   * @param {CanvasRenderingContext2D} ctx The canvas 2D context.
   * @returns {void}
   */
  drawBottomLine(e) {
    const s = this.canvas;
    e.globalAlpha = 1, e.shadowBlur = 0;
    const a = this.margin.x, i = this.height - this.margin.y;
    e.beginPath(), e.moveTo(a, i), e.lineTo(s.width - this.margin.x, i), e.lineWidth = this.baseLineWidth, e.strokeStyle = this.baseStrokeColor, e.stroke(), e.closePath();
  }
  /**
   * Adds a line to the current path, updating the 'signed' status.
   *
   * @param {CanvasRenderingContext2D} ctx The canvas context.
   * @param {number} px The x-coordinate.
   * @param {number} py The y-coordinate.
   * @param {string} color The stroke color.
   * @returns {void}
   */
  addLine(e, s, a, i) {
    this.signed || (this.signed = !0);
    const n = Math.round(s), l = Math.round(a);
    e.lineWidth = this.lineWidth, e.strokeStyle = i, e.lineTo(n, l), e.stroke();
  }
  /**
   * Clears the canvas, sets signed to false, and re-initializes
   * the background for a fresh signature.
   *
   * @returns {void}
   */
  reset() {
    this.signed = !1;
    const { ctx: e } = this;
    e.clearRect(0, 0, this.width, this.height), this.setupBackground(e);
  }
  /**
   * Fills the canvas background with white and draws the baseline.
   *
   * @param {CanvasRenderingContext2D} ctx The canvas context.
   * @returns {void}
   */
  setupBackground(e) {
    e.fillStyle = "transparent", e.fillRect(0, 0, this.width, this.height), this.drawBottomLine(e);
  }
  /**
   * Starts the drawing timer so new lines can be added as pointer moves.
   *
   * @returns {void}
   */
  startTimer() {
    this.stopTimer(), this.draw(), this.timer.start(), this.status = "started";
  }
  /**
   * Stops the drawing timer.
   *
   * @returns {void}
   */
  stopTimer() {
    this.timer.stop(), this.status = "stopped";
  }
}
class yt extends u {
  /**
   * Sets up default properties for the signature panel.
   *
   * @returns {void}
   */
  declareProps() {
    this.data = null, this.lineColor = null, this.lineWidth = null, this.baseLineWidth = null, this.baseStrokeColor = null, this.margin = null, this.targetSize = null, this.callBackData = null, this.pointerUp = null, this.path = null, this.canvasLayer = null;
  }
  /**
   * Renders the main layout for the signature panel,
   * including a hidden input and a reset button.
   *
   * @returns {object} The layout object for the component.
   */
  render() {
    return o({ class: "signature-panel relative flex flex-auto overflow-hidden select-none" }, [
      ne({
        cache: "hiddenInput",
        required: !0,
        bind: this.path + ".data"
      }),
      o({ class: "absolute top-2 right-2" }, [
        T({
          variant: "icon",
          icon: k.circleX,
          click: this.reset.bind(this)
        })
      ]),
      new Ge({
        cache: "canvasLayer",
        margin: this.margin,
        targetSize: this.targetSize,
        lineColor: this.lineColor,
        lineWidth: this.lineWidth,
        baseLineWidth: this.baseLineWidth,
        baseStrokeColor: this.baseStrokeColor,
        pointerUpCallBack: this.pointerUp,
        callBackData: this.callBackData
      })
    ]);
  }
  /**
   * Called after component setup. Resizes the signature canvas once
   * everything is ready.
   *
   * @returns {void}
   */
  afterSetup() {
    this.canvasLayer.resize();
  }
  /**
   * Gets the signature image from the canvas layer, as a data URL.
   *
   * @returns {string} The signature image data URL.
   */
  getImage() {
    return this.canvasLayer.getImage();
  }
  /**
   * Checks if the user has drawn anything on the signature canvas.
   *
   * @returns {boolean} True if the canvas has been signed, otherwise false.
   */
  isSigned() {
    return this.canvasLayer ? this.canvasLayer.signed : !1;
  }
  /**
   * Resets the signature canvas to a blank state.
   *
   * @param {Event} [e] The event object (if called by a click event).
   * @returns {void}
   */
  reset(e) {
    if (this.canvasLayer)
      return this.canvasLayer.reset();
  }
}
export {
  ht as B,
  ye as C,
  ke as D,
  be as H,
  ft as I,
  dt as N,
  j as O,
  at as P,
  rt as S,
  B as T,
  Re as U,
  ot as W,
  he as a,
  W as b,
  ce as c,
  it as d,
  nt as e,
  fe as f,
  de as g,
  ge as h,
  pe as i,
  H as j,
  lt as k,
  ct as l,
  ut as m,
  mt as n,
  Ne as o,
  gt as p,
  pt as q,
  Ke as r,
  wt as s,
  yt as t
};