rei-kit 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as registerErrorMapper, r as toAppError, t as AppError } from "./app-error-DF9cijE0.js";
2
- import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onMounted, onScopeDispose, onUnmounted, openBlock, readonly, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useId, useModel, vModelDynamic, vModelRadio, watch, watchEffect, withCtx, withDirectives } from "vue";
2
+ import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createStaticVNode, createTextVNode, createVNode, defineComponent, getCurrentInstance, h, inject, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onMounted, onScopeDispose, onUnmounted, openBlock, reactive, readonly, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useId, useModel, vModelDynamic, vModelRadio, watch, watchEffect, withCtx, withDirectives } from "vue";
3
3
  import { ArrowDown, ArrowRight, ArrowUp, ChevronRight, X } from "lucide-vue-next";
4
4
  import { createI18n } from "vue-i18n";
5
5
  //#region src/utils/date.ts
@@ -651,12 +651,12 @@ function useVisualViewport() {
651
651
  }
652
652
  //#endregion
653
653
  //#region src/components/BaseButton.vue?vue&type=script&setup=true&lang.ts
654
- var _hoisted_1$12 = [
654
+ var _hoisted_1$13 = [
655
655
  "type",
656
656
  "disabled",
657
657
  "aria-busy"
658
658
  ];
659
- var _hoisted_2$11 = {
659
+ var _hoisted_2$12 = {
660
660
  key: 0,
661
661
  class: "size-4 animate-spin rounded-full border-2 border-current border-t-transparent",
662
662
  "aria-hidden": "true"
@@ -694,15 +694,15 @@ var BaseButton_default = /* @__PURE__ */ defineComponent({
694
694
  disabled: __props.disabled || __props.loading,
695
695
  "aria-busy": __props.loading,
696
696
  class: normalizeClass(["rounded-card focus-visible:outline-primary inline-flex items-center justify-center gap-2 font-medium transition-transform duration-100 select-none focus-visible:outline-2 focus-visible:outline-offset-2 active:scale-95 disabled:pointer-events-none disabled:opacity-50", [VARIANT_CLASS[__props.variant], SIZE_CLASS[__props.size]]])
697
- }, [__props.loading ? (openBlock(), createElementBlock("span", _hoisted_2$11)) : createCommentVNode("", true), renderSlot(_ctx.$slots, "default")], 10, _hoisted_1$12);
697
+ }, [__props.loading ? (openBlock(), createElementBlock("span", _hoisted_2$12)) : createCommentVNode("", true), renderSlot(_ctx.$slots, "default")], 10, _hoisted_1$13);
698
698
  };
699
699
  }
700
700
  });
701
701
  //#endregion
702
702
  //#region src/components/BaseInput.vue?vue&type=script&setup=true&lang.ts
703
- var _hoisted_1$11 = { class: "flex flex-col gap-1.5" };
704
- var _hoisted_2$10 = ["for"];
705
- var _hoisted_3$6 = [
703
+ var _hoisted_1$12 = { class: "flex flex-col gap-1.5" };
704
+ var _hoisted_2$11 = ["for"];
705
+ var _hoisted_3$7 = [
706
706
  "id",
707
707
  "type",
708
708
  "aria-invalid",
@@ -737,18 +737,18 @@ var BaseInput_default = /* @__PURE__ */ defineComponent({
737
737
  if (__props.hint) return hintId;
738
738
  });
739
739
  return (_ctx, _cache) => {
740
- return openBlock(), createElementBlock("div", _hoisted_1$11, [
740
+ return openBlock(), createElementBlock("div", _hoisted_1$12, [
741
741
  createElementVNode("label", {
742
742
  for: unref(id),
743
743
  class: normalizeClass(["text-ink text-sm font-medium", __props.labelHidden ? "sr-only" : ""])
744
- }, toDisplayString(__props.label), 11, _hoisted_2$10),
744
+ }, toDisplayString(__props.label), 11, _hoisted_2$11),
745
745
  withDirectives(createElementVNode("input", mergeProps({
746
746
  id: unref(id),
747
747
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
748
748
  type: __props.type,
749
749
  "aria-invalid": Boolean(__props.error),
750
750
  "aria-describedby": describedBy.value
751
- }, _ctx.$attrs, { class: ["border-hair bg-surface text-ink rounded-card focus-visible:outline-primary h-11 border px-3 focus-visible:outline-2 focus-visible:outline-offset-1", __props.error ? "border-negative" : ""] }), null, 16, _hoisted_3$6), [[vModelDynamic, model.value]]),
751
+ }, _ctx.$attrs, { class: ["border-hair bg-surface text-ink rounded-card focus-visible:outline-primary h-11 border px-3 focus-visible:outline-2 focus-visible:outline-offset-1", __props.error ? "border-negative" : ""] }), null, 16, _hoisted_3$7), [[vModelDynamic, model.value]]),
752
752
  __props.error ? (openBlock(), createElementBlock("p", {
753
753
  key: 0,
754
754
  id: errorId,
@@ -764,10 +764,10 @@ var BaseInput_default = /* @__PURE__ */ defineComponent({
764
764
  });
765
765
  //#endregion
766
766
  //#region src/components/BaseSheet.vue?vue&type=script&setup=true&lang.ts
767
- var _hoisted_1$10 = { class: "shell-frame md:rounded-shell relative flex max-h-full flex-col justify-end overflow-hidden" };
768
- var _hoisted_2$9 = ["aria-label"];
769
- var _hoisted_3$5 = { class: "flex shrink-0 items-start gap-3 px-6 pt-4 pb-5" };
770
- var _hoisted_4$4 = { class: "min-w-0 flex-1" };
767
+ var _hoisted_1$11 = { class: "shell-frame md:rounded-shell relative flex max-h-full flex-col justify-end overflow-hidden" };
768
+ var _hoisted_2$10 = ["aria-label"];
769
+ var _hoisted_3$6 = { class: "flex shrink-0 items-start gap-3 px-6 pt-4 pb-5" };
770
+ var _hoisted_4$5 = { class: "min-w-0 flex-1" };
771
771
  var _hoisted_5$3 = { class: "text-ink text-xl leading-tight font-semibold" };
772
772
  var _hoisted_6$1 = {
773
773
  key: 0,
@@ -845,7 +845,7 @@ var BaseSheet_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
845
845
  key: 0,
846
846
  class: "fixed inset-x-0 top-0 bottom-0 z-50 flex items-center justify-center",
847
847
  style: normalizeStyle(viewportStyle.value)
848
- }, [createElementVNode("div", _hoisted_1$10, [createElementVNode("div", {
848
+ }, [createElementVNode("div", _hoisted_1$11, [createElementVNode("div", {
849
849
  class: "bg-ink/45 absolute inset-0 backdrop-blur-[2px]",
850
850
  onClick: close
851
851
  }), createElementVNode("section", {
@@ -861,14 +861,14 @@ var BaseSheet_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
861
861
  class: "flex shrink-0 justify-center pt-3",
862
862
  "aria-hidden": "true"
863
863
  }, [createElementVNode("span", { class: "bg-hair h-1.5 w-10 rounded-full" })], -1)),
864
- createElementVNode("header", _hoisted_3$5, [createElementVNode("div", _hoisted_4$4, [createElementVNode("h2", _hoisted_5$3, toDisplayString(__props.title), 1), __props.subtitle ? (openBlock(), createElementBlock("p", _hoisted_6$1, toDisplayString(__props.subtitle), 1)) : createCommentVNode("", true)]), createElementVNode("button", {
864
+ createElementVNode("header", _hoisted_3$6, [createElementVNode("div", _hoisted_4$5, [createElementVNode("h2", _hoisted_5$3, toDisplayString(__props.title), 1), __props.subtitle ? (openBlock(), createElementBlock("p", _hoisted_6$1, toDisplayString(__props.subtitle), 1)) : createCommentVNode("", true)]), createElementVNode("button", {
865
865
  type: "button",
866
866
  class: "text-ink-soft hover:bg-muted hover:text-ink -mt-1 flex size-10 shrink-0 items-center justify-center rounded-full transition-colors active:scale-90",
867
867
  "aria-label": __props.closeLabel,
868
868
  onClick: close
869
869
  }, [createVNode(unref(X), { class: "size-5" })], 8, _hoisted_7$1)]),
870
870
  createElementVNode("div", _hoisted_8, [renderSlot(_ctx.$slots, "default", {}, void 0, true)])
871
- ], 8, _hoisted_2$9)])], 4)) : createCommentVNode("", true)]),
871
+ ], 8, _hoisted_2$10)])], 4)) : createCommentVNode("", true)]),
872
872
  _: 3
873
873
  })]);
874
874
  };
@@ -886,13 +886,13 @@ var _plugin_vue_export_helper_default = (sfc, props) => {
886
886
  var BaseSheet_default = /*#__PURE__*/ _plugin_vue_export_helper_default(BaseSheet_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-3f2e9ce4"]]);
887
887
  //#endregion
888
888
  //#region src/components/EmptyState.vue?vue&type=script&setup=true&lang.ts
889
- var _hoisted_1$9 = { class: "flex flex-col items-center gap-3 px-6 py-10 text-center" };
890
- var _hoisted_2$8 = {
889
+ var _hoisted_1$10 = { class: "flex flex-col items-center gap-3 px-6 py-10 text-center" };
890
+ var _hoisted_2$9 = {
891
891
  key: 0,
892
892
  class: "bg-muted text-primary rounded-card flex size-12 items-center"
893
893
  };
894
- var _hoisted_3$4 = { class: "text-ink text-base font-semibold" };
895
- var _hoisted_4$3 = {
894
+ var _hoisted_3$5 = { class: "text-ink text-base font-semibold" };
895
+ var _hoisted_4$4 = {
896
896
  key: 1,
897
897
  class: "text-ink-soft max-w-[36ch] text-sm"
898
898
  };
@@ -910,10 +910,10 @@ var EmptyState_default = /* @__PURE__ */ defineComponent({
910
910
  },
911
911
  setup(__props) {
912
912
  return (_ctx, _cache) => {
913
- return openBlock(), createElementBlock("div", _hoisted_1$9, [
914
- _ctx.$slots.icon ? (openBlock(), createElementBlock("div", _hoisted_2$8, [renderSlot(_ctx.$slots, "icon")])) : createCommentVNode("", true),
915
- createElementVNode("h3", _hoisted_3$4, toDisplayString(__props.title), 1),
916
- __props.description ? (openBlock(), createElementBlock("p", _hoisted_4$3, toDisplayString(__props.description), 1)) : createCommentVNode("", true),
913
+ return openBlock(), createElementBlock("div", _hoisted_1$10, [
914
+ _ctx.$slots.icon ? (openBlock(), createElementBlock("div", _hoisted_2$9, [renderSlot(_ctx.$slots, "icon")])) : createCommentVNode("", true),
915
+ createElementVNode("h3", _hoisted_3$5, toDisplayString(__props.title), 1),
916
+ __props.description ? (openBlock(), createElementBlock("p", _hoisted_4$4, toDisplayString(__props.description), 1)) : createCommentVNode("", true),
917
917
  _ctx.$slots.action ? (openBlock(), createElementBlock("div", _hoisted_5$2, [renderSlot(_ctx.$slots, "action")])) : createCommentVNode("", true)
918
918
  ]);
919
919
  };
@@ -921,10 +921,10 @@ var EmptyState_default = /* @__PURE__ */ defineComponent({
921
921
  });
922
922
  //#endregion
923
923
  //#region src/components/PageHeader.vue?vue&type=script&setup=true&lang.ts
924
- var _hoisted_1$8 = { class: "grid h-12 shrink-0 grid-cols-[2.5rem_1fr_2.5rem] items-center" };
925
- var _hoisted_2$7 = { class: "justify-self-start" };
926
- var _hoisted_3$3 = { class: "text-ink flex min-w-0 justify-center text-base font-semibold tabular-nums" };
927
- var _hoisted_4$2 = { class: "truncate" };
924
+ var _hoisted_1$9 = { class: "grid h-12 shrink-0 grid-cols-[2.5rem_1fr_2.5rem] items-center" };
925
+ var _hoisted_2$8 = { class: "justify-self-start" };
926
+ var _hoisted_3$4 = { class: "text-ink flex min-w-0 justify-center text-base font-semibold tabular-nums" };
927
+ var _hoisted_4$3 = { class: "truncate" };
928
928
  var _hoisted_5$1 = { class: "justify-self-end" };
929
929
  //#endregion
930
930
  //#region src/components/PageHeader.vue
@@ -933,9 +933,9 @@ var PageHeader_default = /* @__PURE__ */ defineComponent({
933
933
  props: { title: {} },
934
934
  setup(__props) {
935
935
  return (_ctx, _cache) => {
936
- return openBlock(), createElementBlock("header", _hoisted_1$8, [
937
- createElementVNode("div", _hoisted_2$7, [renderSlot(_ctx.$slots, "left")]),
938
- createElementVNode("h1", _hoisted_3$3, [renderSlot(_ctx.$slots, "title", {}, () => [createElementVNode("span", _hoisted_4$2, toDisplayString(__props.title), 1)])]),
936
+ return openBlock(), createElementBlock("header", _hoisted_1$9, [
937
+ createElementVNode("div", _hoisted_2$8, [renderSlot(_ctx.$slots, "left")]),
938
+ createElementVNode("h1", _hoisted_3$4, [renderSlot(_ctx.$slots, "title", {}, () => [createElementVNode("span", _hoisted_4$3, toDisplayString(__props.title), 1)])]),
939
939
  createElementVNode("div", _hoisted_5$1, [renderSlot(_ctx.$slots, "right")])
940
940
  ]);
941
941
  };
@@ -943,8 +943,8 @@ var PageHeader_default = /* @__PURE__ */ defineComponent({
943
943
  });
944
944
  //#endregion
945
945
  //#region src/components/ToneDot.vue?vue&type=script&setup=true&lang.ts
946
- var _hoisted_1$7 = { class: "inline-flex items-center gap-1.5" };
947
- var _hoisted_2$6 = {
946
+ var _hoisted_1$8 = { class: "inline-flex items-center gap-1.5" };
947
+ var _hoisted_2$7 = {
948
948
  key: 0,
949
949
  class: "text-ink-soft text-xs font-medium"
950
950
  };
@@ -965,13 +965,13 @@ var ToneDot_default = /* @__PURE__ */ defineComponent({
965
965
  * priorities — without this component knowing about any of them.
966
966
  */
967
967
  return (_ctx, _cache) => {
968
- return openBlock(), createElementBlock("span", _hoisted_1$7, [createElementVNode("span", { class: normalizeClass(["size-2 rounded-full", __props.fill]) }, null, 2), __props.label ? (openBlock(), createElementBlock("span", _hoisted_2$6, toDisplayString(__props.label), 1)) : createCommentVNode("", true)]);
968
+ return openBlock(), createElementBlock("span", _hoisted_1$8, [createElementVNode("span", { class: normalizeClass(["size-2 rounded-full", __props.fill]) }, null, 2), __props.label ? (openBlock(), createElementBlock("span", _hoisted_2$7, toDisplayString(__props.label), 1)) : createCommentVNode("", true)]);
969
969
  };
970
970
  }
971
971
  });
972
972
  //#endregion
973
973
  //#region src/components/SectionHeading.vue?vue&type=script&setup=true&lang.ts
974
- var _hoisted_1$6 = {
974
+ var _hoisted_1$7 = {
975
975
  key: 0,
976
976
  class: "text-ink-soft text-xs tabular-nums"
977
977
  };
@@ -989,15 +989,15 @@ var SectionHeading_default = /* @__PURE__ */ defineComponent({
989
989
  return openBlock(), createElementBlock("h2", { class: normalizeClass(["flex items-center gap-2 self-start rounded-full border px-3 py-1", __props.tone.card]) }, [
990
990
  createVNode(ToneDot_default, { fill: __props.tone.fill }, null, 8, ["fill"]),
991
991
  createElementVNode("span", { class: normalizeClass(["text-xs font-semibold tracking-wide uppercase", __props.tone.text]) }, toDisplayString(__props.label), 3),
992
- __props.count > 0 ? (openBlock(), createElementBlock("span", _hoisted_1$6, toDisplayString(__props.count), 1)) : createCommentVNode("", true)
992
+ __props.count > 0 ? (openBlock(), createElementBlock("span", _hoisted_1$7, toDisplayString(__props.count), 1)) : createCommentVNode("", true)
993
993
  ], 2);
994
994
  };
995
995
  }
996
996
  });
997
997
  //#endregion
998
998
  //#region src/components/SegmentedControl.vue?vue&type=script&setup=true&lang.ts
999
- var _hoisted_1$5 = { class: "bg-muted rounded-card flex w-full gap-1 p-1" };
1000
- var _hoisted_2$5 = ["value", "name"];
999
+ var _hoisted_1$6 = { class: "bg-muted rounded-card flex w-full gap-1 p-1" };
1000
+ var _hoisted_2$6 = ["value", "name"];
1001
1001
  //#endregion
1002
1002
  //#region src/components/SegmentedControl.vue
1003
1003
  var SegmentedControl_default = /* @__PURE__ */ defineComponent({
@@ -1011,7 +1011,7 @@ var SegmentedControl_default = /* @__PURE__ */ defineComponent({
1011
1011
  const model = useModel(__props, "modelValue");
1012
1012
  const name = useId();
1013
1013
  return (_ctx, _cache) => {
1014
- return openBlock(), createElementBlock("div", _hoisted_1$5, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.options, (option) => {
1014
+ return openBlock(), createElementBlock("div", _hoisted_1$6, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.options, (option) => {
1015
1015
  return openBlock(), createElementBlock("label", {
1016
1016
  key: String(option.value),
1017
1017
  class: "flex-1 cursor-pointer"
@@ -1021,16 +1021,16 @@ var SegmentedControl_default = /* @__PURE__ */ defineComponent({
1021
1021
  value: option.value,
1022
1022
  name: unref(name),
1023
1023
  class: "sr-only"
1024
- }, null, 8, _hoisted_2$5), [[vModelRadio, model.value]]), createElementVNode("span", { class: normalizeClass(["flex h-10 items-center justify-center rounded-xl px-2 text-sm font-medium transition-colors select-none", model.value === option.value ? "bg-surface text-ink shadow-sm" : "text-ink-soft"]) }, toDisplayString(option.label), 3)]);
1024
+ }, null, 8, _hoisted_2$6), [[vModelRadio, model.value]]), createElementVNode("span", { class: normalizeClass(["flex h-10 items-center justify-center rounded-xl px-2 text-sm font-medium transition-colors select-none", model.value === option.value ? "bg-surface text-ink shadow-sm" : "text-ink-soft"]) }, toDisplayString(option.label), 3)]);
1025
1025
  }), 128))]);
1026
1026
  };
1027
1027
  }
1028
1028
  });
1029
1029
  //#endregion
1030
1030
  //#region src/components/SettingsGroup.vue?vue&type=script&setup=true&lang.ts
1031
- var _hoisted_1$4 = { class: "flex flex-col gap-2" };
1032
- var _hoisted_2$4 = { class: "text-ink-soft px-1 text-xs font-semibold tracking-wide uppercase" };
1033
- var _hoisted_3$2 = { class: "border-hair bg-surface rounded-card divide-hair divide-y overflow-hidden border" };
1031
+ var _hoisted_1$5 = { class: "flex flex-col gap-2" };
1032
+ var _hoisted_2$5 = { class: "text-ink-soft px-1 text-xs font-semibold tracking-wide uppercase" };
1033
+ var _hoisted_3$3 = { class: "border-hair bg-surface rounded-card divide-hair divide-y overflow-hidden border" };
1034
1034
  //#endregion
1035
1035
  //#region src/components/SettingsGroup.vue
1036
1036
  var SettingsGroup_default = /* @__PURE__ */ defineComponent({
@@ -1038,20 +1038,20 @@ var SettingsGroup_default = /* @__PURE__ */ defineComponent({
1038
1038
  props: { title: {} },
1039
1039
  setup(__props) {
1040
1040
  return (_ctx, _cache) => {
1041
- return openBlock(), createElementBlock("section", _hoisted_1$4, [createElementVNode("h2", _hoisted_2$4, toDisplayString(__props.title), 1), createElementVNode("div", _hoisted_3$2, [renderSlot(_ctx.$slots, "default")])]);
1041
+ return openBlock(), createElementBlock("section", _hoisted_1$5, [createElementVNode("h2", _hoisted_2$5, toDisplayString(__props.title), 1), createElementVNode("div", _hoisted_3$3, [renderSlot(_ctx.$slots, "default")])]);
1042
1042
  };
1043
1043
  }
1044
1044
  });
1045
1045
  //#endregion
1046
1046
  //#region src/components/SettingsRow.vue?vue&type=script&setup=true&lang.ts
1047
- var _hoisted_1$3 = { class: "flex items-center gap-3" };
1048
- var _hoisted_2$3 = {
1047
+ var _hoisted_1$4 = { class: "flex items-center gap-3" };
1048
+ var _hoisted_2$4 = {
1049
1049
  key: 0,
1050
1050
  class: "bg-muted text-ink-soft flex size-9 shrink-0 items-center justify-center rounded-xl",
1051
1051
  "aria-hidden": "true"
1052
1052
  };
1053
- var _hoisted_3$1 = { class: "min-w-0 flex-1" };
1054
- var _hoisted_4$1 = { class: "text-ink text-sm font-medium" };
1053
+ var _hoisted_3$2 = { class: "min-w-0 flex-1" };
1054
+ var _hoisted_4$2 = { class: "text-ink text-sm font-medium" };
1055
1055
  var _hoisted_5 = {
1056
1056
  key: 0,
1057
1057
  class: "text-ink-soft mt-0.5 text-xs leading-snug"
@@ -1087,9 +1087,9 @@ var SettingsRow_default = /* @__PURE__ */ defineComponent({
1087
1087
  class: normalizeClass(["flex w-full items-center gap-3 px-4 py-3 text-left", [__props.interactive ? "hover:bg-muted/60 transition-colors active:scale-[0.99]" : "", __props.stacked ? "flex-col items-stretch gap-3" : ""]]),
1088
1088
  onClick: _cache[0] || (_cache[0] = ($event) => __props.interactive && emit("click"))
1089
1089
  }, {
1090
- default: withCtx(() => [createElementVNode("div", _hoisted_1$3, [
1091
- __props.icon ? (openBlock(), createElementBlock("span", _hoisted_2$3, [(openBlock(), createBlock(resolveDynamicComponent(__props.icon), { class: "size-[18px]" }))])) : createCommentVNode("", true),
1092
- createElementVNode("div", _hoisted_3$1, [createElementVNode("p", _hoisted_4$1, toDisplayString(__props.label), 1), __props.description ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString(__props.description), 1)) : createCommentVNode("", true)]),
1090
+ default: withCtx(() => [createElementVNode("div", _hoisted_1$4, [
1091
+ __props.icon ? (openBlock(), createElementBlock("span", _hoisted_2$4, [(openBlock(), createBlock(resolveDynamicComponent(__props.icon), { class: "size-[18px]" }))])) : createCommentVNode("", true),
1092
+ createElementVNode("div", _hoisted_3$2, [createElementVNode("p", _hoisted_4$2, toDisplayString(__props.label), 1), __props.description ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString(__props.description), 1)) : createCommentVNode("", true)]),
1093
1093
  !__props.stacked ? (openBlock(), createElementBlock("div", _hoisted_6, [renderSlot(_ctx.$slots, "default")])) : createCommentVNode("", true),
1094
1094
  __props.interactive ? (openBlock(), createBlock(unref(ChevronRight), {
1095
1095
  key: 2,
@@ -1104,11 +1104,11 @@ var SettingsRow_default = /* @__PURE__ */ defineComponent({
1104
1104
  });
1105
1105
  //#endregion
1106
1106
  //#region src/components/SkeletonList.vue?vue&type=script&setup=true&lang.ts
1107
- var _hoisted_1$2 = {
1107
+ var _hoisted_1$3 = {
1108
1108
  role: "status",
1109
1109
  class: "flex flex-col gap-1"
1110
1110
  };
1111
- var _hoisted_2$2 = { class: "sr-only" };
1111
+ var _hoisted_2$3 = { class: "sr-only" };
1112
1112
  //#endregion
1113
1113
  //#region src/components/SkeletonList.vue
1114
1114
  var SkeletonList_default = /* @__PURE__ */ defineComponent({
@@ -1120,7 +1120,7 @@ var SkeletonList_default = /* @__PURE__ */ defineComponent({
1120
1120
  },
1121
1121
  setup(__props) {
1122
1122
  return (_ctx, _cache) => {
1123
- return openBlock(), createElementBlock("div", _hoisted_1$2, [createElementVNode("span", _hoisted_2$2, toDisplayString(__props.label), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.rows, (row) => {
1123
+ return openBlock(), createElementBlock("div", _hoisted_1$3, [createElementVNode("span", _hoisted_2$3, toDisplayString(__props.label), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.rows, (row) => {
1124
1124
  return openBlock(), createElementBlock("div", {
1125
1125
  key: row,
1126
1126
  class: normalizeClass(["bg-muted rounded-card animate-pulse", __props.rowHeight]),
@@ -1132,10 +1132,10 @@ var SkeletonList_default = /* @__PURE__ */ defineComponent({
1132
1132
  });
1133
1133
  //#endregion
1134
1134
  //#region src/components/StatCard.vue?vue&type=script&setup=true&lang.ts
1135
- var _hoisted_1$1 = { class: "border-hair rounded-card flex flex-1 flex-col gap-0.5 border p-3" };
1136
- var _hoisted_2$1 = { class: "flex items-baseline gap-1" };
1137
- var _hoisted_3 = { class: "text-ink text-xl font-semibold tabular-nums" };
1138
- var _hoisted_4 = { class: "text-ink-soft text-xs" };
1135
+ var _hoisted_1$2 = { class: "border-hair rounded-card flex flex-1 flex-col gap-0.5 border p-3" };
1136
+ var _hoisted_2$2 = { class: "flex items-baseline gap-1" };
1137
+ var _hoisted_3$1 = { class: "text-ink text-xl font-semibold tabular-nums" };
1138
+ var _hoisted_4$1 = { class: "text-ink-soft text-xs" };
1139
1139
  //#endregion
1140
1140
  //#region src/components/StatCard.vue
1141
1141
  var StatCard_default = /* @__PURE__ */ defineComponent({
@@ -1152,17 +1152,17 @@ var StatCard_default = /* @__PURE__ */ defineComponent({
1152
1152
  flat: ArrowRight
1153
1153
  };
1154
1154
  return (_ctx, _cache) => {
1155
- return openBlock(), createElementBlock("div", _hoisted_1$1, [createElementVNode("div", _hoisted_2$1, [createElementVNode("span", _hoisted_3, toDisplayString(__props.value), 1), __props.trend ? (openBlock(), createBlock(resolveDynamicComponent(TREND_ICON[__props.trend]), {
1155
+ return openBlock(), createElementBlock("div", _hoisted_1$2, [createElementVNode("div", _hoisted_2$2, [createElementVNode("span", _hoisted_3$1, toDisplayString(__props.value), 1), __props.trend ? (openBlock(), createBlock(resolveDynamicComponent(TREND_ICON[__props.trend]), {
1156
1156
  key: 0,
1157
1157
  class: "text-ink-soft size-3"
1158
- })) : createCommentVNode("", true)]), createElementVNode("span", _hoisted_4, toDisplayString(__props.label), 1)]);
1158
+ })) : createCommentVNode("", true)]), createElementVNode("span", _hoisted_4$1, toDisplayString(__props.label), 1)]);
1159
1159
  };
1160
1160
  }
1161
1161
  });
1162
1162
  //#endregion
1163
1163
  //#region src/components/LocaleLinks.vue?vue&type=script&setup=true&lang.ts
1164
- var _hoisted_1 = ["aria-label"];
1165
- var _hoisted_2 = [
1164
+ var _hoisted_1$1 = ["aria-label"];
1165
+ var _hoisted_2$1 = [
1166
1166
  "lang",
1167
1167
  "aria-pressed",
1168
1168
  "onClick"
@@ -1206,12 +1206,707 @@ var LocaleLinks_default = /* @__PURE__ */ defineComponent({
1206
1206
  class: normalizeClass(["rounded-full px-2.5 py-1.5 text-xs transition-colors", preference.value === locale ? "bg-muted text-ink font-semibold" : "text-ink-soft hover:text-ink"]),
1207
1207
  "aria-pressed": preference.value === locale,
1208
1208
  onClick: ($event) => preference.value = locale
1209
- }, toDisplayString(__props.labels[locale]), 11, _hoisted_2);
1210
- }), 128))], 8, _hoisted_1);
1209
+ }, toDisplayString(__props.labels[locale]), 11, _hoisted_2$1);
1210
+ }), 128))], 8, _hoisted_1$1);
1211
1211
  };
1212
1212
  }
1213
1213
  });
1214
1214
  //#endregion
1215
+ //#region src/components/GoogleButton.vue
1216
+ var GoogleButton_default = /* @__PURE__ */ defineComponent({
1217
+ __name: "GoogleButton",
1218
+ props: { label: {} },
1219
+ emits: ["click"],
1220
+ setup(__props, { emit: __emit }) {
1221
+ const emit = __emit;
1222
+ return (_ctx, _cache) => {
1223
+ return openBlock(), createElementBlock("button", {
1224
+ type: "button",
1225
+ class: "border-hair bg-surface text-ink rounded-card hover:bg-muted flex h-11 w-full items-center justify-center gap-2 border text-sm font-medium transition-colors active:scale-95",
1226
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("click"))
1227
+ }, [_cache[1] || (_cache[1] = createStaticVNode("<svg class=\"size-4\" viewBox=\"0 0 48 48\" aria-hidden=\"true\"><path fill=\"#EA4335\" d=\"M24 9.5c3.5 0 6.6 1.2 9 3.6l6.7-6.7C35.6 2.7 30.2.5 24 .5 14.6.5 6.5 5.9 2.6 13.7l7.8 6.1C12.3 13.7 17.7 9.5 24 9.5z\"></path><path fill=\"#4285F4\" d=\"M46.5 24.5c0-1.6-.1-3.1-.4-4.5H24v9h12.7c-.6 3-2.3 5.6-4.9 7.3l7.6 5.9c4.4-4.1 7.1-10.2 7.1-17.7z\"></path><path fill=\"#FBBC05\" d=\"M10.4 28.2a14.6 14.6 0 0 1 0-8.4l-7.8-6.1a24 24 0 0 0 0 20.6l7.8-6.1z\"></path><path fill=\"#34A853\" d=\"M24 47.5c6.2 0 11.5-2 15.4-5.6l-7.6-5.9c-2.1 1.4-4.8 2.3-7.8 2.3-6.3 0-11.7-4.2-13.6-10l-7.8 6.1C6.5 42.1 14.6 47.5 24 47.5z\"></path></svg>", 1)), createTextVNode(" " + toDisplayString(__props.label), 1)]);
1228
+ };
1229
+ }
1230
+ });
1231
+ //#endregion
1232
+ //#region node_modules/.pnpm/nostics@1.2.0/node_modules/nostics/dist/index.mjs
1233
+ /**
1234
+ * Renders a diagnostic into a multi-line, unicode-decorated string suitable
1235
+ * for terminal output. The first line is `[<name>] <message>`; optional
1236
+ * details (`fix`, `sources`, `docs`) follow with `├▶`/`╰▶` connectors.
1237
+ */
1238
+ function formatDiagnostic(diagnostic) {
1239
+ const header = `[${diagnostic.name}] ${diagnostic.message}`;
1240
+ const details = [];
1241
+ if (diagnostic.fix) details.push(`fix: ${diagnostic.fix}`);
1242
+ if (diagnostic.sources?.length) details.push(`sources: ${diagnostic.sources.join(", ")}`);
1243
+ if (diagnostic.docs) details.push(`see: ${diagnostic.docs}`);
1244
+ if (details.length === 0) return header;
1245
+ return [header, ...details.map((detail, i) => {
1246
+ return `${i < details.length - 1 ? "├▶" : "╰▶"} ${detail}`;
1247
+ })].join("\n");
1248
+ }
1249
+ /**
1250
+ * Transforms a value or a function that returns a value to a value.
1251
+ *
1252
+ * @param valFn either a value or a function that returns a value
1253
+ * @param args arguments to pass to the function if `valFn` is a function
1254
+ *
1255
+ * @internal
1256
+ */
1257
+ function toValueWithArgs(valFn, ...args) {
1258
+ return typeof valFn === "function" ? valFn(...args) : valFn;
1259
+ }
1260
+ /**
1261
+ * Creates a console reporter that renders each diagnostic with `formatter` and
1262
+ * prints the result via `console[method]`. Both default sensibly (`'warn'` and
1263
+ * {@link formatDiagnostic}); `method` can also be overridden per call through
1264
+ * the reporter options.
1265
+ */
1266
+ /* @__NO_SIDE_EFFECTS__ */
1267
+ function createConsoleReporter({ method: defaultMethod = "warn", formatter = formatDiagnostic } = {}) {
1268
+ return (diagnostic, { method = defaultMethod } = {}) => {
1269
+ console[method](formatter(diagnostic));
1270
+ };
1271
+ }
1272
+ var captureStackTrace = Error.captureStackTrace;
1273
+ var Diagnostic = class Diagnostic extends Error {
1274
+ name;
1275
+ /**
1276
+ * The diagnostic code, e.g. `MATH_E001`.
1277
+ * Also appears as the `name` property.
1278
+ */
1279
+ code;
1280
+ /**
1281
+ * URL to extended documentation for this diagnostic code.
1282
+ * Auto-generated from {@link DefineDiagnosticsOptions.docsBase}.
1283
+ */
1284
+ docs;
1285
+ /**
1286
+ * Optional actionable instructions on how to resolve the problem.
1287
+ */
1288
+ fix;
1289
+ /**
1290
+ * Locations in user code that contributed to this diagnostic, in
1291
+ * `file:line:column` format. Relevant when the stack trace doesn't reflect
1292
+ * the user's source (e.g. compilers, bundlers), otherwise redundant with the
1293
+ * stack and should be omitted.
1294
+ */
1295
+ sources;
1296
+ /**
1297
+ * Alias for {@link Error.message}: the reason this diagnostic was raised.
1298
+ */
1299
+ get why() {
1300
+ return this.message;
1301
+ }
1302
+ /**
1303
+ * @param init structured initializer; `why` is required
1304
+ * @param captureFrom V8 stack-cutoff frame. Defaults to {@link Diagnostic}
1305
+ * so the top of the trace is the `new Diagnostic(...)` call site.
1306
+ * `defineDiagnostics` passes its action method to strip its own frames too.
1307
+ * Ignored on engines without `Error.captureStackTrace`.
1308
+ */
1309
+ constructor(init, captureFrom = Diagnostic) {
1310
+ super(init.why, { cause: init.cause });
1311
+ this.code = this.name = init.code;
1312
+ this.fix = init.fix;
1313
+ this.docs = init.docs;
1314
+ this.sources = init.sources;
1315
+ captureStackTrace?.(this, captureFrom);
1316
+ }
1317
+ /**
1318
+ * Converts the diagnostic into a serializable structured object.
1319
+ */
1320
+ toJSON() {
1321
+ return {
1322
+ name: this.name,
1323
+ why: this.why,
1324
+ fix: this.fix,
1325
+ docs: this.docs,
1326
+ sources: this.sources,
1327
+ cause: this.cause,
1328
+ stack: this.stack
1329
+ };
1330
+ }
1331
+ };
1332
+ /**
1333
+ * Resolves the docs URL for a code from a `docsBase` (string template or
1334
+ * resolver function). Shared by {@link defineDiagnostics} and
1335
+ * {@link defineProdDiagnostics}. Per-code `docs` overrides are handled by the
1336
+ * caller; this only covers the `docsBase`-derived case.
1337
+ *
1338
+ * @internal
1339
+ */
1340
+ function deriveDocs(docsBase, code) {
1341
+ return typeof docsBase === "string" ? `${docsBase}/${code.toLowerCase()}` : docsBase?.(code);
1342
+ }
1343
+ /**
1344
+ * Creates a typed diagnostics object from a set of code definitions. Each
1345
+ * code becomes a callable {@link DiagnosticHandle}: invoke to report, or
1346
+ * `throw` the result to raise. No `new` required, no proxy.
1347
+ */
1348
+ /* @__NO_SIDE_EFFECTS__ */
1349
+ function defineDiagnostics(options) {
1350
+ const reporters = options.reporters ?? [];
1351
+ const result = {};
1352
+ const { docsBase } = options;
1353
+ for (const code of Object.keys(options.codes)) {
1354
+ const def = options.codes[code];
1355
+ const docs = def.docs === false ? void 0 : def.docs || deriveDocs(docsBase, code);
1356
+ const handle = (params = {}, reporterOptions = {}) => {
1357
+ const diagnostic = new Diagnostic({
1358
+ code,
1359
+ why: toValueWithArgs(def.why, params),
1360
+ fix: toValueWithArgs(def.fix, params),
1361
+ docs,
1362
+ cause: params.cause,
1363
+ sources: params.sources
1364
+ }, handle);
1365
+ for (const reporter of reporters) reporter(diagnostic, reporterOptions);
1366
+ return diagnostic;
1367
+ };
1368
+ result[code] = handle;
1369
+ }
1370
+ return result;
1371
+ }
1372
+ //#endregion
1373
+ //#region node_modules/.pnpm/vue-router@5.3.0_@vue+compiler-sfc@3.5.42_rolldown@1.2.6_vite@8.2.2_@types+node@24.13.3_32624d71e3238734f500b9958d6cb19f/node_modules/vue-router/dist/useApi-CUgTH_jn.js
1374
+ /*!
1375
+ * vue-router v5.3.0
1376
+ * (c) 2026 Eduardo San Martin Morote
1377
+ * @license MIT
1378
+ */
1379
+ var noop = () => {};
1380
+ /**
1381
+ * Typesafe alternative to Array.isArray
1382
+ * https://github.com/microsoft/TypeScript/pull/48228
1383
+ *
1384
+ * @internal
1385
+ */
1386
+ var isArray = Array.isArray;
1387
+ Symbol(process.env.NODE_ENV !== "production" ? "navigation failure" : "");
1388
+ var propertiesToLog = [
1389
+ "params",
1390
+ "query",
1391
+ "hash"
1392
+ ];
1393
+ /**
1394
+ * Stringifies a raw location for display in dev warnings.
1395
+ *
1396
+ * @internal
1397
+ */
1398
+ function stringifyRoute(to) {
1399
+ if (!to || typeof to === "string") return to;
1400
+ if (to.path != null) return to.path;
1401
+ const location = {};
1402
+ for (const key of propertiesToLog) if (key in to) location[key] = to[key];
1403
+ return JSON.stringify(location, null, 2);
1404
+ }
1405
+ /**
1406
+ * Runtime diagnostics catalog for Vue Router.
1407
+ *
1408
+ * Every entry has a stable `VUE_ROUTER_R####` code, a `why` that states the problem
1409
+ * (the diagnosis only, never the remedy) and a `fix` that states the remedy
1410
+ * (only, never the diagnosis). They are complementary: the reporter prints
1411
+ * both, so neither repeats the other. The diagnosis substrings asserted by the
1412
+ * warning tests stay in `why`. All call sites stay behind the existing `__DEV__` (or
1413
+ * `process.env.NODE_ENV !== 'production'`) guards and remain bare expression
1414
+ * statements so they tree-shake out of production builds.
1415
+ *
1416
+ * Codes are permanent: never rename or reuse one.
1417
+ * - `VUE_ROUTER_R0###` core runtime warnings
1418
+ * - `VUE_ROUTER_R1###` experimental data-loaders
1419
+ */
1420
+ var diagnostics = /*#__PURE__*/ defineDiagnostics({
1421
+ reporters: [/*#__PURE__*/ createConsoleReporter()],
1422
+ codes: {
1423
+ VUE_ROUTER_R0001: {
1424
+ why: (p) => `Parent route "${p.name}" not found when adding child route`,
1425
+ fix: "Add the parent route before its children, or check the parent name for typos.",
1426
+ docs: "https://router.vuejs.org/guide/advanced/dynamic-routing.html#Adding-nested-routes"
1427
+ },
1428
+ VUE_ROUTER_R0002: {
1429
+ why: (p) => `Cannot remove non-existent route "${p.name}"`,
1430
+ fix: "Check the route name; it may already have been removed or was never added.",
1431
+ docs: "https://router.vuejs.org/guide/advanced/dynamic-routing.html#Removing-routes"
1432
+ },
1433
+ VUE_ROUTER_R0003: {
1434
+ why: (p) => `Location "${stringifyRoute(p.location)}" resolved to "${p.href}". A resolved location cannot start with multiple slashes.`,
1435
+ fix: "Remove the leading slashes from the location or fix the route configuration."
1436
+ },
1437
+ VUE_ROUTER_R0004: {
1438
+ why: (p) => `No match found for location with path "${stringifyRoute(p.path)}"`,
1439
+ fix: "Add a route matching this path or check for typos in the location.",
1440
+ docs: "https://router.vuejs.org/guide/essentials/dynamic-matching.html#Catch-all-404-Not-found-Route"
1441
+ },
1442
+ VUE_ROUTER_R0005: {
1443
+ why: (p) => `router.resolve() was passed an invalid location. This will fail in production.\nLocation: ${stringifyRoute(p.rawLocation)}`,
1444
+ fix: "Pass a valid route location: a string path or an object with `path` or `name`."
1445
+ },
1446
+ VUE_ROUTER_R0006: {
1447
+ why: (p) => `Path "${p.path}" was passed with params but they will be ignored because a "path" was passed.`,
1448
+ fix: "Use a named route `{ name, params }` instead of `{ path, params }`.",
1449
+ docs: "https://router.vuejs.org/guide/essentials/navigation.html#Navigate-to-a-different-location"
1450
+ },
1451
+ VUE_ROUTER_R0007: {
1452
+ why: (p) => `A \`hash\` should always start with the character "#" but received "${p.hash}".`,
1453
+ fix: (p) => `Prepend "#" to the hash in your route location: use "#${p.hash}".`
1454
+ },
1455
+ VUE_ROUTER_R0008: {
1456
+ why: (p) => `Invalid redirect found:\n${p.target}\n when navigating to "${p.to}".\nThis will break in production.`,
1457
+ fix: "A redirect must resolve to a location with a `name` or `path`; return one of those (or a string path) from `redirect`.",
1458
+ docs: "https://router.vuejs.org/guide/essentials/redirect-and-alias.html#Redirect"
1459
+ },
1460
+ VUE_ROUTER_R0009: {
1461
+ why: (p) => `Detected a possibly infinite redirection in a navigation guard when going from "${p.from}" to "${p.to}". Aborting to avoid a Stack Overflow. This might break in production if not fixed.`,
1462
+ fix: "A guard is returning a new location on every call; make that return conditional so it only redirects when actually needed.",
1463
+ docs: "https://router.vuejs.org/guide/advanced/navigation-guards.html#Global-Before-Guards"
1464
+ },
1465
+ VUE_ROUTER_R0010: {
1466
+ why: "Uncaught error during route navigation",
1467
+ fix: "Register an error handler with `router.onError()` to handle navigation errors."
1468
+ },
1469
+ VUE_ROUTER_R0011: {
1470
+ why: "Unexpected error when starting the router:",
1471
+ fix: "Inspect the actual cause; a navigation guard or async component likely threw during the initial navigation."
1472
+ },
1473
+ VUE_ROUTER_R0020: {
1474
+ why: (p) => `No active route record was found when calling \`${p.fn}()\`. Maybe you called it inside of App.vue?`,
1475
+ fix: "Call it from a component rendered inside <router-view> (a page component or one of its children), not from App.vue.",
1476
+ docs: "https://router.vuejs.org/guide/advanced/composition-api.html#Navigation-Guards"
1477
+ },
1478
+ VUE_ROUTER_R0021: {
1479
+ why: "No active route record was found when reactivating component with navigation guard. This is likely a bug in vue-router.",
1480
+ fix: "Report with a minimal reproduction at https://github.com/vuejs/router/issues/new/choose."
1481
+ },
1482
+ VUE_ROUTER_R0022: {
1483
+ why: (p) => `${p.fn}() was called outside of component setup but it must be called at the top of a setup function`,
1484
+ fix: "Call it synchronously at the top of `setup()`, before any `await`.",
1485
+ docs: "https://router.vuejs.org/guide/advanced/composition-api.html#Navigation-Guards"
1486
+ },
1487
+ VUE_ROUTER_R0023: {
1488
+ why: (p) => `The "next" callback was never called inside of ${p.name ? `"${p.name}"` : ""}:\n${p.guard}`,
1489
+ fix: "Make sure `next()` runs on every branch, including early returns and async paths, or drop the `next` parameter and return the value instead.",
1490
+ docs: "https://router.vuejs.org/guide/advanced/navigation-guards.html#Optional-third-argument-next"
1491
+ },
1492
+ VUE_ROUTER_R0024: {
1493
+ why: (p) => `The "next" callback was called more than once in one navigation guard when going from "${p.from}" to "${p.to}". This will fail in production.`,
1494
+ fix: "Call `next()` exactly once per guard: remove the extra call, or migrate to returning the value you passed to `next()`.",
1495
+ docs: "https://router.vuejs.org/guide/advanced/navigation-guards.html#Optional-third-argument-next"
1496
+ },
1497
+ VUE_ROUTER_R0025: {
1498
+ why: "The `next()` callback in navigation guards is deprecated.",
1499
+ fix: "Return the value instead: `next()` becomes `return`, `next(false)` becomes `return false`, `next(\"/path\")` becomes `return \"/path\"`.",
1500
+ docs: "https://router.vuejs.org/guide/advanced/navigation-guards.html#Optional-third-argument-next"
1501
+ },
1502
+ VUE_ROUTER_R0026: {
1503
+ why: (p) => `Record with path "${p.path}" is either missing a "component(s)" or "children" property.`,
1504
+ fix: "Add a `component`, `components`, or `children` to the route record.",
1505
+ docs: "https://router.vuejs.org/guide/essentials/nested-routes.html"
1506
+ },
1507
+ VUE_ROUTER_R0027: {
1508
+ why: (p) => `Component "${p.name}" in record with path "${p.path}" is not a valid component. Received "${p.received}".`,
1509
+ fix: "Pass a component or a function returning a Promise that resolves to one."
1510
+ },
1511
+ VUE_ROUTER_R0028: {
1512
+ why: (p) => `Component "${p.name}" in record with path "${p.path}" is a Promise instead of a function that returns a Promise. This will break in production if not fixed.`,
1513
+ fix: `Defer the import in an arrow function so it loads lazily: write "() => import('./MyPage.vue')", not "import('./MyPage.vue')".`,
1514
+ docs: "https://router.vuejs.org/guide/advanced/lazy-loading.html"
1515
+ },
1516
+ VUE_ROUTER_R0029: {
1517
+ why: (p) => `Component "${p.name}" in record with path "${p.path}" is defined using "defineAsyncComponent()".`,
1518
+ fix: `Drop the wrapper and pass "() => import('./MyPage.vue')" directly; the router handles lazy components itself.`,
1519
+ docs: "https://router.vuejs.org/guide/advanced/lazy-loading.html#Relationship-to-async-components"
1520
+ },
1521
+ VUE_ROUTER_R0030: {
1522
+ why: (p) => `Component "${p.name}" in record with path "${p.path}" is a function that does not return a Promise. This will break in production if not fixed.`,
1523
+ fix: "Return a dynamic import (`() => import(\"./MyPage.vue\")`) from the function, or add a `displayName` if it is a functional component.",
1524
+ docs: "https://router.vuejs.org/guide/advanced/lazy-loading.html"
1525
+ },
1526
+ VUE_ROUTER_R0040: {
1527
+ why: (p) => `Because "${p.el}" starts with "#", scrollBehavior resolves it as an element id via document.getElementById("${p.el.slice(1)}"), not as a CSS selector. No element has that id, but "${p.el}" does match an element with document.querySelector().`,
1528
+ fix: (p) => `Resolve the element yourself and return the node: el: document.querySelector('${p.el}').`,
1529
+ docs: "https://router.vuejs.org/guide/advanced/scroll-behavior.html"
1530
+ },
1531
+ VUE_ROUTER_R0041: {
1532
+ why: (p) => `The selector "${p.el}" is invalid. See https://mathiasbynens.be/notes/css-escapes or CSS.escape (https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape) for the escaping rules.`,
1533
+ fix: "Build an id selector as `#${CSS.escape(id)}` so special characters in the id are escaped.",
1534
+ docs: "https://router.vuejs.org/guide/advanced/scroll-behavior.html"
1535
+ },
1536
+ VUE_ROUTER_R0042: {
1537
+ why: (p) => `Couldn't find element using selector "${p.el}" returned by scrollBehavior.`,
1538
+ fix: "Return a selector that matches an existing element, or guard against missing elements.",
1539
+ docs: "https://router.vuejs.org/guide/advanced/scroll-behavior.html"
1540
+ },
1541
+ VUE_ROUTER_R0050: {
1542
+ why: (p) => {
1543
+ let to;
1544
+ try {
1545
+ to = p.to === void 0 ? "undefined" : JSON.stringify(p.to);
1546
+ } catch {
1547
+ to = String(p.to);
1548
+ }
1549
+ return `Invalid value for prop "to" in useLink()\n- to: ${to}`;
1550
+ },
1551
+ fix: "Pass a valid route location (a string path or an object) to the \"to\" prop."
1552
+ },
1553
+ VUE_ROUTER_R0060: {
1554
+ why: (p) => `<router-view> can no longer be used directly inside <${p.comp}>.`,
1555
+ fix: (p) => `Wrap the slot's resolved component with <${p.comp}> instead of nesting <router-view> in it:\n\n<router-view v-slot="{ Component }">\n <${p.comp}>\n <component :is="Component" />\n </${p.comp}>\n</router-view>`,
1556
+ docs: "https://router.vuejs.org/guide/advanced/router-view-slot.html#KeepAlive-Transition"
1557
+ },
1558
+ VUE_ROUTER_R0070: {
1559
+ why: (p) => `Cannot resolve a relative location without an absolute path. Trying to resolve "${p.to}" from "${p.from}".`,
1560
+ fix: (p) => `Resolve from an absolute \`from\` path that starts with "/", e.g. "/${p.from}".`
1561
+ },
1562
+ VUE_ROUTER_R0080: {
1563
+ why: (p) => `Error decoding "${p.text}". Using original value`,
1564
+ fix: "Ensure the value is correctly percent-encoded."
1565
+ },
1566
+ VUE_ROUTER_R0090: {
1567
+ why: (p) => `Found duplicated params with name "${p.name}" for path "${p.path}". Only the last one will be available on "$route.params".`,
1568
+ fix: "Give each param a unique name within the path.",
1569
+ docs: "https://router.vuejs.org/guide/essentials/route-matching-syntax.html"
1570
+ },
1571
+ VUE_ROUTER_R0100: {
1572
+ why: (p) => `Discarded invalid param(s) "${p.params}" when navigating.` + p.inherited + ` See https://github.com/vuejs/router/commit/e887570 for more details.`,
1573
+ fix: "Only pass params that exist on the target route."
1574
+ },
1575
+ VUE_ROUTER_R0101: {
1576
+ why: (p) => `The Matcher cannot resolve relative paths but received "${p.path}". Unless you directly called \`matcher.resolve("${p.path}")\`, this is probably a bug in vue-router. Please open an issue at https://github.com/vuejs/router/issues/new/choose.`,
1577
+ fix: "Pass an absolute path (starting with \"/\") to the matcher."
1578
+ },
1579
+ VUE_ROUTER_R0102: {
1580
+ why: (p) => `Alias "${p.alias}" and the original record: "${p.original}" must have the exact same param named "${p.name}"`,
1581
+ fix: "Use the same param names in the alias as in the original route.",
1582
+ docs: "https://router.vuejs.org/guide/essentials/redirect-and-alias.html#Alias"
1583
+ },
1584
+ VUE_ROUTER_R0103: {
1585
+ why: (p) => `The route named "${p.name}" has a child without a name, an empty path, and no children. Using that name won't render the empty path child, so this is probably a mistake.`,
1586
+ fix: "Move the `name` onto the empty-path child; or, if intentional, give the child its own name to silence this.",
1587
+ docs: "https://router.vuejs.org/guide/essentials/nested-routes.html#Nested-Named-Routes"
1588
+ },
1589
+ VUE_ROUTER_R0104: {
1590
+ why: (p) => `Absolute path "${p.path}" must have the exact same param named "${p.name}" as its parent "${p.parent}".`,
1591
+ fix: "Include the parent route params in the absolute child path.",
1592
+ docs: "https://router.vuejs.org/guide/essentials/nested-routes.html"
1593
+ },
1594
+ VUE_ROUTER_R0105: {
1595
+ why: (p) => `Finding ancestor route "${p.ancestor}" failed for "${p.record}"`,
1596
+ fix: "Report a reproduction at https://github.com/vuejs/router/issues/new/choose."
1597
+ },
1598
+ VUE_ROUTER_R0110: {
1599
+ why: `A hash base must end with a "#"`,
1600
+ fix: (p) => `Append "#" to the "base" argument passed to "createWebHashHistory()": "${p.base}" should be "${p.suggestion}".`
1601
+ },
1602
+ VUE_ROUTER_R0120: {
1603
+ why: "Error with push/replace State",
1604
+ fix: "The browser rejected the history API call; check for cross-origin or rate-limit issues."
1605
+ },
1606
+ VUE_ROUTER_R0121: {
1607
+ why: "history.state seems to have been manually replaced without preserving the necessary values.\nYou can find more information at https://router.vuejs.org/guide/migration/#Usage-of-history-state",
1608
+ fix: "Merge the router's state into your own when calling it manually: `history.replaceState({ ...history.state, ...yourState }, '', url)`.",
1609
+ docs: "https://router.vuejs.org/guide/migration.html#Usage-of-history-state"
1610
+ },
1611
+ VUE_ROUTER_R1001: {
1612
+ why: (p) => `Data loader "${String(p.key)}" has a different parent than the current context. This shouldn't be happening.`,
1613
+ fix: "Report a bug with a minimal reproduction at https://github.com/vuejs/router/."
1614
+ },
1615
+ VUE_ROUTER_R1002: {
1616
+ why: "Returning a NavigationResult is deprecated.",
1617
+ fix: "Replace `return new NavigationResult(to)` with `reroute(to)`, which throws internally to reroute.",
1618
+ docs: "https://router.vuejs.org/data-loaders/navigation-aware.html#Controlling-the-navigation-with-reroute-"
1619
+ },
1620
+ VUE_ROUTER_R1003: {
1621
+ why: (p) => `Loader "${p.key}"'s "commit()" was called but there is no staged data.`,
1622
+ fix: "Ensure the loader resolved before calling `commit()`.",
1623
+ docs: "https://router.vuejs.org/data-loaders/defining-loaders.html#Delaying-data-updates-with-commit"
1624
+ },
1625
+ VUE_ROUTER_R1004: {
1626
+ why: (p) => "A loader returned a NavigationResult but is not registered on the route." + p.key,
1627
+ fix: "Export the loader from the page component so it gets registered, e.g. `export const useUserData = defineLoader(...)`.",
1628
+ docs: "https://router.vuejs.org/data-loaders/organization.html"
1629
+ },
1630
+ VUE_ROUTER_R1005: {
1631
+ why: (p) => `Data loader "${p.key}" has itself as parent. This shouldn't be happening.`,
1632
+ fix: "Report a bug with a minimal reproduction at https://github.com/vuejs/router/."
1633
+ },
1634
+ VUE_ROUTER_R1006: {
1635
+ why: (p) => `A query was defined with the same key as the loader "[${p.key}]".\nSee https://pinia-colada.esm.dev/#TODO`,
1636
+ fix: "If the key is meant to match, use the data loader directly; otherwise rename the `useQuery()` key so it no longer collides.",
1637
+ docs: "https://router.vuejs.org/data-loaders/colada.html"
1638
+ },
1639
+ VUE_ROUTER_R1007: {
1640
+ why: "Data Loader was setup twice.",
1641
+ fix: "Register `DataLoaderPlugin` a single time via `app.use()`.",
1642
+ docs: "https://router.vuejs.org/data-loaders.html#Installation"
1643
+ },
1644
+ VUE_ROUTER_R1008: {
1645
+ why: "Data Loader is experimental and subject to breaking changes in the future.",
1646
+ docs: "https://router.vuejs.org/data-loaders.html"
1647
+ },
1648
+ VUE_ROUTER_R1009: {
1649
+ why: "Returning a NavigationResult from a loader is deprecated.",
1650
+ fix: "Call `reroute(to)` inside the loader instead of returning `new NavigationResult(to)`; it throws internally to reroute.",
1651
+ docs: "https://router.vuejs.org/data-loaders/navigation-aware.html#Controlling-the-navigation-with-reroute-"
1652
+ }
1653
+ }
1654
+ });
1655
+ Symbol(process.env.NODE_ENV !== "production" ? "router view location matched" : "");
1656
+ Symbol(process.env.NODE_ENV !== "production" ? "router view depth" : "");
1657
+ /**
1658
+ * Allows overriding the router instance returned by `useRouter` in tests. r
1659
+ * stands for router
1660
+ *
1661
+ * @internal
1662
+ */
1663
+ var routerKey = Symbol(process.env.NODE_ENV !== "production" ? "router" : "");
1664
+ /**
1665
+ * Allows overriding the current route returned by `useRoute` in tests. rl
1666
+ * stands for route location
1667
+ *
1668
+ * @internal
1669
+ */
1670
+ var routeLocationKey = Symbol(process.env.NODE_ENV !== "production" ? "route location" : "");
1671
+ Symbol(process.env.NODE_ENV !== "production" ? "router view location" : "");
1672
+ //#endregion
1673
+ //#region node_modules/.pnpm/vue-router@5.3.0_@vue+compiler-sfc@3.5.42_rolldown@1.2.6_vite@8.2.2_@types+node@24.13.3_32624d71e3238734f500b9958d6cb19f/node_modules/vue-router/dist/devtools-CLRpXhL7.js
1674
+ /*!
1675
+ * vue-router v5.3.0
1676
+ * (c) 2026 Eduardo San Martin Morote
1677
+ * @license MIT
1678
+ */
1679
+ var isBrowser = typeof document !== "undefined";
1680
+ /**
1681
+ * Check if two `RouteRecords` are equal. Takes into account aliases: they are
1682
+ * considered equal to the `RouteRecord` they are aliasing.
1683
+ *
1684
+ * @param a - first {@link RouteRecord}
1685
+ * @param b - second {@link RouteRecord}
1686
+ */
1687
+ function isSameRouteRecord(a, b) {
1688
+ return (a.aliasOf || a) === (b.aliasOf || b);
1689
+ }
1690
+ function isSameRouteLocationParams(a, b) {
1691
+ if (Object.keys(a).length !== Object.keys(b).length) return false;
1692
+ for (var key in a) if (!isSameRouteLocationParamsValue(a[key], b[key])) return false;
1693
+ return true;
1694
+ }
1695
+ function isSameRouteLocationParamsValue(a, b) {
1696
+ return isArray(a) ? isEquivalentArray(a, b) : isArray(b) ? isEquivalentArray(b, a) : (a && a.valueOf()) === (b && b.valueOf());
1697
+ }
1698
+ /**
1699
+ * Check if two arrays are the same or if an array with one single entry is the
1700
+ * same as another primitive value. Used to check query and parameters
1701
+ *
1702
+ * @param a - array of values
1703
+ * @param b - array of values or a single value
1704
+ */
1705
+ function isEquivalentArray(a, b) {
1706
+ return isArray(b) ? a.length === b.length && a.every((value, i) => value === b[i]) : a.length === 1 && a[0] === b;
1707
+ }
1708
+ /**
1709
+ * ScrollBehavior instance used by the router to compute and restore the scroll
1710
+ * position when navigating.
1711
+ */
1712
+ function isRouteLocation(route) {
1713
+ return typeof route === "string" || route && typeof route === "object";
1714
+ }
1715
+ //#endregion
1716
+ //#region node_modules/.pnpm/vue-router@5.3.0_@vue+compiler-sfc@3.5.42_rolldown@1.2.6_vite@8.2.2_@types+node@24.13.3_32624d71e3238734f500b9958d6cb19f/node_modules/vue-router/dist/vue-router.js
1717
+ /*!
1718
+ * vue-router v5.3.0
1719
+ * (c) 2026 Eduardo San Martin Morote
1720
+ * @license MIT
1721
+ */
1722
+ /**
1723
+ * Returns the internal behavior of a {@link RouterLink} without the rendering part.
1724
+ *
1725
+ * @param props - a `to` location and an optional `replace` flag
1726
+ */
1727
+ function useLink(props) {
1728
+ const router = inject(routerKey);
1729
+ const currentRoute = inject(routeLocationKey);
1730
+ let hasPrevious = false;
1731
+ let previousTo = null;
1732
+ const route = computed(() => {
1733
+ const to = unref(props.to);
1734
+ if (process.env.NODE_ENV !== "production" && (!hasPrevious || to !== previousTo)) {
1735
+ if (!isRouteLocation(to)) diagnostics.VUE_ROUTER_R0050({ to });
1736
+ previousTo = to;
1737
+ hasPrevious = true;
1738
+ }
1739
+ return router.resolve(to);
1740
+ });
1741
+ const activeRecordIndex = computed(() => {
1742
+ const { matched } = route.value;
1743
+ const { length } = matched;
1744
+ const routeMatched = matched[length - 1];
1745
+ const currentMatched = currentRoute.matched;
1746
+ if (!routeMatched || !currentMatched.length) return -1;
1747
+ const index = currentMatched.findIndex(isSameRouteRecord.bind(null, routeMatched));
1748
+ if (index > -1) return index;
1749
+ const parentRecordPath = getOriginalPath(matched[length - 2]);
1750
+ return length > 1 && getOriginalPath(routeMatched) === parentRecordPath && currentMatched[currentMatched.length - 1].path !== parentRecordPath ? currentMatched.findIndex(isSameRouteRecord.bind(null, matched[length - 2])) : index;
1751
+ });
1752
+ const isActive = computed(() => activeRecordIndex.value > -1 && includesParams(currentRoute.params, route.value.params));
1753
+ const isExactActive = computed(() => activeRecordIndex.value > -1 && activeRecordIndex.value === currentRoute.matched.length - 1 && isSameRouteLocationParams(currentRoute.params, route.value.params));
1754
+ function navigate(e = {}) {
1755
+ if (guardEvent(e)) {
1756
+ const p = router[unref(props.replace) ? "replace" : "push"](unref(props.to)).catch(noop);
1757
+ if (props.viewTransition && typeof document !== "undefined" && "startViewTransition" in document) document.startViewTransition(() => p);
1758
+ return p;
1759
+ }
1760
+ return Promise.resolve();
1761
+ }
1762
+ if ((process.env.NODE_ENV !== "production" || false) && isBrowser) {
1763
+ const instance = getCurrentInstance();
1764
+ if (instance) {
1765
+ const linkContextDevtools = {
1766
+ route: route.value,
1767
+ isActive: isActive.value,
1768
+ isExactActive: isExactActive.value,
1769
+ error: null
1770
+ };
1771
+ instance.__vrl_devtools = instance.__vrl_devtools || [];
1772
+ instance.__vrl_devtools.push(linkContextDevtools);
1773
+ watchEffect(() => {
1774
+ linkContextDevtools.route = route.value;
1775
+ linkContextDevtools.isActive = isActive.value;
1776
+ linkContextDevtools.isExactActive = isExactActive.value;
1777
+ linkContextDevtools.error = isRouteLocation(unref(props.to)) ? null : "Invalid \"to\" value";
1778
+ }, { flush: "post" });
1779
+ }
1780
+ }
1781
+ /**
1782
+ * NOTE: update {@link _RouterLinkI}'s `$slots` type when updating this
1783
+ */
1784
+ return {
1785
+ route,
1786
+ href: computed(() => route.value.href),
1787
+ isActive,
1788
+ isExactActive,
1789
+ navigate
1790
+ };
1791
+ }
1792
+ function preferSingleVNode(vnodes) {
1793
+ return vnodes.length === 1 ? vnodes[0] : vnodes;
1794
+ }
1795
+ /**
1796
+ * Component to render a link that triggers a navigation on click.
1797
+ */
1798
+ var RouterLink = /* @__PURE__ */ defineComponent({
1799
+ name: "RouterLink",
1800
+ compatConfig: { MODE: 3 },
1801
+ props: {
1802
+ to: {
1803
+ type: [String, Object],
1804
+ required: true
1805
+ },
1806
+ replace: Boolean,
1807
+ activeClass: String,
1808
+ exactActiveClass: String,
1809
+ custom: Boolean,
1810
+ ariaCurrentValue: {
1811
+ type: String,
1812
+ default: "page"
1813
+ },
1814
+ viewTransition: Boolean
1815
+ },
1816
+ useLink,
1817
+ setup(props, { slots }) {
1818
+ const link = reactive(useLink(props));
1819
+ const { options } = inject(routerKey);
1820
+ const elClass = computed(() => ({
1821
+ [getLinkClass(props.activeClass, options.linkActiveClass, "router-link-active")]: link.isActive,
1822
+ [getLinkClass(props.exactActiveClass, options.linkExactActiveClass, "router-link-exact-active")]: link.isExactActive
1823
+ }));
1824
+ return () => {
1825
+ const children = slots.default && preferSingleVNode(slots.default(link));
1826
+ return props.custom ? children : h("a", {
1827
+ "aria-current": link.isExactActive ? props.ariaCurrentValue : null,
1828
+ href: link.href,
1829
+ onClick: link.navigate,
1830
+ class: elClass.value
1831
+ }, children);
1832
+ };
1833
+ }
1834
+ });
1835
+ function guardEvent(e) {
1836
+ if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return;
1837
+ if (e.defaultPrevented) return;
1838
+ if (e.button !== void 0 && e.button !== 0) return;
1839
+ if (e.currentTarget && e.currentTarget.getAttribute) {
1840
+ const target = e.currentTarget.getAttribute("target");
1841
+ if (/\b_blank\b/i.test(target)) return;
1842
+ }
1843
+ if (e.preventDefault) e.preventDefault();
1844
+ return true;
1845
+ }
1846
+ function includesParams(outer, inner) {
1847
+ for (const key in inner) {
1848
+ const innerValue = inner[key];
1849
+ const outerValue = outer[key];
1850
+ if (typeof innerValue === "string") {
1851
+ if (innerValue !== outerValue) return false;
1852
+ } else if (!isArray(outerValue) || outerValue.length !== innerValue.length || innerValue.some((value, i) => value.valueOf() !== outerValue[i].valueOf())) return false;
1853
+ }
1854
+ return true;
1855
+ }
1856
+ /**
1857
+ * Get the original path value of a record by following its aliasOf
1858
+ * @param record
1859
+ */
1860
+ function getOriginalPath(record) {
1861
+ return record ? record.aliasOf ? record.aliasOf.path : record.path : "";
1862
+ }
1863
+ /**
1864
+ * Utility class to get the active class based on defaults.
1865
+ * @param propClass
1866
+ * @param globalClass
1867
+ * @param defaultClass
1868
+ */
1869
+ var getLinkClass = (propClass, globalClass, defaultClass) => propClass != null ? propClass : globalClass != null ? globalClass : defaultClass;
1870
+ //#endregion
1871
+ //#region src/components/TabBar.vue?vue&type=script&setup=true&lang.ts
1872
+ var _hoisted_1 = { class: "tab-bar" };
1873
+ var _hoisted_2 = ["aria-label"];
1874
+ var _hoisted_3 = { class: "tab-icon-slot" };
1875
+ var _hoisted_4 = { class: "tab-label" };
1876
+ //#endregion
1877
+ //#region src/components/TabBar.vue
1878
+ var TabBar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
1879
+ __name: "TabBar",
1880
+ props: {
1881
+ items: {},
1882
+ active: {},
1883
+ label: { default: "" }
1884
+ },
1885
+ setup(__props) {
1886
+ return (_ctx, _cache) => {
1887
+ return openBlock(), createElementBlock("header", _hoisted_1, [createElementVNode("nav", {
1888
+ class: "tab-bar-inner",
1889
+ "aria-label": __props.label || void 0
1890
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item) => {
1891
+ return openBlock(), createBlock(unref(RouterLink), {
1892
+ key: item.key,
1893
+ to: item.to,
1894
+ class: normalizeClass(["tab-link", { "is-active": item.key === __props.active }]),
1895
+ "aria-current": item.key === __props.active ? "page" : void 0,
1896
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(tapFeedback)())
1897
+ }, {
1898
+ default: withCtx(() => [createElementVNode("span", _hoisted_3, [(openBlock(), createBlock(resolveDynamicComponent(item.icon), { class: "tab-icon" }))]), createElementVNode("span", _hoisted_4, toDisplayString(item.label), 1)]),
1899
+ _: 2
1900
+ }, 1032, [
1901
+ "to",
1902
+ "class",
1903
+ "aria-current"
1904
+ ]);
1905
+ }), 128))], 8, _hoisted_2)]);
1906
+ };
1907
+ }
1908
+ }), [["__scopeId", "data-v-2c5e190d"]]);
1909
+ //#endregion
1215
1910
  //#region src/i18n/runtime.ts
1216
1911
  /**
1217
1912
  * Builds an i18n runtime around an app's own catalogue.
@@ -1344,6 +2039,6 @@ function createI18nRuntime(options) {
1344
2039
  */
1345
2040
  var VERSION = "0.0.0";
1346
2041
  //#endregion
1347
- export { AppError, BaseButton_default as BaseButton, BaseInput_default as BaseInput, BaseSheet_default as BaseSheet, EmptyState_default as EmptyState, LocaleLinks_default as LocaleLinks, PageHeader_default as PageHeader, SectionHeading_default as SectionHeading, SegmentedControl_default as SegmentedControl, SettingsGroup_default as SettingsGroup, SettingsRow_default as SettingsRow, SkeletonList_default as SkeletonList, StatCard_default as StatCard, ToneDot_default as ToneDot, VERSION, addDays, applyTheme, createI18nRuntime, downloadJson, eachDayOfYear, formatDate, fromDateKey, isApplePortable, isInstalled, isThemePreference, lastNDays, leadingBlanks, needsIosInstall, readStoredTheme, registerErrorMapper, relativeDayLabel, safeRedirect, setFormatLocale, setThemeStorageKey, startOfWeek, tapFeedback, toAppError, toDateKey, todayKey, useDebouncedCallback, useDragScroll, useOnline, useTheme, useToday, useVisualViewport };
2042
+ export { AppError, BaseButton_default as BaseButton, BaseInput_default as BaseInput, BaseSheet_default as BaseSheet, EmptyState_default as EmptyState, GoogleButton_default as GoogleButton, LocaleLinks_default as LocaleLinks, PageHeader_default as PageHeader, SectionHeading_default as SectionHeading, SegmentedControl_default as SegmentedControl, SettingsGroup_default as SettingsGroup, SettingsRow_default as SettingsRow, SkeletonList_default as SkeletonList, StatCard_default as StatCard, TabBar_default as TabBar, ToneDot_default as ToneDot, VERSION, addDays, applyTheme, createI18nRuntime, downloadJson, eachDayOfYear, formatDate, fromDateKey, isApplePortable, isInstalled, isThemePreference, lastNDays, leadingBlanks, needsIosInstall, readStoredTheme, registerErrorMapper, relativeDayLabel, safeRedirect, setFormatLocale, setThemeStorageKey, startOfWeek, tapFeedback, toAppError, toDateKey, todayKey, useDebouncedCallback, useDragScroll, useOnline, useTheme, useToday, useVisualViewport };
1348
2043
 
1349
2044
  //# sourceMappingURL=index.js.map