directix 1.3.0 → 1.4.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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * directix v1.3.0
2
+ * directix v1.4.0
3
3
  * A comprehensive, easy-to-use, and high-performance Vue custom directives library supporting both Vue 2 and Vue 3
4
4
  * (c) 2021-present saqqdy <https://github.com/saqqdy>
5
5
  * Released under the MIT License.
@@ -57,11 +57,12 @@ var __async = (__this, __arguments, generator) => {
57
57
  });
58
58
  };
59
59
  /*!
60
- * directix v1.3.0
60
+ * directix v1.4.0
61
61
  * A comprehensive, easy-to-use, and high-performance Vue custom directives library supporting both Vue 2 and Vue 3
62
62
  * (c) 2021-present saqqdy <https://github.com/saqqdy>
63
63
  * Released under the MIT License.
64
64
  */
65
+ import { ref, unref, watch, onUnmounted, readonly, computed, onMounted } from "vue";
65
66
  function createVue2Directive(hooks) {
66
67
  const directive = {
67
68
  bind(el, binding, vnode) {
@@ -440,7 +441,7 @@ function transformTextContent(el, transformFn) {
440
441
  function isInputElement(el) {
441
442
  return el.tagName === "INPUT" || el.tagName === "TEXTAREA";
442
443
  }
443
- const DEFAULT_KEEP_LOWER = [
444
+ const DEFAULT_KEEP_LOWER$1 = [
444
445
  "a",
445
446
  "an",
446
447
  "the",
@@ -459,25 +460,25 @@ const DEFAULT_KEEP_LOWER = [
459
460
  "with",
460
461
  "as"
461
462
  ];
462
- function capitalizeText(text, options) {
463
+ function capitalizeText$1(text, options) {
463
464
  if (!text) return text;
464
- const { every = true, keepLower = DEFAULT_KEEP_LOWER } = options;
465
+ const { every = true, keepLower = DEFAULT_KEEP_LOWER$1 } = options;
465
466
  if (every) {
466
467
  const words = text.toLowerCase().split(/\s+/);
467
468
  return words.map((word, index) => {
468
469
  if (index === 0) {
469
- return capitalizeWord(word);
470
+ return capitalizeWord$1(word);
470
471
  }
471
472
  if (keepLower.includes(word.toLowerCase())) {
472
473
  return word.toLowerCase();
473
474
  }
474
- return capitalizeWord(word);
475
+ return capitalizeWord$1(word);
475
476
  }).join(" ");
476
477
  } else {
477
- return capitalizeWord(text);
478
+ return capitalizeWord$1(text);
478
479
  }
479
480
  }
480
- function capitalizeWord(word) {
481
+ function capitalizeWord$1(word) {
481
482
  if (!word) return word;
482
483
  return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
483
484
  }
@@ -491,7 +492,7 @@ function normalizeOptions$B(binding) {
491
492
  }
492
493
  return {
493
494
  every: (_a = binding.every) != null ? _a : true,
494
- keepLower: (_b = binding.keepLower) != null ? _b : DEFAULT_KEEP_LOWER,
495
+ keepLower: (_b = binding.keepLower) != null ? _b : DEFAULT_KEEP_LOWER$1,
495
496
  onInput: (_c = binding.onInput) != null ? _c : true
496
497
  };
497
498
  }
@@ -501,20 +502,20 @@ const vCapitalcase = defineDirective({
501
502
  mounted(el, binding) {
502
503
  const options = normalizeOptions$B(binding.value);
503
504
  if (isInputElement(el)) {
504
- const cleanup2 = setupTextTransformInput(el, options, (text) => capitalizeText(text, options));
505
+ const cleanup2 = setupTextTransformInput(el, options, (text) => capitalizeText$1(text, options));
505
506
  el.__capitalcaseCleanup = cleanup2;
506
507
  } else {
507
- transformTextContent(el, (text) => capitalizeText(text, options));
508
+ transformTextContent(el, (text) => capitalizeText$1(text, options));
508
509
  }
509
510
  },
510
511
  updated(el, binding) {
511
512
  const options = normalizeOptions$B(binding.value);
512
513
  if (isInputElement(el)) {
513
514
  if (options.onInput) {
514
- el.value = capitalizeText(el.value, options);
515
+ el.value = capitalizeText$1(el.value, options);
515
516
  }
516
517
  } else {
517
- transformTextContent(el, (text) => capitalizeText(text, options));
518
+ transformTextContent(el, (text) => capitalizeText$1(text, options));
518
519
  }
519
520
  },
520
521
  unmounted(el) {
@@ -523,133 +524,15 @@ const vCapitalcase = defineDirective({
523
524
  delete el.__capitalcaseCleanup;
524
525
  }
525
526
  });
526
- const vClickDelay = defineDirective({
527
- name: "click-delay",
528
- ssr: true,
529
- defaults: {
530
- delay: 300,
531
- disabled: false,
532
- pendingClass: "v-click-delay--pending",
533
- feedback: true
534
- },
535
- mounted(el, binding) {
536
- const options = normalizeOptions$A(binding.value, binding);
537
- if (options.disabled) return;
538
- const state = {
539
- options,
540
- handler: createClickHandler(el, options),
541
- isPending: false,
542
- timeoutId: null
543
- };
544
- el.__clickDelay = state;
545
- el.addEventListener("click", state.handler);
546
- el.addEventListener("touchend", state.handler);
547
- },
548
- updated(el, binding) {
549
- const state = el.__clickDelay;
550
- if (!state) {
551
- const options = normalizeOptions$A(binding.value, binding);
552
- if (!options.disabled) {
553
- const newState = {
554
- options,
555
- handler: createClickHandler(el, options),
556
- isPending: false,
557
- timeoutId: null
558
- };
559
- el.__clickDelay = newState;
560
- el.addEventListener("click", newState.handler);
561
- el.addEventListener("touchend", newState.handler);
562
- }
563
- return;
564
- }
565
- const newOptions = normalizeOptions$A(binding.value, binding);
566
- if (newOptions.disabled && !state.options.disabled) {
567
- el.removeEventListener("click", state.handler);
568
- el.removeEventListener("touchend", state.handler);
569
- if (state.timeoutId) {
570
- clearTimeout(state.timeoutId);
571
- }
572
- removePendingClass(el, state.options);
573
- delete el.__clickDelay;
574
- } else if (!newOptions.disabled && state.options.disabled) {
575
- state.handler = createClickHandler(el, newOptions);
576
- state.isPending = false;
577
- state.timeoutId = null;
578
- el.addEventListener("click", state.handler);
579
- el.addEventListener("touchend", state.handler);
580
- }
581
- state.options = newOptions;
582
- },
583
- unmounted(el) {
584
- const state = el.__clickDelay;
585
- if (!state) return;
586
- el.removeEventListener("click", state.handler);
587
- el.removeEventListener("touchend", state.handler);
588
- if (state.timeoutId) {
589
- clearTimeout(state.timeoutId);
590
- }
591
- removePendingClass(el, state.options);
592
- delete el.__clickDelay;
593
- }
594
- });
595
- function createClickHandler(el, options) {
596
- return (event) => {
597
- const state = el.__clickDelay;
598
- if (!state || state.isPending) {
599
- event.preventDefault();
600
- event.stopPropagation();
601
- return;
602
- }
603
- state.isPending = true;
604
- if (options.feedback && options.pendingClass) {
605
- el.classList.add(options.pendingClass);
606
- }
607
- options.handler(event);
608
- state.timeoutId = setTimeout(() => {
609
- state.isPending = false;
610
- state.timeoutId = null;
611
- removePendingClass(el, options);
612
- }, options.delay);
613
- };
614
- }
615
- function removePendingClass(el, options) {
616
- if (options.feedback && options.pendingClass) {
617
- el.classList.remove(options.pendingClass);
618
- }
527
+ const STATE_PREFIX = "__directix_";
528
+ function setState$1(el, key, state) {
529
+ el[STATE_PREFIX + key] = state;
619
530
  }
620
- function parseTime$1(arg) {
621
- if (!arg) return null;
622
- if (arg.endsWith("ms")) {
623
- return parseInt(arg, 10);
624
- }
625
- if (arg.endsWith("s")) {
626
- return parseFloat(arg) * 1e3;
627
- }
628
- const num = parseInt(arg, 10);
629
- return Number.isNaN(num) ? null : num;
531
+ function getState$1(el, key) {
532
+ return el[STATE_PREFIX + key];
630
533
  }
631
- function normalizeOptions$A(binding, directiveBinding) {
632
- var _a, _b, _c, _d;
633
- const delay = parseTime$1(directiveBinding.arg) || 300;
634
- if (typeof binding === "function") {
635
- return {
636
- handler: binding,
637
- delay,
638
- disabled: false,
639
- pendingClass: "v-click-delay--pending",
640
- feedback: true
641
- };
642
- }
643
- if (!binding) {
644
- throw new Error("[Directix] v-click-delay: handler is required");
645
- }
646
- return {
647
- handler: binding.handler,
648
- delay: (_a = binding.delay) != null ? _a : delay,
649
- disabled: (_b = binding.disabled) != null ? _b : false,
650
- pendingClass: (_c = binding.pendingClass) != null ? _c : "v-click-delay--pending",
651
- feedback: (_d = binding.feedback) != null ? _d : true
652
- };
534
+ function deleteState(el, key) {
535
+ delete el[STATE_PREFIX + key];
653
536
  }
654
537
  function isElement(value) {
655
538
  return value instanceof Element;
@@ -676,15 +559,15 @@ function getScrollParent(el) {
676
559
  }
677
560
  function on(target, event, handler, options = false) {
678
561
  if (!isBrowser()) return;
679
- const opts = normalizeOptions$z(options);
562
+ const opts = normalizeOptions$A(options);
680
563
  target.addEventListener(event, handler, opts);
681
564
  }
682
565
  function off(target, event, handler, options = false) {
683
566
  if (!isBrowser()) return;
684
- const opts = normalizeOptions$z(options);
567
+ const opts = normalizeOptions$A(options);
685
568
  target.removeEventListener(event, handler, opts);
686
569
  }
687
- function normalizeOptions$z(options) {
570
+ function normalizeOptions$A(options) {
688
571
  if (typeof options === "boolean") {
689
572
  return options;
690
573
  }
@@ -694,7 +577,7 @@ function normalizeOptions$z(options) {
694
577
  }
695
578
  return capture;
696
579
  }
697
- function getEventPosition(e) {
580
+ function getEventPosition$1(e) {
698
581
  let clientX = 0, clientY = 0;
699
582
  if ("touches" in e && e.touches.length > 0) {
700
583
  clientX = e.touches[0].clientX;
@@ -710,6 +593,58 @@ function getEventPosition(e) {
710
593
  clientY
711
594
  };
712
595
  }
596
+ function bindEvents$2(target, events, options = false) {
597
+ Object.entries(events).forEach(([event, handler]) => {
598
+ target.addEventListener(event, handler, typeof options === "boolean" ? options : normalizeOptionsObject(options));
599
+ });
600
+ return () => {
601
+ Object.entries(events).forEach(([event, handler]) => {
602
+ target.removeEventListener(event, handler, typeof options === "boolean" ? options : normalizeOptionsObject(options));
603
+ });
604
+ };
605
+ }
606
+ function normalizeOptionsObject(options) {
607
+ const { capture = false, passive = false, once = false } = options;
608
+ if (supportsPassive()) {
609
+ return { capture, passive, once };
610
+ }
611
+ return capture;
612
+ }
613
+ const EVENT_MODIFIERS = [
614
+ "click",
615
+ "input",
616
+ "change",
617
+ "submit",
618
+ "scroll",
619
+ "resize",
620
+ "mouseenter",
621
+ "mouseleave",
622
+ "mousemove",
623
+ "mousedown",
624
+ "mouseup",
625
+ "keydown",
626
+ "keyup",
627
+ "focus",
628
+ "blur",
629
+ "touchstart",
630
+ "touchmove",
631
+ "touchend"
632
+ ];
633
+ function getEventTypeFromModifiers(modifiers) {
634
+ for (const modifier of EVENT_MODIFIERS) {
635
+ if (modifiers[modifier]) {
636
+ return modifier;
637
+ }
638
+ }
639
+ return null;
640
+ }
641
+ function getDefaultEventType(el) {
642
+ const tagName = el.tagName.toLowerCase();
643
+ if (tagName === "input" || tagName === "textarea") {
644
+ return "input";
645
+ }
646
+ return "click";
647
+ }
713
648
  function isString(value) {
714
649
  return typeof value === "string";
715
650
  }
@@ -896,53 +831,171 @@ function parseTime(arg) {
896
831
  function generateId(prefix = "") {
897
832
  return `${prefix}${Date.now().toString(36)}${Math.random().toString(36).slice(2, 9)}`;
898
833
  }
899
- const vClickOutside = defineDirective({
900
- name: "click-outside",
901
- ssr: false,
834
+ const STATE_KEY$5 = "clickDelay";
835
+ function removePendingClass(el, options) {
836
+ if (options.feedback && options.pendingClass) {
837
+ el.classList.remove(options.pendingClass);
838
+ }
839
+ }
840
+ function createClickHandler(el, options) {
841
+ return (event) => {
842
+ const state = getState$1(el, STATE_KEY$5);
843
+ if (!state || state.isPending) {
844
+ event.preventDefault();
845
+ event.stopPropagation();
846
+ return;
847
+ }
848
+ state.isPending = true;
849
+ if (options.feedback && options.pendingClass) {
850
+ el.classList.add(options.pendingClass);
851
+ }
852
+ options.handler(event);
853
+ state.timeoutId = setTimeout(() => {
854
+ state.isPending = false;
855
+ state.timeoutId = null;
856
+ removePendingClass(el, options);
857
+ }, options.delay);
858
+ };
859
+ }
860
+ function normalizeOptions$z(binding, directiveBinding) {
861
+ var _a, _b, _c, _d;
862
+ const delay = parseTime(directiveBinding.arg) || 300;
863
+ if (typeof binding === "function") {
864
+ return {
865
+ handler: binding,
866
+ delay,
867
+ disabled: false,
868
+ pendingClass: "v-click-delay--pending",
869
+ feedback: true
870
+ };
871
+ }
872
+ if (!binding) {
873
+ throw new Error("[Directix] v-click-delay: handler is required");
874
+ }
875
+ return {
876
+ handler: binding.handler,
877
+ delay: (_a = binding.delay) != null ? _a : delay,
878
+ disabled: (_b = binding.disabled) != null ? _b : false,
879
+ pendingClass: (_c = binding.pendingClass) != null ? _c : "v-click-delay--pending",
880
+ feedback: (_d = binding.feedback) != null ? _d : true
881
+ };
882
+ }
883
+ const vClickDelay = defineDirective({
884
+ name: "click-delay",
885
+ ssr: true,
902
886
  defaults: {
903
- capture: true,
904
- events: ["click"],
887
+ delay: 300,
905
888
  disabled: false,
906
- stop: false,
907
- prevent: false
889
+ pendingClass: "v-click-delay--pending",
890
+ feedback: true
908
891
  },
909
892
  mounted(el, binding) {
910
- const options = normalizeOptions$y(binding.value);
893
+ const options = normalizeOptions$z(binding.value, binding);
911
894
  if (options.disabled) return;
912
895
  const state = {
913
896
  options,
914
- handlers: /* @__PURE__ */ new Map()
915
- };
916
- el.__clickOutside = state;
917
- const createHandler = (_eventType) => {
918
- return (event) => {
919
- if (!isValidClick(el, event, options)) {
920
- return;
921
- }
922
- if (options.stop) {
923
- event.stopPropagation();
924
- }
925
- if (options.prevent) {
926
- event.preventDefault();
927
- }
928
- options.handler(event);
929
- };
897
+ handler: createClickHandler(el, options),
898
+ isPending: false,
899
+ timeoutId: null
930
900
  };
931
- options.events.forEach((eventType) => {
932
- const handler = createHandler();
933
- state.handlers.set(eventType, handler);
934
- const listenerOptions = {
935
- capture: options.capture,
936
- passive: !options.prevent
937
- };
938
- on(document, eventType, handler, listenerOptions);
939
- });
901
+ setState$1(el, STATE_KEY$5, state);
902
+ el.addEventListener("click", state.handler);
903
+ el.addEventListener("touchend", state.handler);
940
904
  },
941
905
  updated(el, binding) {
942
- const state = el.__clickOutside;
943
- if (!state) return;
944
- const oldOptions = state.options;
945
- const newOptions = normalizeOptions$y(binding.value);
906
+ const state = getState$1(el, STATE_KEY$5);
907
+ if (!state) {
908
+ const options = normalizeOptions$z(binding.value, binding);
909
+ if (!options.disabled) {
910
+ const newState = {
911
+ options,
912
+ handler: createClickHandler(el, options),
913
+ isPending: false,
914
+ timeoutId: null
915
+ };
916
+ setState$1(el, STATE_KEY$5, newState);
917
+ el.addEventListener("click", newState.handler);
918
+ el.addEventListener("touchend", newState.handler);
919
+ }
920
+ return;
921
+ }
922
+ const newOptions = normalizeOptions$z(binding.value, binding);
923
+ if (newOptions.disabled && !state.options.disabled) {
924
+ el.removeEventListener("click", state.handler);
925
+ el.removeEventListener("touchend", state.handler);
926
+ if (state.timeoutId) {
927
+ clearTimeout(state.timeoutId);
928
+ }
929
+ removePendingClass(el, state.options);
930
+ deleteState(el, STATE_KEY$5);
931
+ } else if (!newOptions.disabled && state.options.disabled) {
932
+ state.handler = createClickHandler(el, newOptions);
933
+ state.isPending = false;
934
+ state.timeoutId = null;
935
+ el.addEventListener("click", state.handler);
936
+ el.addEventListener("touchend", state.handler);
937
+ }
938
+ state.options = newOptions;
939
+ },
940
+ unmounted(el) {
941
+ const state = getState$1(el, STATE_KEY$5);
942
+ if (!state) return;
943
+ el.removeEventListener("click", state.handler);
944
+ el.removeEventListener("touchend", state.handler);
945
+ if (state.timeoutId) {
946
+ clearTimeout(state.timeoutId);
947
+ }
948
+ removePendingClass(el, state.options);
949
+ deleteState(el, STATE_KEY$5);
950
+ }
951
+ });
952
+ const vClickOutside = defineDirective({
953
+ name: "click-outside",
954
+ ssr: false,
955
+ defaults: {
956
+ capture: true,
957
+ events: ["click"],
958
+ disabled: false,
959
+ stop: false,
960
+ prevent: false
961
+ },
962
+ mounted(el, binding) {
963
+ const options = normalizeOptions$y(binding.value);
964
+ if (options.disabled) return;
965
+ const state = {
966
+ options,
967
+ handlers: /* @__PURE__ */ new Map()
968
+ };
969
+ el.__clickOutside = state;
970
+ const createHandler = (_eventType) => {
971
+ return (event) => {
972
+ if (!isValidClick$1(el, event, options)) {
973
+ return;
974
+ }
975
+ if (options.stop) {
976
+ event.stopPropagation();
977
+ }
978
+ if (options.prevent) {
979
+ event.preventDefault();
980
+ }
981
+ options.handler(event);
982
+ };
983
+ };
984
+ options.events.forEach((eventType) => {
985
+ const handler = createHandler();
986
+ state.handlers.set(eventType, handler);
987
+ const listenerOptions = {
988
+ capture: options.capture,
989
+ passive: !options.prevent
990
+ };
991
+ on(document, eventType, handler, listenerOptions);
992
+ });
993
+ },
994
+ updated(el, binding) {
995
+ const state = el.__clickOutside;
996
+ if (!state) return;
997
+ const oldOptions = state.options;
998
+ const newOptions = normalizeOptions$y(binding.value);
946
999
  if (oldOptions.disabled !== newOptions.disabled) {
947
1000
  if (newOptions.disabled) {
948
1001
  state.handlers.forEach((handler, eventType) => {
@@ -952,7 +1005,7 @@ const vClickOutside = defineDirective({
952
1005
  } else {
953
1006
  const createHandler = (_eventType) => {
954
1007
  return (event) => {
955
- if (!isValidClick(el, event, newOptions)) return;
1008
+ if (!isValidClick$1(el, event, newOptions)) return;
956
1009
  if (newOptions.stop) event.stopPropagation();
957
1010
  if (newOptions.prevent) event.preventDefault();
958
1011
  newOptions.handler(event);
@@ -1002,7 +1055,7 @@ function normalizeOptions$y(binding) {
1002
1055
  prevent: (_e = binding.prevent) != null ? _e : false
1003
1056
  }, binding);
1004
1057
  }
1005
- function isValidClick(el, event, options) {
1058
+ function isValidClick$1(el, event, options) {
1006
1059
  var _a;
1007
1060
  const target = event.target;
1008
1061
  if (el.contains(target)) {
@@ -1018,7 +1071,7 @@ function isValidClick(el, event, options) {
1018
1071
  }
1019
1072
  return true;
1020
1073
  }
1021
- function copyToClipboard(text) {
1074
+ function copyToClipboard$1(text) {
1022
1075
  return __async(this, null, function* () {
1023
1076
  if (supportsClipboard()) {
1024
1077
  try {
@@ -1028,10 +1081,10 @@ function copyToClipboard(text) {
1028
1081
  console.warn("[Directix] Clipboard API failed, falling back to execCommand");
1029
1082
  }
1030
1083
  }
1031
- return copyWithExecCommand(text);
1084
+ return copyWithExecCommand$1(text);
1032
1085
  });
1033
1086
  }
1034
- function copyWithExecCommand(text) {
1087
+ function copyWithExecCommand$1(text) {
1035
1088
  const textarea = document.createElement("textarea");
1036
1089
  textarea.value = text;
1037
1090
  textarea.style.cssText = `
@@ -1073,7 +1126,7 @@ const vCopy = defineDirective({
1073
1126
  return;
1074
1127
  }
1075
1128
  try {
1076
- const success = yield copyToClipboard(text);
1129
+ const success = yield copyToClipboard$1(text);
1077
1130
  if (success) {
1078
1131
  (_b = (_a = state.options).onSuccess) == null ? void 0 : _b.call(_a, text);
1079
1132
  el.dispatchEvent(new CustomEvent("copy:success", { detail: { text } }));
@@ -1110,7 +1163,7 @@ function normalizeOptions$x(binding) {
1110
1163
  }
1111
1164
  return binding;
1112
1165
  }
1113
- function parseTargetTime(target) {
1166
+ function parseTargetTime$1(target) {
1114
1167
  if (target instanceof Date) {
1115
1168
  return target.getTime();
1116
1169
  }
@@ -1119,7 +1172,7 @@ function parseTargetTime(target) {
1119
1172
  }
1120
1173
  return new Date(target).getTime();
1121
1174
  }
1122
- function calculateTime(remaining) {
1175
+ function calculateTime$1(remaining) {
1123
1176
  const total = Math.max(0, remaining);
1124
1177
  return {
1125
1178
  days: Math.floor(total / (1e3 * 60 * 60 * 24)),
@@ -1130,7 +1183,7 @@ function calculateTime(remaining) {
1130
1183
  total
1131
1184
  };
1132
1185
  }
1133
- function formatTime(time, format) {
1186
+ function formatTime$1(time, format) {
1134
1187
  if (typeof format === "function") {
1135
1188
  return format(time);
1136
1189
  }
@@ -1165,7 +1218,7 @@ const vCountdown = defineDirective({
1165
1218
  ssr: true,
1166
1219
  mounted(el, binding) {
1167
1220
  const options = normalizeOptions$w(binding.value);
1168
- const targetTime = parseTargetTime(options.target);
1221
+ const targetTime = parseTargetTime$1(options.target);
1169
1222
  const state = {
1170
1223
  options,
1171
1224
  targetTime,
@@ -1183,7 +1236,7 @@ const vCountdown = defineDirective({
1183
1236
  updated(el, binding) {
1184
1237
  const state = el.__countdown;
1185
1238
  const newOptions = normalizeOptions$w(binding.value);
1186
- const newTargetTime = parseTargetTime(newOptions.target);
1239
+ const newTargetTime = parseTargetTime$1(newOptions.target);
1187
1240
  if (newTargetTime !== state.targetTime) {
1188
1241
  state.targetTime = newTargetTime;
1189
1242
  state.options = newOptions;
@@ -1222,7 +1275,7 @@ function startCountdown(el, state) {
1222
1275
  }
1223
1276
  updateDisplay(el, state);
1224
1277
  if (state.options.onTick) {
1225
- const time = calculateTime(state.remaining);
1278
+ const time = calculateTime$1(state.remaining);
1226
1279
  state.options.onTick(time);
1227
1280
  }
1228
1281
  };
@@ -1236,45 +1289,10 @@ function stopCountdown(state) {
1236
1289
  }
1237
1290
  }
1238
1291
  function updateDisplay(el, state) {
1239
- const time = calculateTime(state.remaining);
1240
- const display = formatTime(time, state.options.format || "hh:mm:ss");
1292
+ const time = calculateTime$1(state.remaining);
1293
+ const display = formatTime$1(time, state.options.format || "hh:mm:ss");
1241
1294
  el.textContent = display;
1242
1295
  }
1243
- const EVENT_MODIFIERS = [
1244
- "click",
1245
- "input",
1246
- "change",
1247
- "submit",
1248
- "scroll",
1249
- "resize",
1250
- "mouseenter",
1251
- "mouseleave",
1252
- "mousemove",
1253
- "mousedown",
1254
- "mouseup",
1255
- "keydown",
1256
- "keyup",
1257
- "focus",
1258
- "blur",
1259
- "touchstart",
1260
- "touchmove",
1261
- "touchend"
1262
- ];
1263
- function getEventTypeFromModifiers(modifiers) {
1264
- for (const modifier of EVENT_MODIFIERS) {
1265
- if (modifiers[modifier]) {
1266
- return modifier;
1267
- }
1268
- }
1269
- return null;
1270
- }
1271
- function getDefaultEventType(el) {
1272
- const tagName = el.tagName.toLowerCase();
1273
- if (tagName === "input" || tagName === "textarea") {
1274
- return "input";
1275
- }
1276
- return "click";
1277
- }
1278
1296
  function normalizeOptions$v(binding, directiveBinding) {
1279
1297
  const wait = parseTime(directiveBinding.arg) || 300;
1280
1298
  if (typeof binding === "function") {
@@ -1334,7 +1352,7 @@ const vDebounce = defineDirective({
1334
1352
  delete el.__debounce;
1335
1353
  }
1336
1354
  });
1337
- function getBoundary(_el, boundary) {
1355
+ function getBoundary$1(_el, boundary) {
1338
1356
  var _a, _b;
1339
1357
  if (!boundary) return null;
1340
1358
  if (typeof boundary === "function") {
@@ -1347,7 +1365,7 @@ function getBoundary(_el, boundary) {
1347
1365
  }
1348
1366
  return boundary.getBoundingClientRect();
1349
1367
  }
1350
- function getClientCoords(e) {
1368
+ function getClientCoords$1(e) {
1351
1369
  if (e.type.startsWith("touch")) {
1352
1370
  const touch = e.touches[0];
1353
1371
  return { clientX: touch.clientX, clientY: touch.clientY };
@@ -1355,7 +1373,7 @@ function getClientCoords(e) {
1355
1373
  const mouseEvent = e;
1356
1374
  return { clientX: mouseEvent.clientX, clientY: mouseEvent.clientY };
1357
1375
  }
1358
- function parseTranslate(transform) {
1376
+ function parseTranslate$1(transform) {
1359
1377
  const match = transform.match(/translate\(([-\d.]+)px,\s*([-\d.]+)px\)/);
1360
1378
  if (match) {
1361
1379
  return { x: parseFloat(match[1]), y: parseFloat(match[2]) };
@@ -1418,15 +1436,15 @@ const vDraggable = defineDirective({
1418
1436
  if (e.type === "touchstart") {
1419
1437
  e.preventDefault();
1420
1438
  }
1421
- const { clientX, clientY } = getClientCoords(e);
1439
+ const { clientX, clientY } = getClientCoords$1(e);
1422
1440
  state.isDragging = true;
1423
1441
  state.startX = clientX;
1424
1442
  state.startY = clientY;
1425
- const { x, y } = parseTranslate(el.style.transform);
1443
+ const { x, y } = parseTranslate$1(el.style.transform);
1426
1444
  state.offsetX = x;
1427
1445
  state.offsetY = y;
1428
1446
  if (state.options.constrain || state.options.boundary) {
1429
- const boundary = state.options.boundary ? getBoundary(el, state.options.boundary) : (_a = el.parentElement) == null ? void 0 : _a.getBoundingClientRect();
1447
+ const boundary = state.options.boundary ? getBoundary$1(el, state.options.boundary) : (_a = el.parentElement) == null ? void 0 : _a.getBoundingClientRect();
1430
1448
  if (boundary) {
1431
1449
  const elRect = el.getBoundingClientRect();
1432
1450
  state.initialLeft = elRect.left - boundary.left;
@@ -1441,7 +1459,7 @@ const vDraggable = defineDirective({
1441
1459
  state.moveHandler = (moveEvent) => {
1442
1460
  var _a2, _b2;
1443
1461
  if (!state.isDragging) return;
1444
- const { clientX: moveX, clientY: moveY } = getClientCoords(moveEvent);
1462
+ const { clientX: moveX, clientY: moveY } = getClientCoords$1(moveEvent);
1445
1463
  let deltaX = moveX - state.startX, deltaY = moveY - state.startY;
1446
1464
  if (state.options.axis === "x") {
1447
1465
  deltaY = 0;
@@ -1479,7 +1497,7 @@ const vDraggable = defineDirective({
1479
1497
  document.removeEventListener("mouseup", state.endHandler);
1480
1498
  document.removeEventListener("touchend", state.endHandler);
1481
1499
  }
1482
- const { x: finalX, y: finalY } = parseTranslate(el.style.transform);
1500
+ const { x: finalX, y: finalY } = parseTranslate$1(el.style.transform);
1483
1501
  (_b2 = (_a2 = state.options).onEnd) == null ? void 0 : _b2.call(_a2, { x: finalX, y: finalY }, new MouseEvent("mouseup"));
1484
1502
  };
1485
1503
  document.addEventListener("mousemove", state.moveHandler);
@@ -1655,7 +1673,7 @@ function normalizeOptions$t(binding) {
1655
1673
  titleBehavior: (_d = binding == null ? void 0 : binding.titleBehavior) != null ? _d : "auto"
1656
1674
  };
1657
1675
  }
1658
- const FOCUSABLE_TAGS = /* @__PURE__ */ new Set(["input", "textarea", "select", "button"]);
1676
+ const FOCUSABLE_TAGS$1 = /* @__PURE__ */ new Set(["input", "textarea", "select", "button"]);
1659
1677
  function isEqual(a, b) {
1660
1678
  if (a === b) return true;
1661
1679
  if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
@@ -1677,7 +1695,7 @@ const vFocus = defineDirective({
1677
1695
  mounted(el, binding) {
1678
1696
  if (!isBrowser()) return;
1679
1697
  const options = normalizeOptions$s(binding.value);
1680
- if (!options.focus || !isFocusable(el)) {
1698
+ if (!options.focus || !isFocusable$1(el)) {
1681
1699
  if (options.focus) {
1682
1700
  console.warn("[Directix] v-focus: Element is not focusable");
1683
1701
  }
@@ -1745,10 +1763,10 @@ function normalizeOptions$s(binding) {
1745
1763
  refocus: false
1746
1764
  }, binding);
1747
1765
  }
1748
- function isFocusable(el) {
1766
+ function isFocusable$1(el) {
1749
1767
  if (!isBrowser()) return false;
1750
1768
  const tagName = el.tagName.toLowerCase();
1751
- if (FOCUSABLE_TAGS.has(tagName)) {
1769
+ if (FOCUSABLE_TAGS$1.has(tagName)) {
1752
1770
  return !el.disabled;
1753
1771
  }
1754
1772
  if (el.isContentEditable) return true;
@@ -1759,7 +1777,7 @@ function isFocusable(el) {
1759
1777
  }
1760
1778
  return false;
1761
1779
  }
1762
- const KEY_ALIASES = {
1780
+ const KEY_ALIASES$1 = {
1763
1781
  esc: "escape",
1764
1782
  space: " ",
1765
1783
  up: "arrowup",
@@ -1791,7 +1809,7 @@ const KEY_ALIASES = {
1791
1809
  const MODIFIER_KEYS = /* @__PURE__ */ new Set(["ctrl", "alt", "shift", "meta"]);
1792
1810
  function normalizeKey(key) {
1793
1811
  const lowerKey = key.toLowerCase();
1794
- return KEY_ALIASES[lowerKey] || lowerKey;
1812
+ return KEY_ALIASES$1[lowerKey] || lowerKey;
1795
1813
  }
1796
1814
  function parseHotkeyString(hotkey) {
1797
1815
  const parts = hotkey.toLowerCase().split(/[+.]/);
@@ -1806,7 +1824,7 @@ function parseHotkeyString(hotkey) {
1806
1824
  }
1807
1825
  return { key, modifiers };
1808
1826
  }
1809
- function matchesHotkey(event, entry) {
1827
+ function matchesHotkey$1(event, entry) {
1810
1828
  if (normalizeKey(event.key) !== entry.key) return false;
1811
1829
  const eventModifiers = /* @__PURE__ */ new Set();
1812
1830
  if (event.ctrlKey) eventModifiers.add("ctrl");
@@ -1893,7 +1911,7 @@ function createKeydownHandler(state) {
1893
1911
  return (event) => {
1894
1912
  for (const entry of state.entries) {
1895
1913
  if (entry.disabled) continue;
1896
- if (!matchesHotkey(event, entry)) continue;
1914
+ if (!matchesHotkey$1(event, entry)) continue;
1897
1915
  if (entry.prevent) event.preventDefault();
1898
1916
  if (entry.stop) event.stopPropagation();
1899
1917
  entry.handler(event);
@@ -1933,6 +1951,61 @@ const vHotkey = defineDirective({
1933
1951
  delete el.__hotkey;
1934
1952
  }
1935
1953
  });
1954
+ function useTimer() {
1955
+ const timeouts = /* @__PURE__ */ new Set();
1956
+ const intervals = /* @__PURE__ */ new Set();
1957
+ return {
1958
+ /**
1959
+ * Set a timeout (tracked for cleanup)
1960
+ */
1961
+ setTimeout(fn, delay) {
1962
+ const id = setTimeout(() => {
1963
+ timeouts.delete(id);
1964
+ fn();
1965
+ }, delay);
1966
+ timeouts.add(id);
1967
+ return id;
1968
+ },
1969
+ /**
1970
+ * Clear a specific timeout
1971
+ */
1972
+ clearTimeout(id) {
1973
+ clearTimeout(id);
1974
+ timeouts.delete(id);
1975
+ },
1976
+ /**
1977
+ * Set an interval (tracked for cleanup)
1978
+ */
1979
+ setInterval(fn, delay) {
1980
+ const id = setInterval(fn, delay);
1981
+ intervals.add(id);
1982
+ return id;
1983
+ },
1984
+ /**
1985
+ * Clear a specific interval
1986
+ */
1987
+ clearInterval(id) {
1988
+ clearInterval(id);
1989
+ intervals.delete(id);
1990
+ },
1991
+ /**
1992
+ * Clear all tracked timers
1993
+ */
1994
+ clearAll() {
1995
+ timeouts.forEach((id) => clearTimeout(id));
1996
+ intervals.forEach((id) => clearInterval(id));
1997
+ timeouts.clear();
1998
+ intervals.clear();
1999
+ },
2000
+ /**
2001
+ * Check if there are any active timers
2002
+ */
2003
+ hasActive() {
2004
+ return timeouts.size > 0 || intervals.size > 0;
2005
+ }
2006
+ };
2007
+ }
2008
+ const STATE_KEY$4 = "hover";
1936
2009
  function normalizeOptions$r(binding) {
1937
2010
  if (typeof binding === "function") {
1938
2011
  return { handler: binding, class: "v-hover" };
@@ -1944,6 +2017,26 @@ function normalizeOptions$r(binding) {
1944
2017
  leaveDelay: 0
1945
2018
  }, binding);
1946
2019
  }
2020
+ function applyHoverState(el, state, e) {
2021
+ var _a, _b;
2022
+ const { options } = state;
2023
+ if (options.class) {
2024
+ el.classList.add(options.class);
2025
+ }
2026
+ el.dispatchEvent(new CustomEvent("hover:enter", { detail: { event: e } }));
2027
+ (_a = options.onEnter) == null ? void 0 : _a.call(options, e);
2028
+ (_b = options.handler) == null ? void 0 : _b.call(options, true, e);
2029
+ }
2030
+ function applyLeaveState(el, state, e) {
2031
+ var _a, _b;
2032
+ const { options } = state;
2033
+ if (options.class) {
2034
+ el.classList.remove(options.class);
2035
+ }
2036
+ el.dispatchEvent(new CustomEvent("hover:leave", { detail: { event: e } }));
2037
+ (_a = options.onLeave) == null ? void 0 : _a.call(options, e);
2038
+ (_b = options.handler) == null ? void 0 : _b.call(options, false, e);
2039
+ }
1947
2040
  const vHover = defineDirective({
1948
2041
  name: "hover",
1949
2042
  ssr: false,
@@ -1956,56 +2049,54 @@ const vHover = defineDirective({
1956
2049
  mounted(el, binding) {
1957
2050
  const options = normalizeOptions$r(binding.value);
1958
2051
  if (options.disabled || !isBrowser()) return;
2052
+ const timer = useTimer();
2053
+ let isHovering = false;
1959
2054
  const state = {
1960
2055
  options,
1961
2056
  isHovering: false,
1962
- enterTimerId: null,
1963
- leaveTimerId: null,
1964
- enterHandler: () => {
1965
- },
1966
- leaveHandler: () => {
1967
- }
2057
+ timer,
2058
+ cleanup: null
1968
2059
  };
1969
- state.enterHandler = (e) => {
2060
+ const enterHandler = (e) => {
1970
2061
  const event = e;
1971
- if (state.leaveTimerId) {
1972
- clearTimeout(state.leaveTimerId);
1973
- state.leaveTimerId = null;
1974
- }
1975
- if (state.isHovering) return;
2062
+ timer.clearAll();
2063
+ if (isHovering) return;
1976
2064
  if (options.enterDelay && options.enterDelay > 0) {
1977
- state.enterTimerId = setTimeout(() => {
2065
+ timer.setTimeout(() => {
2066
+ isHovering = true;
1978
2067
  state.isHovering = true;
1979
2068
  applyHoverState(el, state, event);
1980
2069
  }, options.enterDelay);
1981
2070
  } else {
2071
+ isHovering = true;
1982
2072
  state.isHovering = true;
1983
2073
  applyHoverState(el, state, event);
1984
2074
  }
1985
2075
  };
1986
- state.leaveHandler = (e) => {
2076
+ const leaveHandler = (e) => {
1987
2077
  const event = e;
1988
- if (state.enterTimerId) {
1989
- clearTimeout(state.enterTimerId);
1990
- state.enterTimerId = null;
1991
- }
1992
- if (!state.isHovering) return;
2078
+ timer.clearAll();
2079
+ if (!isHovering) return;
1993
2080
  if (options.leaveDelay && options.leaveDelay > 0) {
1994
- state.leaveTimerId = setTimeout(() => {
2081
+ timer.setTimeout(() => {
2082
+ isHovering = false;
1995
2083
  state.isHovering = false;
1996
2084
  applyLeaveState(el, state, event);
1997
2085
  }, options.leaveDelay);
1998
2086
  } else {
2087
+ isHovering = false;
1999
2088
  state.isHovering = false;
2000
2089
  applyLeaveState(el, state, event);
2001
2090
  }
2002
2091
  };
2003
- el.__hover = state;
2004
- on(el, "mouseenter", state.enterHandler);
2005
- on(el, "mouseleave", state.leaveHandler);
2092
+ state.cleanup = bindEvents$2(el, {
2093
+ mouseenter: enterHandler,
2094
+ mouseleave: leaveHandler
2095
+ });
2096
+ setState$1(el, STATE_KEY$4, state);
2006
2097
  },
2007
2098
  updated(el, binding) {
2008
- const state = el.__hover;
2099
+ const state = getState$1(el, STATE_KEY$4);
2009
2100
  if (!state) return;
2010
2101
  const newOptions = normalizeOptions$r(binding.value);
2011
2102
  if (newOptions.disabled && !state.options.disabled) {
@@ -2014,40 +2105,15 @@ const vHover = defineDirective({
2014
2105
  state.options = newOptions;
2015
2106
  },
2016
2107
  unmounted(el) {
2017
- const state = el.__hover;
2108
+ var _a;
2109
+ const state = getState$1(el, STATE_KEY$4);
2018
2110
  if (!state) return;
2019
- if (state.enterTimerId) {
2020
- clearTimeout(state.enterTimerId);
2021
- }
2022
- if (state.leaveTimerId) {
2023
- clearTimeout(state.leaveTimerId);
2024
- }
2025
- off(el, "mouseenter", state.enterHandler);
2026
- off(el, "mouseleave", state.leaveHandler);
2111
+ state.timer.clearAll();
2112
+ (_a = state.cleanup) == null ? void 0 : _a.call(state);
2027
2113
  el.classList.remove(state.options.class || "v-hover");
2028
- delete el.__hover;
2114
+ deleteState(el, STATE_KEY$4);
2029
2115
  }
2030
2116
  });
2031
- function applyHoverState(el, state, e) {
2032
- var _a, _b;
2033
- const { options } = state;
2034
- if (options.class) {
2035
- el.classList.add(options.class);
2036
- }
2037
- el.dispatchEvent(new CustomEvent("hover:enter", { detail: { event: e } }));
2038
- (_a = options.onEnter) == null ? void 0 : _a.call(options, e);
2039
- (_b = options.handler) == null ? void 0 : _b.call(options, true, e);
2040
- }
2041
- function applyLeaveState(el, state, e) {
2042
- var _a, _b;
2043
- const { options } = state;
2044
- if (options.class) {
2045
- el.classList.remove(options.class);
2046
- }
2047
- el.dispatchEvent(new CustomEvent("hover:leave", { detail: { event: e } }));
2048
- (_a = options.onLeave) == null ? void 0 : _a.call(options, e);
2049
- (_b = options.handler) == null ? void 0 : _b.call(options, false, e);
2050
- }
2051
2117
  const DEFAULTS = {
2052
2118
  minScale: 0.5,
2053
2119
  maxScale: 5,
@@ -2058,7 +2124,7 @@ const DEFAULTS = {
2058
2124
  zoomIndicatorDuration: 1500
2059
2125
  };
2060
2126
  let globalZIndex = 9999;
2061
- function getDistance$2(x1, y1, x2, y2) {
2127
+ function getDistance$3(x1, y1, x2, y2) {
2062
2128
  return Math.sqrt(__pow(x2 - x1, 2) + __pow(y2 - y1, 2));
2063
2129
  }
2064
2130
  function clamp(value, min, max) {
@@ -2241,7 +2307,7 @@ function createGestureHandlers(state, transformManager, closePreview) {
2241
2307
  gesture.swipeStartY = e.touches[0].clientY;
2242
2308
  } else if (e.touches.length === 2 && options.enablePinchZoom !== false) {
2243
2309
  gesture.isDragging = false;
2244
- gesture.startDistance = getDistance$2(
2310
+ gesture.startDistance = getDistance$3(
2245
2311
  e.touches[0].clientX,
2246
2312
  e.touches[0].clientY,
2247
2313
  e.touches[1].clientX,
@@ -2262,7 +2328,7 @@ function createGestureHandlers(state, transformManager, closePreview) {
2262
2328
  transform.translateY = constrained.y;
2263
2329
  updateTransform(false);
2264
2330
  } else if (e.touches.length === 2 && options.enablePinchZoom !== false) {
2265
- const currentDistance = getDistance$2(
2331
+ const currentDistance = getDistance$3(
2266
2332
  e.touches[0].clientX,
2267
2333
  e.touches[0].clientY,
2268
2334
  e.touches[1].clientX,
@@ -3031,7 +3097,7 @@ function normalizeOptions$l(binding) {
3031
3097
  tickInterval: 100
3032
3098
  }, binding);
3033
3099
  }
3034
- function getDistance$1(p1, p2) {
3100
+ function getDistance$2(p1, p2) {
3035
3101
  return Math.sqrt(__pow(p2.x - p1.x, 2) + __pow(p2.y - p1.y, 2));
3036
3102
  }
3037
3103
  const vLongPress = defineDirective({
@@ -3078,7 +3144,7 @@ const vLongPress = defineDirective({
3078
3144
  clearInterval(state.tickTimerId);
3079
3145
  state.tickTimerId = null;
3080
3146
  }
3081
- const pos = getEventPosition(event);
3147
+ const pos = getEventPosition$1(event);
3082
3148
  state.startPos = { x: pos.x, y: pos.y };
3083
3149
  state.startTime = Date.now();
3084
3150
  (_a = options.onStart) == null ? void 0 : _a.call(options, event);
@@ -3118,8 +3184,8 @@ const vLongPress = defineDirective({
3118
3184
  var _a;
3119
3185
  if (!state.timerId) return;
3120
3186
  const event = e;
3121
- const pos = getEventPosition(event);
3122
- const distance = getDistance$1(state.startPos, { x: pos.x, y: pos.y });
3187
+ const pos = getEventPosition$1(event);
3188
+ const distance = getDistance$2(state.startPos, { x: pos.x, y: pos.y });
3123
3189
  if (distance > (options.distance || 10)) {
3124
3190
  if (state.timerId) {
3125
3191
  clearTimeout(state.timerId);
@@ -3354,7 +3420,7 @@ const vMask = defineDirective({
3354
3420
  delete el[STATE_KEY$2];
3355
3421
  }
3356
3422
  });
3357
- function formatNumber(value, options) {
3423
+ function formatNumber$1(value, options) {
3358
3424
  const { precision = 0, separator = ",", decimal = ".", prefix = "", suffix = "" } = options;
3359
3425
  const fixed = value.toFixed(precision);
3360
3426
  const [intPart, decPart] = fixed.split(".");
@@ -3457,7 +3523,7 @@ function setupNumberInput(el, options, formatFn) {
3457
3523
  el.removeEventListener("blur", onBlur);
3458
3524
  };
3459
3525
  }
3460
- function formatMoney(value, options) {
3526
+ function formatMoney$1(value, options) {
3461
3527
  const { precision = 2, separator = ",", decimal = ".", symbol = "$", symbolPosition = "before" } = options;
3462
3528
  const fixed = value.toFixed(precision);
3463
3529
  const [intPart, decPart] = fixed.split(".");
@@ -3478,14 +3544,14 @@ const vMoney = defineDirective({
3478
3544
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
3479
3545
  const { symbol = "$", symbolPosition = "before" } = options;
3480
3546
  const prefix = symbolPosition === "before" ? symbol : "";
3481
- const cleanup2 = setupNumberInput(el, __spreadProps(__spreadValues({}, options), { prefix }), formatMoney);
3547
+ const cleanup2 = setupNumberInput(el, __spreadProps(__spreadValues({}, options), { prefix }), formatMoney$1);
3482
3548
  el.__money = { options, cleanup: cleanup2 };
3483
3549
  requestAnimationFrame(() => {
3484
3550
  const inputEl = el;
3485
3551
  if (inputEl.value) {
3486
3552
  const num = parseToNumber(inputEl.value, options.decimal || ".");
3487
3553
  if (num !== null) {
3488
- const formatted = formatMoney(clampValue(num, options), options);
3554
+ const formatted = formatMoney$1(clampValue(num, options), options);
3489
3555
  if (formatted !== inputEl.value) {
3490
3556
  inputEl.value = formatted;
3491
3557
  inputEl.dispatchEvent(new Event("input", { bubbles: true }));
@@ -3504,7 +3570,7 @@ const vMoney = defineDirective({
3504
3570
  }
3505
3571
  }
3506
3572
  if (value !== null) {
3507
- el.textContent = formatMoney(clampValue(value, options), options);
3573
+ el.textContent = formatMoney$1(clampValue(value, options), options);
3508
3574
  }
3509
3575
  }
3510
3576
  },
@@ -3521,7 +3587,7 @@ const vMoney = defineDirective({
3521
3587
  value = binding.value.value;
3522
3588
  }
3523
3589
  if (value !== null) {
3524
- el.textContent = formatMoney(clampValue(value, options), options);
3590
+ el.textContent = formatMoney$1(clampValue(value, options), options);
3525
3591
  }
3526
3592
  }
3527
3593
  },
@@ -3639,14 +3705,14 @@ const vNumber = defineDirective({
3639
3705
  var _a, _b;
3640
3706
  const options = typeof binding.value === "number" ? { precision: binding.value } : (_a = binding.value) != null ? _a : {};
3641
3707
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
3642
- const cleanup2 = setupNumberInput(el, options, formatNumber);
3708
+ const cleanup2 = setupNumberInput(el, options, formatNumber$1);
3643
3709
  el.__number = { options, cleanup: cleanup2 };
3644
3710
  requestAnimationFrame(() => {
3645
3711
  const inputEl = el;
3646
3712
  if (inputEl.value) {
3647
3713
  const num = parseToNumber(inputEl.value, options.decimal || ".");
3648
3714
  if (num !== null) {
3649
- const formatted = formatNumber(clampValue(num, options), options);
3715
+ const formatted = formatNumber$1(clampValue(num, options), options);
3650
3716
  if (formatted !== inputEl.value) {
3651
3717
  inputEl.value = formatted;
3652
3718
  inputEl.dispatchEvent(new Event("input", { bubbles: true }));
@@ -3667,7 +3733,7 @@ const vNumber = defineDirective({
3667
3733
  }
3668
3734
  }
3669
3735
  if (value !== null) {
3670
- el.textContent = formatNumber(clampValue(value, options), options);
3736
+ el.textContent = formatNumber$1(clampValue(value, options), options);
3671
3737
  }
3672
3738
  }
3673
3739
  },
@@ -3685,7 +3751,7 @@ const vNumber = defineDirective({
3685
3751
  value = binding.value.value;
3686
3752
  }
3687
3753
  if (value !== null) {
3688
- el.textContent = formatNumber(clampValue(value, options), options);
3754
+ el.textContent = formatNumber$1(clampValue(value, options), options);
3689
3755
  }
3690
3756
  }
3691
3757
  },
@@ -3696,14 +3762,6 @@ const vNumber = defineDirective({
3696
3762
  }
3697
3763
  });
3698
3764
  const STATE_KEY$1 = "__permission";
3699
- const WILDCARD = "*";
3700
- let globalConfig = null;
3701
- function configurePermission(config) {
3702
- globalConfig = config;
3703
- }
3704
- function getPermissionConfig() {
3705
- return globalConfig;
3706
- }
3707
3765
  function normalizeOptions$h(binding) {
3708
3766
  if (!binding) {
3709
3767
  throw new Error("[Directix] v-permission: permission value is required");
@@ -3716,39 +3774,14 @@ function normalizeOptions$h(binding) {
3716
3774
  }
3717
3775
  return binding;
3718
3776
  }
3719
- function hasPermission(required, permissions) {
3720
- return permissions.includes(WILDCARD) || permissions.includes(required);
3721
- }
3722
3777
  function verifyPermission(options) {
3723
- var _a;
3724
3778
  if (options.check) {
3725
3779
  return options.check(options.value, options.mode || "some");
3726
3780
  }
3727
- if (!globalConfig) {
3781
+ {
3728
3782
  console.warn("[Directix] v-permission: No permission config provided");
3729
3783
  return true;
3730
3784
  }
3731
- const permissions = globalConfig.getPermissions();
3732
- const roles = ((_a = globalConfig.getRoles) == null ? void 0 : _a.call(globalConfig)) || [];
3733
- const roleMap = globalConfig.roleMap || {};
3734
- const required = Array.isArray(options.value) ? options.value : [options.value];
3735
- const mode = options.mode || "some";
3736
- function checkSingle(value) {
3737
- if (value in roleMap) {
3738
- return roles.includes(value);
3739
- }
3740
- if (hasPermission(value, permissions)) {
3741
- return true;
3742
- }
3743
- for (const role of roles) {
3744
- const rolePermissions = roleMap[role] || [];
3745
- if (hasPermission(value, rolePermissions)) {
3746
- return true;
3747
- }
3748
- }
3749
- return false;
3750
- }
3751
- return mode === "every" ? required.every(checkSingle) : required.some(checkSingle);
3752
3785
  }
3753
3786
  function handleDenied(el, action, state) {
3754
3787
  var _a, _b;
@@ -3897,16 +3930,16 @@ function printElement(triggerEl, options) {
3897
3930
  return;
3898
3931
  }
3899
3932
  if (options.newWindow) {
3900
- yield printInNewWindow(targetEl, options);
3933
+ yield printInNewWindow$1(targetEl, options);
3901
3934
  } else {
3902
- yield printInIframe(targetEl, options);
3935
+ yield printInIframe$1(targetEl, options);
3903
3936
  }
3904
3937
  if (options.onAfterPrint) {
3905
3938
  options.onAfterPrint();
3906
3939
  }
3907
3940
  });
3908
3941
  }
3909
- function printInIframe(el, options) {
3942
+ function printInIframe$1(el, options) {
3910
3943
  return __async(this, null, function* () {
3911
3944
  var _a, _b, _c;
3912
3945
  const iframe = document.createElement("iframe");
@@ -3918,11 +3951,11 @@ function printInIframe(el, options) {
3918
3951
  document.body.removeChild(iframe);
3919
3952
  return;
3920
3953
  }
3921
- const content = buildPrintContent(el, options);
3954
+ const content = buildPrintContent$1(el, options);
3922
3955
  iframeDoc.open();
3923
3956
  iframeDoc.write(content);
3924
3957
  iframeDoc.close();
3925
- yield waitForImages(iframeDoc);
3958
+ yield waitForImages$1(iframeDoc);
3926
3959
  try {
3927
3960
  (_b = iframe.contentWindow) == null ? void 0 : _b.focus();
3928
3961
  (_c = iframe.contentWindow) == null ? void 0 : _c.print();
@@ -3934,18 +3967,18 @@ function printInIframe(el, options) {
3934
3967
  }, 1e3);
3935
3968
  });
3936
3969
  }
3937
- function printInNewWindow(el, options) {
3970
+ function printInNewWindow$1(el, options) {
3938
3971
  return __async(this, null, function* () {
3939
3972
  const printWindow = window.open("", "_blank");
3940
3973
  if (!printWindow) {
3941
3974
  console.warn("[Directix] v-print: Could not open print window");
3942
3975
  return;
3943
3976
  }
3944
- const content = buildPrintContent(el, options);
3977
+ const content = buildPrintContent$1(el, options);
3945
3978
  printWindow.document.open();
3946
3979
  printWindow.document.write(content);
3947
3980
  printWindow.document.close();
3948
- yield waitForImages(printWindow.document);
3981
+ yield waitForImages$1(printWindow.document);
3949
3982
  printWindow.focus();
3950
3983
  printWindow.print();
3951
3984
  setTimeout(() => {
@@ -3953,7 +3986,7 @@ function printInNewWindow(el, options) {
3953
3986
  }, 1e3);
3954
3987
  });
3955
3988
  }
3956
- function buildPrintContent(el, options) {
3989
+ function buildPrintContent$1(el, options) {
3957
3990
  let styles = "";
3958
3991
  document.querySelectorAll('style, link[rel="stylesheet"]').forEach((styleEl) => {
3959
3992
  if (styleEl.tagName === "STYLE") {
@@ -3994,7 +4027,7 @@ function buildPrintContent(el, options) {
3994
4027
  </body>
3995
4028
  </html>`;
3996
4029
  }
3997
- function waitForImages(doc) {
4030
+ function waitForImages$1(doc) {
3998
4031
  const images = doc.querySelectorAll("img");
3999
4032
  const promises = [];
4000
4033
  images.forEach((img) => {
@@ -4087,16 +4120,16 @@ function triggerRefresh(internal) {
4087
4120
  try {
4088
4121
  yield internal.options.handler();
4089
4122
  setState(internal, "success");
4090
- yield sleep(internal.options.successDuration);
4123
+ yield sleep$1(internal.options.successDuration);
4091
4124
  } catch (e) {
4092
4125
  setState(internal, "error");
4093
- yield sleep(internal.options.errorDuration);
4126
+ yield sleep$1(internal.options.errorDuration);
4094
4127
  } finally {
4095
4128
  resetPosition(internal);
4096
4129
  }
4097
4130
  });
4098
4131
  }
4099
- function sleep(ms) {
4132
+ function sleep$1(ms) {
4100
4133
  return new Promise((resolve) => setTimeout(resolve, ms));
4101
4134
  }
4102
4135
  function createHandlers(internal) {
@@ -4822,8 +4855,8 @@ const vSticky = defineDirective({
4822
4855
  });
4823
4856
  const DEFAULT_THRESHOLD = 30;
4824
4857
  const DEFAULT_MAX_TIME = 500;
4825
- const DEFAULT_DIRECTIONS = ["left", "right", "up", "down"];
4826
- function getSwipeDirection(deltaX, deltaY, allowedDirections) {
4858
+ const DEFAULT_DIRECTIONS$1 = ["left", "right", "up", "down"];
4859
+ function getSwipeDirection$1(deltaX, deltaY, allowedDirections) {
4827
4860
  const absX = Math.abs(deltaX);
4828
4861
  const absY = Math.abs(deltaY);
4829
4862
  if (absX > absY) {
@@ -4841,7 +4874,7 @@ function normalizeOptions$9(binding) {
4841
4874
  handler: binding.handler,
4842
4875
  threshold: (_a = binding.threshold) != null ? _a : DEFAULT_THRESHOLD,
4843
4876
  maxTime: (_b = binding.maxTime) != null ? _b : DEFAULT_MAX_TIME,
4844
- directions: (_c = binding.directions) != null ? _c : [...DEFAULT_DIRECTIONS],
4877
+ directions: (_c = binding.directions) != null ? _c : [...DEFAULT_DIRECTIONS$1],
4845
4878
  preventScrollOnSwipe: (_d = binding.preventScrollOnSwipe) != null ? _d : true,
4846
4879
  disabled: (_e = binding.disabled) != null ? _e : false,
4847
4880
  mouse: (_f = binding.mouse) != null ? _f : true,
@@ -4857,7 +4890,7 @@ function triggerSwipe(state, deltaX, deltaY, deltaTime, event, el) {
4857
4890
  if (deltaTime > ((_a = options.maxTime) != null ? _a : DEFAULT_MAX_TIME)) return;
4858
4891
  const distance = Math.max(Math.abs(deltaX), Math.abs(deltaY));
4859
4892
  if (distance < ((_b = options.threshold) != null ? _b : DEFAULT_THRESHOLD)) return;
4860
- const direction = getSwipeDirection(deltaX, deltaY, (_c = options.directions) != null ? _c : DEFAULT_DIRECTIONS);
4893
+ const direction = getSwipeDirection$1(deltaX, deltaY, (_c = options.directions) != null ? _c : DEFAULT_DIRECTIONS$1);
4861
4894
  if (!direction) return;
4862
4895
  if (options.preventScrollOnSwipe && event.cancelable) {
4863
4896
  event.preventDefault();
@@ -5346,7 +5379,7 @@ const vTooltip = defineDirective({
5346
5379
  delete el.__tooltip;
5347
5380
  }
5348
5381
  });
5349
- const getDistance = (x1, y1, x2, y2) => Math.sqrt(__pow(x2 - x1, 2) + __pow(y2 - y1, 2));
5382
+ const getDistance$1 = (x1, y1, x2, y2) => Math.sqrt(__pow(x2 - x1, 2) + __pow(y2 - y1, 2));
5350
5383
  const getAngle = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
5351
5384
  const MOUSE_IGNORE_DURATION = 400;
5352
5385
  const vTouch = defineDirective({
@@ -5424,7 +5457,7 @@ const vTouch = defineDirective({
5424
5457
  } else if (e.touches.length === 2) {
5425
5458
  clearLongPressTimer();
5426
5459
  const [t1, t2] = e.touches;
5427
- state.startDistance = getDistance(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5460
+ state.startDistance = getDistance$1(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5428
5461
  state.startAngle = getAngle(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5429
5462
  state.lastScale = 1;
5430
5463
  state.lastAngle = 0;
@@ -5441,7 +5474,7 @@ const vTouch = defineDirective({
5441
5474
  }
5442
5475
  if (e.touches.length === 2) {
5443
5476
  const [t1, t2] = e.touches;
5444
- const currentDistance = getDistance(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5477
+ const currentDistance = getDistance$1(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5445
5478
  const currentAngle = getAngle(t1.clientX, t1.clientY, t2.clientX, t2.clientY);
5446
5479
  if (state.options.enablePinch && state.options.onPinch) {
5447
5480
  const scale = currentDistance / state.startDistance;
@@ -5560,9 +5593,9 @@ function normalizeOptions$6(binding) {
5560
5593
  onTouchEnd: binding == null ? void 0 : binding.onTouchEnd
5561
5594
  };
5562
5595
  }
5563
- function trimText(text, options) {
5596
+ function trimText$1(text, options) {
5564
5597
  const { position = "both", chars } = options;
5565
- const charPattern = chars ? `[\\s${escapeRegex(chars)}]` : "\\s";
5598
+ const charPattern = chars ? `[\\s${escapeRegex$2(chars)}]` : "\\s";
5566
5599
  switch (position) {
5567
5600
  case "start":
5568
5601
  return text.replace(new RegExp(`^${charPattern}+`, "g"), "");
@@ -5573,7 +5606,7 @@ function trimText(text, options) {
5573
5606
  return text.replace(new RegExp(`^${charPattern}+|${charPattern}+$`, "g"), "");
5574
5607
  }
5575
5608
  }
5576
- function escapeRegex(str) {
5609
+ function escapeRegex$2(str) {
5577
5610
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5578
5611
  }
5579
5612
  const vTrim = defineDirective({
@@ -5585,7 +5618,7 @@ const vTrim = defineDirective({
5585
5618
  setupInputElement(el, options);
5586
5619
  } else {
5587
5620
  const text = el.textContent || "";
5588
- el.textContent = trimText(text, options);
5621
+ el.textContent = trimText$1(text, options);
5589
5622
  }
5590
5623
  },
5591
5624
  updated(el, binding) {
@@ -5597,7 +5630,7 @@ const vTrim = defineDirective({
5597
5630
  }
5598
5631
  } else {
5599
5632
  const text = el.textContent || "";
5600
- el.textContent = trimText(text, options);
5633
+ el.textContent = trimText$1(text, options);
5601
5634
  }
5602
5635
  },
5603
5636
  unmounted(el) {
@@ -5616,7 +5649,7 @@ function setupInputElement(el, options) {
5616
5649
  el.__trim = state;
5617
5650
  const performTrim = () => {
5618
5651
  const originalValue = el.value;
5619
- const trimmed = trimText(originalValue, options);
5652
+ const trimmed = trimText$1(originalValue, options);
5620
5653
  if (originalValue !== trimmed) {
5621
5654
  el.value = trimmed;
5622
5655
  el.dispatchEvent(new Event("input", { bubbles: true }));
@@ -5665,7 +5698,7 @@ function normalizeOptions$5(binding) {
5665
5698
  chars: binding.chars
5666
5699
  };
5667
5700
  }
5668
- function truncateText(text, options) {
5701
+ function truncateText$1(text, options) {
5669
5702
  const { length = 100, position = "end", ellipsis = "..." } = options;
5670
5703
  if (text.length <= length) {
5671
5704
  return text;
@@ -5728,7 +5761,7 @@ function applyTruncation(el, text, options) {
5728
5761
  el.setAttribute("title", text);
5729
5762
  }
5730
5763
  } else {
5731
- const truncated = truncateText(text, options);
5764
+ const truncated = truncateText$1(text, options);
5732
5765
  el.textContent = truncated;
5733
5766
  if (showTitle && text && text !== truncated) {
5734
5767
  el.setAttribute("title", text);
@@ -6114,7 +6147,7 @@ function applyVisibility(el, state, isVisible) {
6114
6147
  state.options.handler(isVisible);
6115
6148
  }
6116
6149
  }
6117
- function createWatermarkCanvas(options) {
6150
+ function createWatermarkCanvas$1(options) {
6118
6151
  var _a;
6119
6152
  const canvas = document.createElement("canvas");
6120
6153
  const ctx = canvas.getContext("2d");
@@ -6230,7 +6263,7 @@ const vWatermark = defineDirective({
6230
6263
  });
6231
6264
  function applyWatermark(el, state) {
6232
6265
  const options = state.options;
6233
- state.canvas = createWatermarkCanvas(options);
6266
+ state.canvas = createWatermarkCanvas$1(options);
6234
6267
  state.watermarkEl = createWatermarkElement(state.canvas, options);
6235
6268
  el.appendChild(state.watermarkEl);
6236
6269
  if (options.protect) {
@@ -6253,7 +6286,7 @@ function setupProtection(el, state) {
6253
6286
  state.observer = new MutationObserver((mutations) => {
6254
6287
  if (!state.watermarkEl || !el.contains(state.watermarkEl)) {
6255
6288
  if (!state.options.disabled) {
6256
- state.canvas = createWatermarkCanvas(state.options);
6289
+ state.canvas = createWatermarkCanvas$1(state.options);
6257
6290
  state.watermarkEl = createWatermarkElement(state.canvas, state.options);
6258
6291
  el.appendChild(state.watermarkEl);
6259
6292
  }
@@ -6278,6 +6311,2988 @@ function setupProtection(el, state) {
6278
6311
  attributeFilter: ["style", "class", "hidden"]
6279
6312
  });
6280
6313
  }
6314
+ const DEFAULT_KEEP_LOWER = [
6315
+ "a",
6316
+ "an",
6317
+ "the",
6318
+ "and",
6319
+ "but",
6320
+ "or",
6321
+ "for",
6322
+ "nor",
6323
+ "on",
6324
+ "at",
6325
+ "to",
6326
+ "from",
6327
+ "by",
6328
+ "in",
6329
+ "of",
6330
+ "with",
6331
+ "as"
6332
+ ];
6333
+ function capitalizeWord(word) {
6334
+ if (!word) return word;
6335
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
6336
+ }
6337
+ function capitalizeText(text, options = {}) {
6338
+ if (!text) return text;
6339
+ const { every = true, keepLower = DEFAULT_KEEP_LOWER } = options;
6340
+ if (every) {
6341
+ const words = text.toLowerCase().split(/\s+/);
6342
+ return words.map((word, index) => {
6343
+ if (index === 0) {
6344
+ return capitalizeWord(word);
6345
+ }
6346
+ if (keepLower.includes(word.toLowerCase())) {
6347
+ return word.toLowerCase();
6348
+ }
6349
+ return capitalizeWord(word);
6350
+ }).join(" ");
6351
+ } else {
6352
+ return capitalizeWord(text);
6353
+ }
6354
+ }
6355
+ function useCapitalcase(options) {
6356
+ const {
6357
+ text,
6358
+ every = true,
6359
+ keepLower = DEFAULT_KEEP_LOWER
6360
+ } = options;
6361
+ const original = ref(unref(text));
6362
+ const capitalized = ref("");
6363
+ function calculate() {
6364
+ const textValue = unref(text);
6365
+ const everyValue = unref(every);
6366
+ const keepLowerValue = unref(keepLower);
6367
+ original.value = textValue;
6368
+ capitalized.value = capitalizeText(textValue, {
6369
+ every: everyValue,
6370
+ keepLower: keepLowerValue
6371
+ });
6372
+ }
6373
+ watch(
6374
+ () => [unref(text), unref(every), unref(keepLower)],
6375
+ () => calculate(),
6376
+ { immediate: true }
6377
+ );
6378
+ return {
6379
+ capitalized,
6380
+ original
6381
+ };
6382
+ }
6383
+ function createCapitalizer(options = {}) {
6384
+ return (text) => capitalizeText(text, options);
6385
+ }
6386
+ function useClickDelay(options) {
6387
+ const {
6388
+ handler,
6389
+ delay = 300,
6390
+ disabled = false
6391
+ } = options;
6392
+ const isPending = ref(false);
6393
+ let timeoutId = null;
6394
+ const getDelay = () => unref(delay);
6395
+ const getDisabled = () => unref(disabled);
6396
+ function click(event) {
6397
+ if (getDisabled() || isPending.value) {
6398
+ event.preventDefault();
6399
+ event.stopPropagation();
6400
+ return;
6401
+ }
6402
+ isPending.value = true;
6403
+ handler(event);
6404
+ timeoutId = setTimeout(() => {
6405
+ isPending.value = false;
6406
+ timeoutId = null;
6407
+ }, getDelay());
6408
+ }
6409
+ function reset() {
6410
+ if (timeoutId) {
6411
+ clearTimeout(timeoutId);
6412
+ timeoutId = null;
6413
+ }
6414
+ isPending.value = false;
6415
+ }
6416
+ function cancel() {
6417
+ if (timeoutId) {
6418
+ clearTimeout(timeoutId);
6419
+ timeoutId = null;
6420
+ }
6421
+ }
6422
+ onUnmounted(() => {
6423
+ cancel();
6424
+ });
6425
+ return {
6426
+ isPending,
6427
+ click,
6428
+ reset,
6429
+ cancel
6430
+ };
6431
+ }
6432
+ function createDelayedClick(handler, delay = 300) {
6433
+ let isPending = false;
6434
+ return (event) => {
6435
+ if (isPending) {
6436
+ event.preventDefault();
6437
+ event.stopPropagation();
6438
+ return;
6439
+ }
6440
+ isPending = true;
6441
+ handler(event);
6442
+ setTimeout(() => {
6443
+ isPending = false;
6444
+ }, delay);
6445
+ };
6446
+ }
6447
+ function isValidClick(el, event, exclude) {
6448
+ const target = event.target;
6449
+ if (el.contains(target)) {
6450
+ return false;
6451
+ }
6452
+ if (exclude == null ? void 0 : exclude.length) {
6453
+ for (const item of exclude) {
6454
+ const excludeEl = typeof item === "function" ? item() : unref(item);
6455
+ const resolved = typeof excludeEl === "string" ? getElement(excludeEl) : excludeEl;
6456
+ if (resolved && (resolved === target || resolved.contains(target))) {
6457
+ return false;
6458
+ }
6459
+ }
6460
+ }
6461
+ return true;
6462
+ }
6463
+ function useClickOutside(options) {
6464
+ const {
6465
+ handler,
6466
+ exclude = [],
6467
+ capture = true,
6468
+ events = ["click"],
6469
+ stop = false,
6470
+ prevent = false
6471
+ } = options;
6472
+ let currentElement = null;
6473
+ const handlers = /* @__PURE__ */ new Map();
6474
+ function createEventHandler(_eventType) {
6475
+ return (event) => {
6476
+ if (!currentElement) return;
6477
+ if (!isValidClick(currentElement, event, exclude)) {
6478
+ return;
6479
+ }
6480
+ if (stop) {
6481
+ event.stopPropagation();
6482
+ }
6483
+ if (prevent) {
6484
+ event.preventDefault();
6485
+ }
6486
+ handler(event);
6487
+ };
6488
+ }
6489
+ function bind(element) {
6490
+ if (!isBrowser()) return () => {
6491
+ };
6492
+ unbind();
6493
+ currentElement = element;
6494
+ events.forEach((eventType) => {
6495
+ const eventHandler = createEventHandler();
6496
+ handlers.set(eventType, eventHandler);
6497
+ document.addEventListener(eventType, eventHandler, {
6498
+ capture,
6499
+ passive: !prevent
6500
+ });
6501
+ });
6502
+ return unbind;
6503
+ }
6504
+ function unbind() {
6505
+ handlers.forEach((eventHandler, eventType) => {
6506
+ document.removeEventListener(eventType, eventHandler, { capture });
6507
+ });
6508
+ handlers.clear();
6509
+ currentElement = null;
6510
+ }
6511
+ onUnmounted(() => {
6512
+ unbind();
6513
+ });
6514
+ return {
6515
+ bind
6516
+ };
6517
+ }
6518
+ function copyToClipboard(text) {
6519
+ return __async(this, null, function* () {
6520
+ if (supportsClipboard()) {
6521
+ try {
6522
+ yield navigator.clipboard.writeText(text);
6523
+ return true;
6524
+ } catch (e) {
6525
+ console.warn("[Directix] Clipboard API failed, falling back to execCommand");
6526
+ }
6527
+ }
6528
+ return copyWithExecCommand(text);
6529
+ });
6530
+ }
6531
+ function copyWithExecCommand(text) {
6532
+ if (!isBrowser()) return false;
6533
+ const textarea = document.createElement("textarea");
6534
+ textarea.value = text;
6535
+ textarea.style.cssText = `
6536
+ position: fixed;
6537
+ top: -9999px;
6538
+ left: -9999px;
6539
+ opacity: 0;
6540
+ pointer-events: none;
6541
+ `;
6542
+ document.body.appendChild(textarea);
6543
+ try {
6544
+ textarea.select();
6545
+ textarea.setSelectionRange(0, textarea.value.length);
6546
+ return document.execCommand("copy");
6547
+ } catch (e) {
6548
+ return false;
6549
+ } finally {
6550
+ document.body.removeChild(textarea);
6551
+ }
6552
+ }
6553
+ function useCopy(options = {}) {
6554
+ const {
6555
+ source,
6556
+ onSuccess,
6557
+ onError,
6558
+ copiedTimeout = 1500
6559
+ } = options;
6560
+ const copied = ref(false);
6561
+ const error = ref(null);
6562
+ const isSupported = supportsClipboard() || isBrowser();
6563
+ let timeoutId = null;
6564
+ function copy(text) {
6565
+ return __async(this, null, function* () {
6566
+ const value = text != null ? text : unref(source);
6567
+ if (!value) {
6568
+ console.warn("[Directix] useCopy: No text to copy");
6569
+ return false;
6570
+ }
6571
+ if (timeoutId) {
6572
+ clearTimeout(timeoutId);
6573
+ timeoutId = null;
6574
+ }
6575
+ error.value = null;
6576
+ try {
6577
+ const success = yield copyToClipboard(value);
6578
+ if (success) {
6579
+ copied.value = true;
6580
+ onSuccess == null ? void 0 : onSuccess(value);
6581
+ timeoutId = setTimeout(() => {
6582
+ copied.value = false;
6583
+ timeoutId = null;
6584
+ }, copiedTimeout);
6585
+ return true;
6586
+ } else {
6587
+ throw new Error("Copy failed");
6588
+ }
6589
+ } catch (err) {
6590
+ const copyError = err;
6591
+ error.value = copyError;
6592
+ copied.value = false;
6593
+ onError == null ? void 0 : onError(copyError);
6594
+ return false;
6595
+ }
6596
+ });
6597
+ }
6598
+ return {
6599
+ copy,
6600
+ copied: readonly(copied),
6601
+ error: readonly(error),
6602
+ isSupported
6603
+ };
6604
+ }
6605
+ function parseTargetTime(target) {
6606
+ if (target instanceof Date) {
6607
+ return target.getTime();
6608
+ }
6609
+ if (typeof target === "number") {
6610
+ return target;
6611
+ }
6612
+ return new Date(target).getTime();
6613
+ }
6614
+ function calculateTime(remaining) {
6615
+ const total = Math.max(0, remaining);
6616
+ return {
6617
+ days: Math.floor(total / (1e3 * 60 * 60 * 24)),
6618
+ hours: Math.floor(total % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60)),
6619
+ minutes: Math.floor(total % (1e3 * 60 * 60) / (1e3 * 60)),
6620
+ seconds: Math.floor(total % (1e3 * 60) / 1e3),
6621
+ milliseconds: total % 1e3,
6622
+ total
6623
+ };
6624
+ }
6625
+ function formatTime(time, format) {
6626
+ if (typeof format === "function") {
6627
+ return format(time);
6628
+ }
6629
+ const pad = (n, len = 2) => String(n).padStart(len, "0");
6630
+ const result = format.replace(/dd/gi, pad(time.days)).replace(/hh/gi, pad(time.hours)).replace(/mm/gi, pad(time.minutes)).replace(/ss/gi, pad(time.seconds)).replace(/S{3}/gi, pad(time.milliseconds, 3)).replace(/SS/gi, pad(Math.floor(time.milliseconds / 10))).replace(/S/gi, String(Math.floor(time.milliseconds / 100)));
6631
+ return result;
6632
+ }
6633
+ function useCountdown(options) {
6634
+ const {
6635
+ target,
6636
+ format = "hh:mm:ss",
6637
+ onComplete,
6638
+ onTick,
6639
+ interval = 1e3,
6640
+ autoStart = true
6641
+ } = options;
6642
+ const time = ref(calculateTime(0));
6643
+ const formatted = ref("");
6644
+ const running = ref(false);
6645
+ const paused = ref(false);
6646
+ const completed = ref(false);
6647
+ let intervalId = null, targetTime = 0, remainingWhenPaused = 0;
6648
+ const getInterval = () => unref(interval);
6649
+ const getFormat = () => unref(format);
6650
+ function update() {
6651
+ const now = Date.now();
6652
+ const remaining = targetTime - now;
6653
+ if (remaining <= 0) {
6654
+ time.value = calculateTime(0);
6655
+ formatted.value = formatTime(time.value, getFormat());
6656
+ completed.value = true;
6657
+ running.value = false;
6658
+ stop();
6659
+ if (onComplete) {
6660
+ onComplete();
6661
+ }
6662
+ return;
6663
+ }
6664
+ time.value = calculateTime(remaining);
6665
+ formatted.value = formatTime(time.value, getFormat());
6666
+ if (onTick) {
6667
+ onTick(time.value);
6668
+ }
6669
+ }
6670
+ function start() {
6671
+ if (running.value) return;
6672
+ targetTime = parseTargetTime(unref(target));
6673
+ running.value = true;
6674
+ paused.value = false;
6675
+ completed.value = false;
6676
+ update();
6677
+ intervalId = setInterval(update, getInterval());
6678
+ }
6679
+ function stop() {
6680
+ if (intervalId) {
6681
+ clearInterval(intervalId);
6682
+ intervalId = null;
6683
+ }
6684
+ running.value = false;
6685
+ }
6686
+ function pause() {
6687
+ if (!running.value) return;
6688
+ remainingWhenPaused = targetTime - Date.now();
6689
+ stop();
6690
+ paused.value = true;
6691
+ }
6692
+ function resume() {
6693
+ if (running.value || !paused.value) return;
6694
+ targetTime = Date.now() + remainingWhenPaused;
6695
+ running.value = true;
6696
+ paused.value = false;
6697
+ update();
6698
+ intervalId = setInterval(update, getInterval());
6699
+ }
6700
+ function reset() {
6701
+ stop();
6702
+ paused.value = false;
6703
+ completed.value = false;
6704
+ remainingWhenPaused = 0;
6705
+ time.value = calculateTime(0);
6706
+ formatted.value = formatTime(time.value, getFormat());
6707
+ }
6708
+ watch(
6709
+ () => unref(target),
6710
+ (newTarget) => {
6711
+ if (running.value) {
6712
+ targetTime = parseTargetTime(newTarget);
6713
+ }
6714
+ }
6715
+ );
6716
+ if (unref(autoStart)) {
6717
+ start();
6718
+ }
6719
+ onUnmounted(() => {
6720
+ stop();
6721
+ });
6722
+ return {
6723
+ time,
6724
+ formatted,
6725
+ running,
6726
+ paused,
6727
+ completed,
6728
+ start,
6729
+ pause,
6730
+ resume,
6731
+ reset
6732
+ };
6733
+ }
6734
+ function useDebounce(options) {
6735
+ const {
6736
+ handler,
6737
+ wait = 300,
6738
+ leading = false,
6739
+ trailing = true
6740
+ } = options;
6741
+ let timerId = null, lastArgs = null, lastThis = null;
6742
+ const invokeFunc = () => {
6743
+ if (lastArgs) {
6744
+ handler.apply(lastThis, lastArgs);
6745
+ lastArgs = null;
6746
+ lastThis = null;
6747
+ }
6748
+ };
6749
+ const getWait = () => unref(wait);
6750
+ const getLeading = () => unref(leading);
6751
+ const getTrailing = () => unref(trailing);
6752
+ function run(...args) {
6753
+ lastArgs = args;
6754
+ lastThis = this;
6755
+ if (timerId) {
6756
+ clearTimeout(timerId);
6757
+ }
6758
+ if (getLeading() && !timerId) {
6759
+ invokeFunc();
6760
+ }
6761
+ timerId = setTimeout(() => {
6762
+ if (getTrailing()) {
6763
+ invokeFunc();
6764
+ }
6765
+ timerId = null;
6766
+ }, getWait());
6767
+ }
6768
+ function cancel() {
6769
+ if (timerId) {
6770
+ clearTimeout(timerId);
6771
+ timerId = null;
6772
+ }
6773
+ lastArgs = null;
6774
+ lastThis = null;
6775
+ }
6776
+ function flush() {
6777
+ if (timerId) {
6778
+ clearTimeout(timerId);
6779
+ invokeFunc();
6780
+ timerId = null;
6781
+ }
6782
+ }
6783
+ function pending() {
6784
+ return timerId !== null;
6785
+ }
6786
+ onUnmounted(() => {
6787
+ cancel();
6788
+ });
6789
+ return {
6790
+ run,
6791
+ cancel,
6792
+ flush,
6793
+ pending
6794
+ };
6795
+ }
6796
+ function debounceFn(fn, wait = 300, options) {
6797
+ return debounce(fn, wait, options);
6798
+ }
6799
+ function getBoundary(boundary) {
6800
+ var _a, _b;
6801
+ if (!boundary) return null;
6802
+ if (typeof boundary === "function") {
6803
+ const boundaryEl = boundary();
6804
+ return (_a = boundaryEl == null ? void 0 : boundaryEl.getBoundingClientRect()) != null ? _a : null;
6805
+ }
6806
+ if (typeof boundary === "string") {
6807
+ const boundaryEl = document.querySelector(boundary);
6808
+ return (_b = boundaryEl == null ? void 0 : boundaryEl.getBoundingClientRect()) != null ? _b : null;
6809
+ }
6810
+ return boundary.getBoundingClientRect();
6811
+ }
6812
+ function getClientCoords(e) {
6813
+ if (e.type.startsWith("touch")) {
6814
+ const touch = e.touches[0] || e.changedTouches[0];
6815
+ return { clientX: touch.clientX, clientY: touch.clientY };
6816
+ }
6817
+ const mouseEvent = e;
6818
+ return { clientX: mouseEvent.clientX, clientY: mouseEvent.clientY };
6819
+ }
6820
+ function parseTranslate(transform) {
6821
+ const match = transform.match(/translate\(([-\d.]+)px,\s*([-\d.]+)px\)/);
6822
+ if (match) {
6823
+ return { x: parseFloat(match[1]), y: parseFloat(match[2]) };
6824
+ }
6825
+ return { x: 0, y: 0 };
6826
+ }
6827
+ function useDraggable(options = {}) {
6828
+ const {
6829
+ axis = "both",
6830
+ constrain = false,
6831
+ boundary,
6832
+ handle,
6833
+ grid,
6834
+ disabled = false,
6835
+ onStart,
6836
+ onDrag,
6837
+ onEnd
6838
+ } = options;
6839
+ const position = ref({ x: 0, y: 0 });
6840
+ const isDragging = ref(false);
6841
+ let currentElement = null, handleEl = null, startX = 0, startY = 0, offsetX = 0, offsetY = 0, initialLeft = 0, initialTop = 0, boundaryWidth = 0, boundaryHeight = 0, elWidth = 0, elHeight = 0;
6842
+ function startDrag(e) {
6843
+ var _a;
6844
+ if (unref(disabled)) return;
6845
+ e.preventDefault();
6846
+ const { clientX, clientY } = getClientCoords(e);
6847
+ isDragging.value = true;
6848
+ startX = clientX;
6849
+ startY = clientY;
6850
+ const { x, y } = parseTranslate(currentElement.style.transform);
6851
+ offsetX = x;
6852
+ offsetY = y;
6853
+ if (unref(constrain) || boundary) {
6854
+ const boundaryRect = boundary ? getBoundary(boundary) : (_a = currentElement.parentElement) == null ? void 0 : _a.getBoundingClientRect();
6855
+ if (boundaryRect) {
6856
+ const elRect = currentElement.getBoundingClientRect();
6857
+ initialLeft = elRect.left - boundaryRect.left;
6858
+ initialTop = elRect.top - boundaryRect.top;
6859
+ boundaryWidth = boundaryRect.width;
6860
+ boundaryHeight = boundaryRect.height;
6861
+ elWidth = elRect.width;
6862
+ elHeight = elRect.height;
6863
+ }
6864
+ }
6865
+ currentElement.classList.add("v-draggable--dragging");
6866
+ document.addEventListener("mousemove", handleDrag);
6867
+ document.addEventListener("mouseup", endDrag);
6868
+ document.addEventListener("touchmove", handleDrag, { passive: false });
6869
+ document.addEventListener("touchend", endDrag);
6870
+ onStart == null ? void 0 : onStart({ x: offsetX, y: offsetY }, e);
6871
+ }
6872
+ function handleDrag(e) {
6873
+ if (!isDragging.value || unref(disabled)) return;
6874
+ e.preventDefault();
6875
+ const { clientX, clientY } = getClientCoords(e);
6876
+ let deltaX = clientX - startX, deltaY = clientY - startY, newX = offsetX + deltaX, newY = offsetY + deltaY;
6877
+ const currentAxis = unref(axis);
6878
+ if (currentAxis === "x") {
6879
+ deltaY = 0;
6880
+ } else if (currentAxis === "y") {
6881
+ deltaX = 0;
6882
+ }
6883
+ const currentGrid = unref(grid);
6884
+ if (currentGrid) {
6885
+ deltaX = Math.round(deltaX / currentGrid[0]) * currentGrid[0];
6886
+ deltaY = Math.round(deltaY / currentGrid[1]) * currentGrid[1];
6887
+ }
6888
+ if (unref(constrain) || boundary) {
6889
+ const newLeft = initialLeft + deltaX;
6890
+ const newTop = initialTop + deltaY;
6891
+ const maxLeft = boundaryWidth - elWidth;
6892
+ const maxTop = boundaryHeight - elHeight;
6893
+ const constrainedLeft = Math.max(0, Math.min(newLeft, maxLeft));
6894
+ const constrainedTop = Math.max(0, Math.min(newTop, maxTop));
6895
+ newX = offsetX + (constrainedLeft - initialLeft);
6896
+ newY = offsetY + (constrainedTop - initialTop);
6897
+ }
6898
+ currentElement.style.transform = `translate(${newX}px, ${newY}px)`;
6899
+ position.value = { x: newX, y: newY };
6900
+ onDrag == null ? void 0 : onDrag({ x: newX, y: newY }, e);
6901
+ }
6902
+ function endDrag(e) {
6903
+ if (!isDragging.value) return;
6904
+ isDragging.value = false;
6905
+ currentElement == null ? void 0 : currentElement.classList.remove("v-draggable--dragging");
6906
+ document.removeEventListener("mousemove", handleDrag);
6907
+ document.removeEventListener("mouseup", endDrag);
6908
+ document.removeEventListener("touchmove", handleDrag);
6909
+ document.removeEventListener("touchend", endDrag);
6910
+ onEnd == null ? void 0 : onEnd(__spreadValues({}, position.value), e);
6911
+ }
6912
+ function reset() {
6913
+ if (currentElement) {
6914
+ currentElement.style.transform = "translate(0px, 0px)";
6915
+ position.value = { x: 0, y: 0 };
6916
+ }
6917
+ }
6918
+ function bind(element) {
6919
+ if (!isBrowser()) return () => {
6920
+ };
6921
+ unbind();
6922
+ currentElement = element;
6923
+ if (getComputedStyle(element).position === "static") {
6924
+ element.style.position = "absolute";
6925
+ }
6926
+ handleEl = handle ? element.querySelector(handle) : null;
6927
+ const target = handleEl || element;
6928
+ target.addEventListener("mousedown", startDrag);
6929
+ target.addEventListener("touchstart", startDrag, { passive: false });
6930
+ return unbind;
6931
+ }
6932
+ function unbind() {
6933
+ if (currentElement) {
6934
+ const target = handleEl || currentElement;
6935
+ target.removeEventListener("mousedown", startDrag);
6936
+ target.removeEventListener("touchstart", startDrag);
6937
+ }
6938
+ currentElement = null;
6939
+ handleEl = null;
6940
+ }
6941
+ onUnmounted(() => {
6942
+ unbind();
6943
+ });
6944
+ return {
6945
+ position: readonly(position),
6946
+ isDragging: readonly(isDragging),
6947
+ reset,
6948
+ bind
6949
+ };
6950
+ }
6951
+ function measureTextWidth(text, fontSize = 14, fontFamily = "sans-serif") {
6952
+ if (typeof document === "undefined") return text.length * 8;
6953
+ const canvas = document.createElement("canvas");
6954
+ const ctx = canvas.getContext("2d");
6955
+ if (!ctx) return text.length * 8;
6956
+ ctx.font = `${fontSize}px ${fontFamily}`;
6957
+ return ctx.measureText(text).width;
6958
+ }
6959
+ function truncateToWidth(text, maxWidth, ellipsis = "...", fontSize = 14, fontFamily = "sans-serif") {
6960
+ if (maxWidth <= 0) return text;
6961
+ const textWidth = measureTextWidth(text, fontSize, fontFamily);
6962
+ if (textWidth <= maxWidth) return text;
6963
+ const ellipsisWidth = measureTextWidth(ellipsis, fontSize, fontFamily);
6964
+ const availableWidth = maxWidth - ellipsisWidth;
6965
+ if (availableWidth <= 0) return ellipsis;
6966
+ let low = 0, high = text.length;
6967
+ while (low < high) {
6968
+ const mid = Math.floor((low + high + 1) / 2);
6969
+ const truncatedText = text.slice(0, mid);
6970
+ const truncatedWidth = measureTextWidth(truncatedText, fontSize, fontFamily);
6971
+ if (truncatedWidth <= availableWidth) {
6972
+ low = mid;
6973
+ } else {
6974
+ high = mid - 1;
6975
+ }
6976
+ }
6977
+ return text.slice(0, low) + ellipsis;
6978
+ }
6979
+ function truncateToLines(text, lines, ellipsis = "...") {
6980
+ if (lines <= 0) return "";
6981
+ const avgCharsPerLine = 80;
6982
+ const maxChars = lines * avgCharsPerLine;
6983
+ if (text.length <= maxChars) return text;
6984
+ return text.slice(0, maxChars - ellipsis.length) + ellipsis;
6985
+ }
6986
+ function useEllipsis(options) {
6987
+ const {
6988
+ text,
6989
+ lines = 1,
6990
+ ellipsis = "...",
6991
+ maxWidth = 0
6992
+ } = options;
6993
+ const original = ref(unref(text));
6994
+ const truncated = ref("");
6995
+ const isTruncated = ref(false);
6996
+ function calculate() {
6997
+ const textValue = unref(text);
6998
+ const linesValue = unref(lines);
6999
+ const ellipsisValue = unref(ellipsis);
7000
+ const maxWidthValue = unref(maxWidth);
7001
+ original.value = textValue;
7002
+ if (!textValue) {
7003
+ truncated.value = "";
7004
+ isTruncated.value = false;
7005
+ return;
7006
+ }
7007
+ if (maxWidthValue > 0) {
7008
+ const result = truncateToWidth(textValue, maxWidthValue, ellipsisValue);
7009
+ truncated.value = result;
7010
+ isTruncated.value = result !== textValue;
7011
+ } else if (linesValue > 1) {
7012
+ const result = truncateToLines(textValue, linesValue, ellipsisValue);
7013
+ truncated.value = result;
7014
+ isTruncated.value = result !== textValue;
7015
+ } else {
7016
+ truncated.value = textValue;
7017
+ isTruncated.value = false;
7018
+ }
7019
+ }
7020
+ function calculateForWidth(width) {
7021
+ const textValue = unref(text);
7022
+ const ellipsisValue = unref(ellipsis);
7023
+ if (!textValue || width <= 0) return textValue || "";
7024
+ return truncateToWidth(textValue, width, ellipsisValue);
7025
+ }
7026
+ function wouldTruncate(width) {
7027
+ const textValue = unref(text);
7028
+ if (!textValue || width <= 0) return false;
7029
+ const textWidth = measureTextWidth(textValue);
7030
+ return textWidth > width;
7031
+ }
7032
+ watch(
7033
+ () => [unref(text), unref(lines), unref(ellipsis), unref(maxWidth)],
7034
+ () => calculate(),
7035
+ { immediate: true }
7036
+ );
7037
+ onUnmounted(() => {
7038
+ });
7039
+ return {
7040
+ truncated,
7041
+ isTruncated,
7042
+ original,
7043
+ calculateForWidth,
7044
+ wouldTruncate
7045
+ };
7046
+ }
7047
+ function truncateText(text, maxLength, ellipsis = "...") {
7048
+ if (!text || text.length <= maxLength) return text;
7049
+ return text.slice(0, maxLength - ellipsis.length) + ellipsis;
7050
+ }
7051
+ function wouldTextTruncate(text, containerWidth, fontSize = 14) {
7052
+ return measureTextWidth(text, fontSize) > containerWidth;
7053
+ }
7054
+ const FOCUSABLE_TAGS = /* @__PURE__ */ new Set(["input", "textarea", "select", "button"]);
7055
+ function isFocusable(el) {
7056
+ if (!isBrowser()) return false;
7057
+ const tagName = el.tagName.toLowerCase();
7058
+ if (FOCUSABLE_TAGS.has(tagName)) {
7059
+ return !el.disabled;
7060
+ }
7061
+ if (el.isContentEditable) return true;
7062
+ const tabindex = el.getAttribute("tabindex");
7063
+ if (tabindex != null) return tabindex !== "-1";
7064
+ if (tagName === "a" || tagName === "area") {
7065
+ return el.hasAttribute("href");
7066
+ }
7067
+ return false;
7068
+ }
7069
+ function useFocus(options = {}) {
7070
+ const { onFocus, onBlur } = options;
7071
+ const isFocused = ref(false);
7072
+ let currentElement = null, focusHandler = null, blurHandler = null;
7073
+ function focus() {
7074
+ if (currentElement && isFocusable(currentElement)) {
7075
+ currentElement.focus();
7076
+ }
7077
+ }
7078
+ function blur() {
7079
+ if (currentElement) {
7080
+ currentElement.blur();
7081
+ }
7082
+ }
7083
+ function bind(element) {
7084
+ if (!isBrowser()) return () => {
7085
+ };
7086
+ unbind();
7087
+ currentElement = element;
7088
+ focusHandler = (e) => {
7089
+ isFocused.value = true;
7090
+ onFocus == null ? void 0 : onFocus(e);
7091
+ };
7092
+ blurHandler = (e) => {
7093
+ isFocused.value = false;
7094
+ onBlur == null ? void 0 : onBlur(e);
7095
+ };
7096
+ element.addEventListener("focus", focusHandler);
7097
+ element.addEventListener("blur", blurHandler);
7098
+ isFocused.value = document.activeElement === element;
7099
+ return unbind;
7100
+ }
7101
+ function unbind() {
7102
+ if (currentElement) {
7103
+ if (focusHandler) {
7104
+ currentElement.removeEventListener("focus", focusHandler);
7105
+ }
7106
+ if (blurHandler) {
7107
+ currentElement.removeEventListener("blur", blurHandler);
7108
+ }
7109
+ }
7110
+ currentElement = null;
7111
+ focusHandler = null;
7112
+ blurHandler = null;
7113
+ isFocused.value = false;
7114
+ }
7115
+ onUnmounted(() => {
7116
+ unbind();
7117
+ });
7118
+ return {
7119
+ isFocused: readonly(isFocused),
7120
+ focus,
7121
+ blur,
7122
+ bind
7123
+ };
7124
+ }
7125
+ const KEY_ALIASES = {
7126
+ esc: "Escape",
7127
+ space: " ",
7128
+ up: "ArrowUp",
7129
+ down: "ArrowDown",
7130
+ left: "ArrowLeft",
7131
+ right: "ArrowRight",
7132
+ enter: "Enter",
7133
+ tab: "Tab",
7134
+ backspace: "Backspace",
7135
+ delete: "Delete",
7136
+ insert: "Insert",
7137
+ home: "Home",
7138
+ end: "End",
7139
+ pageup: "PageUp",
7140
+ pagedown: "PageDown",
7141
+ plus: "+",
7142
+ minus: "-"
7143
+ };
7144
+ const MODIFIERS = /* @__PURE__ */ new Set(["ctrl", "alt", "shift", "meta"]);
7145
+ function parseHotkey(hotkey) {
7146
+ const parts = hotkey.toLowerCase().split("+").map((p) => p.trim());
7147
+ const modifiers = /* @__PURE__ */ new Set();
7148
+ let key = "";
7149
+ for (const part of parts) {
7150
+ if (MODIFIERS.has(part)) {
7151
+ modifiers.add(part);
7152
+ } else {
7153
+ key = KEY_ALIASES[part] || part;
7154
+ }
7155
+ }
7156
+ return { key, modifiers };
7157
+ }
7158
+ function matchesHotkey(event, definition) {
7159
+ if (definition.modifiers.has("ctrl") !== (event.ctrlKey || event.metaKey)) return false;
7160
+ if (definition.modifiers.has("alt") !== event.altKey) return false;
7161
+ if (definition.modifiers.has("shift") !== event.shiftKey) return false;
7162
+ if (definition.modifiers.has("meta") !== event.metaKey) return false;
7163
+ const eventKey = event.key;
7164
+ const targetKey = definition.key;
7165
+ return eventKey.toLowerCase() === targetKey.toLowerCase();
7166
+ }
7167
+ function useHotkey(options = {}) {
7168
+ const {
7169
+ hotkey,
7170
+ hotkeys = [],
7171
+ target,
7172
+ enabled: initialEnabled = true
7173
+ } = options;
7174
+ const enabled = ref(unref(initialEnabled));
7175
+ const hotkeyMap = /* @__PURE__ */ new Map();
7176
+ let currentTarget = null, keydownHandler = null, keyupHandler = null;
7177
+ if (hotkey) {
7178
+ addHotkey(hotkey);
7179
+ }
7180
+ hotkeys.forEach(addHotkey);
7181
+ function addHotkey(def) {
7182
+ const parsed = parseHotkey(def.key);
7183
+ const key = parsed.key.toLowerCase();
7184
+ if (!hotkeyMap.has(key)) {
7185
+ hotkeyMap.set(key, []);
7186
+ }
7187
+ hotkeyMap.get(key).push(def);
7188
+ }
7189
+ function removeHotkey(key) {
7190
+ hotkeyMap.delete(key.toLowerCase());
7191
+ }
7192
+ function clearHotkeys() {
7193
+ hotkeyMap.clear();
7194
+ }
7195
+ function handleKeyEvent(event, isKeyup) {
7196
+ if (!enabled.value) return;
7197
+ const key = event.key.toLowerCase();
7198
+ const definitions = hotkeyMap.get(key);
7199
+ if (!definitions) return;
7200
+ for (const def of definitions) {
7201
+ if (unref(def.disabled)) continue;
7202
+ if (!!def.keyup !== isKeyup) continue;
7203
+ const parsed = parseHotkey(def.key);
7204
+ if (matchesHotkey(event, parsed)) {
7205
+ if (def.prevent !== false) {
7206
+ event.preventDefault();
7207
+ }
7208
+ if (def.stop) {
7209
+ event.stopPropagation();
7210
+ }
7211
+ def.handler(event);
7212
+ break;
7213
+ }
7214
+ }
7215
+ }
7216
+ function bind() {
7217
+ if (!isBrowser()) return;
7218
+ unbind();
7219
+ currentTarget = target ? unref(target) : document;
7220
+ keydownHandler = (e) => handleKeyEvent(e, false);
7221
+ keyupHandler = (e) => handleKeyEvent(e, true);
7222
+ currentTarget == null ? void 0 : currentTarget.addEventListener("keydown", keydownHandler);
7223
+ currentTarget == null ? void 0 : currentTarget.addEventListener("keyup", keyupHandler);
7224
+ }
7225
+ function unbind() {
7226
+ if (currentTarget) {
7227
+ if (keydownHandler) {
7228
+ currentTarget.removeEventListener("keydown", keydownHandler);
7229
+ }
7230
+ if (keyupHandler) {
7231
+ currentTarget.removeEventListener("keyup", keyupHandler);
7232
+ }
7233
+ }
7234
+ currentTarget = null;
7235
+ keydownHandler = null;
7236
+ keyupHandler = null;
7237
+ }
7238
+ function enable() {
7239
+ enabled.value = true;
7240
+ }
7241
+ function disable() {
7242
+ enabled.value = false;
7243
+ }
7244
+ function toggle() {
7245
+ enabled.value = !enabled.value;
7246
+ }
7247
+ watch(enabled, (newEnabled) => {
7248
+ if (newEnabled) {
7249
+ bind();
7250
+ } else {
7251
+ unbind();
7252
+ }
7253
+ });
7254
+ if (target && typeof target === "object" && "value" in target) {
7255
+ watch(target, () => {
7256
+ if (enabled.value) {
7257
+ bind();
7258
+ }
7259
+ });
7260
+ }
7261
+ if (enabled.value) {
7262
+ bind();
7263
+ }
7264
+ onUnmounted(() => {
7265
+ unbind();
7266
+ });
7267
+ return {
7268
+ enabled,
7269
+ enable,
7270
+ disable,
7271
+ toggle,
7272
+ add: addHotkey,
7273
+ remove: removeHotkey,
7274
+ clear: clearHotkeys
7275
+ };
7276
+ }
7277
+ function useHover(options = {}) {
7278
+ const {
7279
+ onEnter,
7280
+ onLeave,
7281
+ class: hoverClass,
7282
+ enterDelay = 0,
7283
+ leaveDelay = 0
7284
+ } = options;
7285
+ const isHovering = ref(false);
7286
+ let enterTimerId = null, leaveTimerId = null, currentElement = null;
7287
+ function clearTimers() {
7288
+ if (enterTimerId) {
7289
+ clearTimeout(enterTimerId);
7290
+ enterTimerId = null;
7291
+ }
7292
+ if (leaveTimerId) {
7293
+ clearTimeout(leaveTimerId);
7294
+ leaveTimerId = null;
7295
+ }
7296
+ }
7297
+ function handleMouseEnter(event) {
7298
+ if (leaveTimerId) {
7299
+ clearTimeout(leaveTimerId);
7300
+ leaveTimerId = null;
7301
+ }
7302
+ if (isHovering.value) return;
7303
+ const delay = unref(enterDelay);
7304
+ if (delay && delay > 0) {
7305
+ enterTimerId = setTimeout(() => {
7306
+ isHovering.value = true;
7307
+ applyHoverState2();
7308
+ onEnter == null ? void 0 : onEnter(event);
7309
+ enterTimerId = null;
7310
+ }, delay);
7311
+ } else {
7312
+ isHovering.value = true;
7313
+ applyHoverState2();
7314
+ onEnter == null ? void 0 : onEnter(event);
7315
+ }
7316
+ }
7317
+ function handleMouseLeave(event) {
7318
+ if (enterTimerId) {
7319
+ clearTimeout(enterTimerId);
7320
+ enterTimerId = null;
7321
+ }
7322
+ if (!isHovering.value) return;
7323
+ const delay = unref(leaveDelay);
7324
+ if (delay && delay > 0) {
7325
+ leaveTimerId = setTimeout(() => {
7326
+ isHovering.value = false;
7327
+ removeHoverState();
7328
+ onLeave == null ? void 0 : onLeave(event);
7329
+ leaveTimerId = null;
7330
+ }, delay);
7331
+ } else {
7332
+ isHovering.value = false;
7333
+ removeHoverState();
7334
+ onLeave == null ? void 0 : onLeave(event);
7335
+ }
7336
+ }
7337
+ function applyHoverState2() {
7338
+ if (currentElement && hoverClass) {
7339
+ currentElement.classList.add(hoverClass);
7340
+ }
7341
+ }
7342
+ function removeHoverState() {
7343
+ if (currentElement && hoverClass) {
7344
+ currentElement.classList.remove(hoverClass);
7345
+ }
7346
+ }
7347
+ function bind(element) {
7348
+ if (!isBrowser()) return () => {
7349
+ };
7350
+ currentElement = element;
7351
+ element.addEventListener("mouseenter", handleMouseEnter);
7352
+ element.addEventListener("mouseleave", handleMouseLeave);
7353
+ return () => {
7354
+ element.removeEventListener("mouseenter", handleMouseEnter);
7355
+ element.removeEventListener("mouseleave", handleMouseLeave);
7356
+ clearTimers();
7357
+ removeHoverState();
7358
+ currentElement = null;
7359
+ };
7360
+ }
7361
+ onUnmounted(() => {
7362
+ clearTimers();
7363
+ removeHoverState();
7364
+ });
7365
+ return {
7366
+ isHovering,
7367
+ bind
7368
+ };
7369
+ }
7370
+ function useImagePreview(options = {}) {
7371
+ const {
7372
+ src: initialSrc,
7373
+ closeOnClickOutside = true,
7374
+ closeOnEsc = true,
7375
+ showCloseButton = true,
7376
+ onOpen,
7377
+ onClose
7378
+ } = options;
7379
+ const isOpen = ref(false);
7380
+ const currentSrc = ref("");
7381
+ let currentElement = null, overlay = null, clickHandler = null, keydownHandler = null;
7382
+ function createOverlay2() {
7383
+ const div = document.createElement("div");
7384
+ div.className = "v-image-preview";
7385
+ div.style.cssText = `
7386
+ position: fixed;
7387
+ top: 0;
7388
+ left: 0;
7389
+ right: 0;
7390
+ bottom: 0;
7391
+ z-index: 9999;
7392
+ background: rgba(0, 0, 0, 0.9);
7393
+ display: flex;
7394
+ align-items: center;
7395
+ justify-content: center;
7396
+ cursor: zoom-out;
7397
+ `;
7398
+ return div;
7399
+ }
7400
+ function open(src) {
7401
+ if (!isBrowser()) return;
7402
+ const imageSrc = src || (initialSrc && typeof initialSrc === "object" ? initialSrc.value : initialSrc);
7403
+ if (!imageSrc && !currentElement) return;
7404
+ const finalSrc = imageSrc || currentElement.src;
7405
+ currentSrc.value = finalSrc;
7406
+ overlay = createOverlay2();
7407
+ const img = document.createElement("img");
7408
+ img.src = finalSrc;
7409
+ img.style.cssText = `
7410
+ max-width: 90%;
7411
+ max-height: 90%;
7412
+ object-fit: contain;
7413
+ cursor: default;
7414
+ `;
7415
+ if (showCloseButton) {
7416
+ const closeBtn = document.createElement("button");
7417
+ closeBtn.className = "v-image-preview__close";
7418
+ closeBtn.innerHTML = "&times;";
7419
+ closeBtn.style.cssText = `
7420
+ position: absolute;
7421
+ top: 20px;
7422
+ right: 20px;
7423
+ width: 40px;
7424
+ height: 40px;
7425
+ border: none;
7426
+ background: rgba(255, 255, 255, 0.2);
7427
+ color: white;
7428
+ font-size: 24px;
7429
+ cursor: pointer;
7430
+ border-radius: 50%;
7431
+ display: flex;
7432
+ align-items: center;
7433
+ justify-content: center;
7434
+ `;
7435
+ closeBtn.addEventListener("click", (e) => {
7436
+ e.stopPropagation();
7437
+ close();
7438
+ });
7439
+ overlay.appendChild(closeBtn);
7440
+ }
7441
+ overlay.appendChild(img);
7442
+ document.body.appendChild(overlay);
7443
+ if (closeOnClickOutside) {
7444
+ clickHandler = close;
7445
+ overlay.addEventListener("click", clickHandler);
7446
+ }
7447
+ if (closeOnEsc) {
7448
+ keydownHandler = (e) => {
7449
+ if (e.key === "Escape") {
7450
+ close();
7451
+ }
7452
+ };
7453
+ document.addEventListener("keydown", keydownHandler);
7454
+ }
7455
+ isOpen.value = true;
7456
+ onOpen == null ? void 0 : onOpen();
7457
+ }
7458
+ function close() {
7459
+ if (overlay) {
7460
+ overlay.remove();
7461
+ overlay = null;
7462
+ }
7463
+ if (clickHandler) {
7464
+ document.removeEventListener("click", clickHandler);
7465
+ clickHandler = null;
7466
+ }
7467
+ if (keydownHandler) {
7468
+ document.removeEventListener("keydown", keydownHandler);
7469
+ keydownHandler = null;
7470
+ }
7471
+ isOpen.value = false;
7472
+ currentSrc.value = "";
7473
+ onClose == null ? void 0 : onClose();
7474
+ }
7475
+ function handleElementClick() {
7476
+ if (currentElement) {
7477
+ open(currentElement.src);
7478
+ }
7479
+ }
7480
+ function bind(element) {
7481
+ if (!isBrowser()) return () => {
7482
+ };
7483
+ unbind();
7484
+ currentElement = element;
7485
+ element.style.cursor = "zoom-in";
7486
+ element.addEventListener("click", handleElementClick);
7487
+ return unbind;
7488
+ }
7489
+ function unbind() {
7490
+ if (currentElement) {
7491
+ currentElement.style.cursor = "";
7492
+ currentElement.removeEventListener("click", handleElementClick);
7493
+ }
7494
+ currentElement = null;
7495
+ }
7496
+ onUnmounted(() => {
7497
+ unbind();
7498
+ close();
7499
+ });
7500
+ return {
7501
+ isOpen: readonly(isOpen),
7502
+ currentSrc: readonly(currentSrc),
7503
+ open,
7504
+ close,
7505
+ bind
7506
+ };
7507
+ }
7508
+ function useIntersect(options = {}) {
7509
+ const {
7510
+ handler,
7511
+ onEnter,
7512
+ onLeave,
7513
+ onChange,
7514
+ root = null,
7515
+ rootMargin = "0px",
7516
+ threshold = 0,
7517
+ once = false
7518
+ } = options;
7519
+ const isIntersecting = ref(false);
7520
+ const ratio = ref(0);
7521
+ let observer = null, hasTriggeredOnce = false;
7522
+ function createObserver2() {
7523
+ if (!isBrowser() || !supportsIntersectionObserver()) {
7524
+ console.warn("[Directix] useIntersect: IntersectionObserver not supported");
7525
+ return null;
7526
+ }
7527
+ return new IntersectionObserver(
7528
+ (entries) => {
7529
+ for (const entry of entries) {
7530
+ if (once && hasTriggeredOnce) continue;
7531
+ const intersecting = entry.isIntersecting;
7532
+ isIntersecting.value = intersecting;
7533
+ ratio.value = entry.intersectionRatio;
7534
+ handler == null ? void 0 : handler(entry, observer);
7535
+ onChange == null ? void 0 : onChange(intersecting, entry);
7536
+ if (intersecting) {
7537
+ onEnter == null ? void 0 : onEnter(entry, observer);
7538
+ if (once) hasTriggeredOnce = true;
7539
+ } else {
7540
+ onLeave == null ? void 0 : onLeave(entry, observer);
7541
+ }
7542
+ }
7543
+ },
7544
+ {
7545
+ root: unref(root),
7546
+ rootMargin,
7547
+ threshold
7548
+ }
7549
+ );
7550
+ }
7551
+ function bind(element) {
7552
+ if (!isBrowser()) return () => {
7553
+ };
7554
+ stop();
7555
+ observer = createObserver2();
7556
+ if (observer) {
7557
+ observer.observe(element);
7558
+ }
7559
+ return stop;
7560
+ }
7561
+ function stop() {
7562
+ if (observer) {
7563
+ observer.disconnect();
7564
+ observer = null;
7565
+ }
7566
+ isIntersecting.value = false;
7567
+ ratio.value = 0;
7568
+ }
7569
+ onUnmounted(() => {
7570
+ stop();
7571
+ });
7572
+ return {
7573
+ isIntersecting: readonly(isIntersecting),
7574
+ ratio: readonly(ratio),
7575
+ bind,
7576
+ stop
7577
+ };
7578
+ }
7579
+ function getEventPosition(e) {
7580
+ if ("touches" in e && e.touches.length > 0) {
7581
+ return {
7582
+ x: e.touches[0].clientX,
7583
+ y: e.touches[0].clientY
7584
+ };
7585
+ }
7586
+ if ("clientX" in e) {
7587
+ return {
7588
+ x: e.clientX,
7589
+ y: e.clientY
7590
+ };
7591
+ }
7592
+ return { x: 0, y: 0 };
7593
+ }
7594
+ function getDistance(p1, p2) {
7595
+ return Math.sqrt(__pow(p2.x - p1.x, 2) + __pow(p2.y - p1.y, 2));
7596
+ }
7597
+ function useLongPress(options = {}) {
7598
+ const {
7599
+ duration = 500,
7600
+ distance = 10,
7601
+ onStart,
7602
+ onTrigger,
7603
+ onCancel,
7604
+ onTick,
7605
+ tickInterval = 100,
7606
+ prevent = true
7607
+ } = options;
7608
+ const isPressing = ref(false);
7609
+ let timerId = null, tickTimerId = null, startPos = { x: 0, y: 0 }, startPosSet = false;
7610
+ function start(event) {
7611
+ if (!isBrowser()) return;
7612
+ if (prevent) {
7613
+ event.preventDefault();
7614
+ }
7615
+ clearTimers();
7616
+ startPos = getEventPosition(event);
7617
+ startPosSet = true;
7618
+ isPressing.value = true;
7619
+ onStart == null ? void 0 : onStart(event);
7620
+ if (onTick) {
7621
+ let remaining = unref(duration);
7622
+ tickTimerId = setInterval(() => {
7623
+ remaining -= tickInterval;
7624
+ onTick == null ? void 0 : onTick(Math.max(0, remaining));
7625
+ }, tickInterval);
7626
+ }
7627
+ timerId = setTimeout(() => {
7628
+ clearTimers();
7629
+ isPressing.value = false;
7630
+ onTrigger == null ? void 0 : onTrigger(event);
7631
+ }, unref(duration));
7632
+ }
7633
+ function stop(event) {
7634
+ if (!isPressing.value) return;
7635
+ clearTimers();
7636
+ startPosSet = false;
7637
+ isPressing.value = false;
7638
+ onCancel == null ? void 0 : onCancel(event);
7639
+ }
7640
+ function handleMove(event) {
7641
+ if (!isPressing.value || !startPosSet) return;
7642
+ const pos = getEventPosition(event);
7643
+ const dist = getDistance(startPos, pos);
7644
+ if (dist > unref(distance)) {
7645
+ stop(event);
7646
+ }
7647
+ }
7648
+ function clearTimers() {
7649
+ if (timerId) {
7650
+ clearTimeout(timerId);
7651
+ timerId = null;
7652
+ }
7653
+ if (tickTimerId) {
7654
+ clearInterval(tickTimerId);
7655
+ tickTimerId = null;
7656
+ }
7657
+ }
7658
+ function bind(element) {
7659
+ element.addEventListener("mousedown", start);
7660
+ element.addEventListener("mouseup", stop);
7661
+ element.addEventListener("mouseleave", stop);
7662
+ element.addEventListener("mousemove", handleMove);
7663
+ element.addEventListener("touchstart", start, { passive: !prevent });
7664
+ element.addEventListener("touchend", stop);
7665
+ element.addEventListener("touchcancel", stop);
7666
+ element.addEventListener("touchmove", handleMove, { passive: true });
7667
+ return () => {
7668
+ element.removeEventListener("mousedown", start);
7669
+ element.removeEventListener("mouseup", stop);
7670
+ element.removeEventListener("mouseleave", stop);
7671
+ element.removeEventListener("mousemove", handleMove);
7672
+ element.removeEventListener("touchstart", start);
7673
+ element.removeEventListener("touchend", stop);
7674
+ element.removeEventListener("touchcancel", stop);
7675
+ element.removeEventListener("touchmove", handleMove);
7676
+ clearTimers();
7677
+ };
7678
+ }
7679
+ onUnmounted(() => {
7680
+ clearTimers();
7681
+ });
7682
+ return {
7683
+ isPressing,
7684
+ start,
7685
+ stop,
7686
+ bind
7687
+ };
7688
+ }
7689
+ function lowercaseText(text, firstOnly = false) {
7690
+ if (!text) return text;
7691
+ if (firstOnly) {
7692
+ return text.charAt(0).toLowerCase() + text.slice(1);
7693
+ }
7694
+ return text.toLowerCase();
7695
+ }
7696
+ function useLowercase(options) {
7697
+ const {
7698
+ text,
7699
+ first = false
7700
+ } = options;
7701
+ const original = ref(unref(text));
7702
+ const transformed = ref("");
7703
+ function calculate() {
7704
+ const textValue = unref(text);
7705
+ const firstValue = unref(first);
7706
+ original.value = textValue;
7707
+ transformed.value = lowercaseText(textValue, firstValue);
7708
+ }
7709
+ watch(
7710
+ () => [unref(text), unref(first)],
7711
+ () => calculate(),
7712
+ { immediate: true }
7713
+ );
7714
+ return {
7715
+ transformed,
7716
+ original
7717
+ };
7718
+ }
7719
+ function createLowercaser(first = false) {
7720
+ return (text) => lowercaseText(text, first);
7721
+ }
7722
+ function formatMoney(value, options = {}) {
7723
+ const {
7724
+ precision = 2,
7725
+ separator = ",",
7726
+ decimal = ".",
7727
+ symbol = "$",
7728
+ symbolPosition = "before"
7729
+ } = options;
7730
+ const fixed = value.toFixed(precision);
7731
+ const [intPart, decPart] = fixed.split(".");
7732
+ const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
7733
+ let result = formattedInt;
7734
+ if (precision > 0 && decPart) {
7735
+ result += decimal + decPart;
7736
+ }
7737
+ return symbolPosition === "before" ? symbol + result : result + symbol;
7738
+ }
7739
+ function parseMoney(formatted, options = {}) {
7740
+ const { decimal = ".", symbol = "$" } = options;
7741
+ let cleaned = formatted.replace(new RegExp(`[${symbol}\\s]`, "g"), "");
7742
+ if (decimal !== ".") {
7743
+ cleaned = cleaned.replace(/,/g, "");
7744
+ cleaned = cleaned.replace(new RegExp(`\\${decimal}`, "g"), ".");
7745
+ } else {
7746
+ cleaned = cleaned.replace(/,/g, "");
7747
+ }
7748
+ return parseFloat(cleaned) || 0;
7749
+ }
7750
+ function useMoney(options) {
7751
+ const {
7752
+ value,
7753
+ symbol = "$",
7754
+ symbolPosition = "before",
7755
+ precision = 2,
7756
+ separator = ",",
7757
+ decimal = "."
7758
+ } = options;
7759
+ const valueRef = ref(unref(value));
7760
+ function getFormatOptions() {
7761
+ return {
7762
+ precision: unref(precision),
7763
+ separator: unref(separator),
7764
+ decimal: unref(decimal),
7765
+ symbol: unref(symbol),
7766
+ symbolPosition: unref(symbolPosition)
7767
+ };
7768
+ }
7769
+ const formatted = computed(() => {
7770
+ return formatMoney(valueRef.value, getFormatOptions());
7771
+ });
7772
+ function parse(formattedString) {
7773
+ return parseMoney(formattedString, {
7774
+ decimal: unref(decimal),
7775
+ symbol: unref(symbol)
7776
+ });
7777
+ }
7778
+ watch(
7779
+ () => unref(value),
7780
+ (newValue) => {
7781
+ valueRef.value = newValue;
7782
+ }
7783
+ );
7784
+ return {
7785
+ value: valueRef,
7786
+ formatted,
7787
+ parse
7788
+ };
7789
+ }
7790
+ function createMoneyFormatter(options = {}) {
7791
+ return (value) => formatMoney(value, options);
7792
+ }
7793
+ function formatNumber(value, options = {}) {
7794
+ const {
7795
+ precision = 0,
7796
+ separator = ",",
7797
+ decimal = ".",
7798
+ prefix = "",
7799
+ suffix = ""
7800
+ } = options;
7801
+ const fixed = value.toFixed(precision);
7802
+ const [intPart, decPart] = fixed.split(".");
7803
+ const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
7804
+ let result = formattedInt;
7805
+ if (precision > 0 && decPart) {
7806
+ result += decimal + decPart;
7807
+ }
7808
+ return prefix + result + suffix;
7809
+ }
7810
+ function parseNumber(formatted, options = {}) {
7811
+ const { decimal = ".", prefix = "", suffix = "" } = options;
7812
+ let cleaned = formatted.replace(new RegExp(`^${escapeRegex$1(prefix)}`), "").replace(new RegExp(`${escapeRegex$1(suffix)}$`), "").replace(/\s/g, "");
7813
+ if (decimal !== ".") {
7814
+ cleaned = cleaned.replace(/,/g, "");
7815
+ cleaned = cleaned.replace(new RegExp(`\\${decimal}`, "g"), ".");
7816
+ } else {
7817
+ cleaned = cleaned.replace(/,/g, "");
7818
+ }
7819
+ return parseFloat(cleaned) || 0;
7820
+ }
7821
+ function escapeRegex$1(str) {
7822
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7823
+ }
7824
+ function useNumber(options) {
7825
+ const {
7826
+ value,
7827
+ precision = 0,
7828
+ separator = ",",
7829
+ decimal = ".",
7830
+ prefix = "",
7831
+ suffix = ""
7832
+ } = options;
7833
+ const valueRef = ref(unref(value));
7834
+ function getFormatOptions() {
7835
+ return {
7836
+ precision: unref(precision),
7837
+ separator: unref(separator),
7838
+ decimal: unref(decimal),
7839
+ prefix: unref(prefix),
7840
+ suffix: unref(suffix)
7841
+ };
7842
+ }
7843
+ const formatted = computed(() => {
7844
+ return formatNumber(valueRef.value, getFormatOptions());
7845
+ });
7846
+ function parse(formattedString) {
7847
+ return parseNumber(formattedString, {
7848
+ decimal: unref(decimal),
7849
+ prefix: unref(prefix),
7850
+ suffix: unref(suffix)
7851
+ });
7852
+ }
7853
+ watch(
7854
+ () => unref(value),
7855
+ (newValue) => {
7856
+ valueRef.value = newValue;
7857
+ }
7858
+ );
7859
+ return {
7860
+ value: valueRef,
7861
+ formatted,
7862
+ parse
7863
+ };
7864
+ }
7865
+ function createNumberFormatter(options = {}) {
7866
+ return (value) => formatNumber(value, options);
7867
+ }
7868
+ const WILDCARD = "*";
7869
+ function hasPermission(required, permissions) {
7870
+ return permissions.includes(WILDCARD) || permissions.includes(required);
7871
+ }
7872
+ function usePermission(options) {
7873
+ const {
7874
+ value,
7875
+ mode = "some",
7876
+ check,
7877
+ getPermissions,
7878
+ getRoles,
7879
+ roleMap = {}
7880
+ } = options;
7881
+ const granted = ref(false);
7882
+ function verifyPermission2() {
7883
+ if (check) {
7884
+ return check(unref(value), unref(mode));
7885
+ }
7886
+ if (!getPermissions) {
7887
+ console.warn("[Directix] usePermission: getPermissions function is required");
7888
+ return true;
7889
+ }
7890
+ const permissions = getPermissions();
7891
+ const roles = (getRoles == null ? void 0 : getRoles()) || [];
7892
+ const required = Array.isArray(unref(value)) ? unref(value) : [unref(value)];
7893
+ const currentMode = unref(mode);
7894
+ function checkSingle(perm) {
7895
+ if (perm in roleMap) {
7896
+ return roles.includes(perm);
7897
+ }
7898
+ if (hasPermission(perm, permissions)) {
7899
+ return true;
7900
+ }
7901
+ for (const role of roles) {
7902
+ const rolePermissions = roleMap[role] || [];
7903
+ if (hasPermission(perm, rolePermissions)) {
7904
+ return true;
7905
+ }
7906
+ }
7907
+ return false;
7908
+ }
7909
+ return currentMode === "every" ? required.every(checkSingle) : required.some(checkSingle);
7910
+ }
7911
+ function recheck() {
7912
+ granted.value = verifyPermission2();
7913
+ }
7914
+ watch(
7915
+ () => unref(value),
7916
+ () => recheck(),
7917
+ { immediate: true }
7918
+ );
7919
+ if (typeof mode === "object" && "value" in mode) {
7920
+ watch(mode, () => recheck());
7921
+ }
7922
+ return {
7923
+ granted: readonly(granted),
7924
+ recheck
7925
+ };
7926
+ }
7927
+ function createPermissionChecker(config) {
7928
+ const { getPermissions, getRoles, roleMap = {} } = config;
7929
+ return (value, mode = "some") => {
7930
+ const permissions = getPermissions();
7931
+ const roles = (getRoles == null ? void 0 : getRoles()) || [];
7932
+ const required = Array.isArray(value) ? value : [value];
7933
+ function checkSingle(perm) {
7934
+ if (perm in roleMap) {
7935
+ return roles.includes(perm);
7936
+ }
7937
+ if (hasPermission(perm, permissions)) {
7938
+ return true;
7939
+ }
7940
+ for (const role of roles) {
7941
+ const rolePermissions = roleMap[role] || [];
7942
+ if (hasPermission(perm, rolePermissions)) {
7943
+ return true;
7944
+ }
7945
+ }
7946
+ return false;
7947
+ }
7948
+ return mode === "every" ? required.every(checkSingle) : required.some(checkSingle);
7949
+ };
7950
+ }
7951
+ function waitForImages(doc) {
7952
+ const images = doc.querySelectorAll("img");
7953
+ const promises = [];
7954
+ images.forEach((img) => {
7955
+ if (!img.complete) {
7956
+ promises.push(
7957
+ new Promise((resolve) => {
7958
+ img.onload = () => resolve();
7959
+ img.onerror = () => resolve();
7960
+ })
7961
+ );
7962
+ }
7963
+ });
7964
+ return Promise.all(promises);
7965
+ }
7966
+ function buildPrintContent(el, options) {
7967
+ let styles = "";
7968
+ if (typeof document !== "undefined") {
7969
+ document.querySelectorAll('style, link[rel="stylesheet"]').forEach((styleEl) => {
7970
+ if (styleEl.tagName === "STYLE") {
7971
+ styles += `<style>${styleEl.textContent}</style>`;
7972
+ } else if (styleEl.tagName === "LINK") {
7973
+ const href = styleEl.href;
7974
+ styles += `<link rel="stylesheet" href="${href}">`;
7975
+ }
7976
+ });
7977
+ }
7978
+ options.cssUrls.forEach((url) => {
7979
+ styles += `<link rel="stylesheet" href="${url}">`;
7980
+ });
7981
+ if (options.styles) {
7982
+ styles += `<style>${options.styles}</style>`;
7983
+ }
7984
+ styles += `
7985
+ <style>
7986
+ @media print {
7987
+ body { margin: 0; padding: 20px; }
7988
+ ${options.printClass ? `.${options.printClass} { page-break-inside: avoid; }` : ""}
7989
+ }
7990
+ </style>
7991
+ `;
7992
+ const title = options.title || (typeof document !== "undefined" ? document.title : "Print");
7993
+ const content = el.outerHTML;
7994
+ return `<!DOCTYPE html>
7995
+ <html>
7996
+ <head>
7997
+ <meta charset="utf-8">
7998
+ <title>${title}</title>
7999
+ ${styles}
8000
+ </head>
8001
+ <body>
8002
+ ${content}
8003
+ </body>
8004
+ </html>`;
8005
+ }
8006
+ function printInIframe(el, options) {
8007
+ return __async(this, null, function* () {
8008
+ var _a, _b, _c;
8009
+ const iframe = document.createElement("iframe");
8010
+ iframe.style.cssText = "position: absolute; top: -10000px; left: -10000px; width: 0; height: 0; border: none;";
8011
+ document.body.appendChild(iframe);
8012
+ const iframeDoc = iframe.contentDocument || ((_a = iframe.contentWindow) == null ? void 0 : _a.document);
8013
+ if (!iframeDoc) {
8014
+ console.warn("[Directix] usePrint: Could not access iframe document");
8015
+ document.body.removeChild(iframe);
8016
+ return;
8017
+ }
8018
+ const content = buildPrintContent(el, options);
8019
+ iframeDoc.open();
8020
+ iframeDoc.write(content);
8021
+ iframeDoc.close();
8022
+ yield waitForImages(iframeDoc);
8023
+ try {
8024
+ (_b = iframe.contentWindow) == null ? void 0 : _b.focus();
8025
+ (_c = iframe.contentWindow) == null ? void 0 : _c.print();
8026
+ } catch (err) {
8027
+ console.error("[Directix] usePrint: Print failed", err);
8028
+ }
8029
+ setTimeout(() => {
8030
+ document.body.removeChild(iframe);
8031
+ }, 1e3);
8032
+ });
8033
+ }
8034
+ function printInNewWindow(el, options) {
8035
+ return __async(this, null, function* () {
8036
+ const printWindow = window.open("", "_blank");
8037
+ if (!printWindow) {
8038
+ console.warn("[Directix] usePrint: Could not open print window");
8039
+ return;
8040
+ }
8041
+ const content = buildPrintContent(el, options);
8042
+ printWindow.document.open();
8043
+ printWindow.document.write(content);
8044
+ printWindow.document.close();
8045
+ yield waitForImages(printWindow.document);
8046
+ printWindow.focus();
8047
+ printWindow.print();
8048
+ setTimeout(() => {
8049
+ printWindow.close();
8050
+ }, 1e3);
8051
+ });
8052
+ }
8053
+ function usePrint(options = {}) {
8054
+ const {
8055
+ title,
8056
+ styles,
8057
+ cssUrls = [],
8058
+ onBeforePrint,
8059
+ onAfterPrint,
8060
+ newWindow = false,
8061
+ printClass
8062
+ } = options;
8063
+ const isPrinting = ref(false);
8064
+ function print(target) {
8065
+ return __async(this, null, function* () {
8066
+ if (onBeforePrint) {
8067
+ const result = onBeforePrint();
8068
+ if (result === false) return;
8069
+ }
8070
+ isPrinting.value = true;
8071
+ try {
8072
+ let targetEl = null;
8073
+ if (typeof target === "string") {
8074
+ targetEl = document.querySelector(target);
8075
+ } else if (target instanceof HTMLElement) {
8076
+ targetEl = target;
8077
+ } else {
8078
+ targetEl = document.body;
8079
+ }
8080
+ if (!targetEl) {
8081
+ console.warn("[Directix] usePrint: Target element not found");
8082
+ return;
8083
+ }
8084
+ const printOptions = {
8085
+ title: unref(title) || "",
8086
+ styles: Array.isArray(unref(styles)) ? unref(styles).join("\n") : unref(styles) || "",
8087
+ cssUrls: unref(cssUrls) || [],
8088
+ printClass: unref(printClass)
8089
+ };
8090
+ if (unref(newWindow)) {
8091
+ yield printInNewWindow(targetEl, printOptions);
8092
+ } else {
8093
+ yield printInIframe(targetEl, printOptions);
8094
+ }
8095
+ if (onAfterPrint) {
8096
+ onAfterPrint();
8097
+ }
8098
+ } finally {
8099
+ isPrinting.value = false;
8100
+ }
8101
+ });
8102
+ }
8103
+ function printPage() {
8104
+ return __async(this, null, function* () {
8105
+ yield print();
8106
+ });
8107
+ }
8108
+ onUnmounted(() => {
8109
+ });
8110
+ return {
8111
+ isPrinting,
8112
+ print,
8113
+ printPage
8114
+ };
8115
+ }
8116
+ function quickPrint(_0) {
8117
+ return __async(this, arguments, function* (target, options = {}) {
8118
+ const { print } = usePrint(options);
8119
+ yield print(target);
8120
+ });
8121
+ }
8122
+ function sleep(ms) {
8123
+ return new Promise((resolve) => setTimeout(resolve, ms));
8124
+ }
8125
+ function usePullRefresh(options) {
8126
+ const {
8127
+ handler,
8128
+ distance = 60,
8129
+ maxDistance = 100,
8130
+ disabled = false,
8131
+ successDuration = 500,
8132
+ errorDuration = 1e3
8133
+ } = options;
8134
+ const state = ref("idle");
8135
+ const distanceValue = ref(0);
8136
+ const isPulling = ref(false);
8137
+ const containerRef = ref(null);
8138
+ let startY = 0, currentY = 0;
8139
+ const getDistance2 = () => unref(distance);
8140
+ const getMaxDistance = () => unref(maxDistance);
8141
+ const getDisabled = () => unref(disabled);
8142
+ const getSuccessDuration = () => unref(successDuration);
8143
+ const getErrorDuration = () => unref(errorDuration);
8144
+ function reset() {
8145
+ state.value = "idle";
8146
+ distanceValue.value = 0;
8147
+ isPulling.value = false;
8148
+ }
8149
+ function refresh() {
8150
+ return __async(this, null, function* () {
8151
+ state.value = "loading";
8152
+ try {
8153
+ yield handler();
8154
+ state.value = "success";
8155
+ yield sleep(getSuccessDuration());
8156
+ } catch (e) {
8157
+ state.value = "error";
8158
+ yield sleep(getErrorDuration());
8159
+ } finally {
8160
+ reset();
8161
+ }
8162
+ });
8163
+ }
8164
+ function touchstart(e) {
8165
+ if (getDisabled() || state.value === "loading") return;
8166
+ const container = containerRef.value;
8167
+ if (container && container.scrollTop > 0) return;
8168
+ isPulling.value = true;
8169
+ startY = e.touches[0].clientY;
8170
+ currentY = startY;
8171
+ state.value = "idle";
8172
+ }
8173
+ function touchmove(e) {
8174
+ if (!isPulling.value || getDisabled() || state.value === "loading") return;
8175
+ currentY = e.touches[0].clientY;
8176
+ const diff = currentY - startY;
8177
+ if (diff <= 0) {
8178
+ distanceValue.value = 0;
8179
+ state.value = "idle";
8180
+ return;
8181
+ }
8182
+ e.preventDefault();
8183
+ const calculatedDistance = Math.min(diff * 0.5, getMaxDistance());
8184
+ distanceValue.value = calculatedDistance;
8185
+ const progress = calculatedDistance / getDistance2();
8186
+ state.value = progress >= 1 ? "ready" : "pulling";
8187
+ }
8188
+ function touchend() {
8189
+ if (!isPulling.value || getDisabled()) return;
8190
+ isPulling.value = false;
8191
+ if (state.value === "ready" && distanceValue.value >= getDistance2()) {
8192
+ refresh();
8193
+ } else {
8194
+ distanceValue.value = 0;
8195
+ reset();
8196
+ }
8197
+ }
8198
+ onUnmounted(() => {
8199
+ reset();
8200
+ });
8201
+ return {
8202
+ state,
8203
+ distance: distanceValue,
8204
+ isPulling,
8205
+ events: {
8206
+ touchstart,
8207
+ touchmove,
8208
+ touchend
8209
+ },
8210
+ containerRef,
8211
+ refresh
8212
+ };
8213
+ }
8214
+ function useResize(options = {}) {
8215
+ const {
8216
+ debounce: debounce2 = 0,
8217
+ box = "content-box",
8218
+ onResize
8219
+ } = options;
8220
+ const width = ref(0);
8221
+ const height = ref(0);
8222
+ let observer = null, debounceTimer = null, fallbackIframe = null;
8223
+ function handleResize(entry) {
8224
+ const currentDebounce = unref(debounce2);
8225
+ function doUpdate() {
8226
+ width.value = entry.contentRect.width;
8227
+ height.value = entry.contentRect.height;
8228
+ onResize == null ? void 0 : onResize({
8229
+ width: entry.contentRect.width,
8230
+ height: entry.contentRect.height,
8231
+ contentRect: entry.contentRect
8232
+ });
8233
+ }
8234
+ if (currentDebounce && currentDebounce > 0) {
8235
+ if (debounceTimer) {
8236
+ clearTimeout(debounceTimer);
8237
+ }
8238
+ debounceTimer = setTimeout(doUpdate, currentDebounce);
8239
+ } else {
8240
+ doUpdate();
8241
+ }
8242
+ }
8243
+ function createObserver2() {
8244
+ if (!isBrowser()) return;
8245
+ if (supportsResizeObserver()) {
8246
+ observer = new ResizeObserver((entries) => {
8247
+ for (const entry of entries) {
8248
+ handleResize(entry);
8249
+ }
8250
+ });
8251
+ }
8252
+ }
8253
+ function bind(element) {
8254
+ if (!isBrowser()) return () => {
8255
+ };
8256
+ stop();
8257
+ const rect = element.getBoundingClientRect();
8258
+ width.value = rect.width;
8259
+ height.value = rect.height;
8260
+ if (supportsResizeObserver()) {
8261
+ createObserver2();
8262
+ observer == null ? void 0 : observer.observe(element, { box });
8263
+ } else {
8264
+ fallbackIframe = document.createElement("iframe");
8265
+ fallbackIframe.style.cssText = `
8266
+ position: absolute;
8267
+ top: 0;
8268
+ left: 0;
8269
+ width: 100%;
8270
+ height: 100%;
8271
+ border: none;
8272
+ pointer-events: none;
8273
+ opacity: 0;
8274
+ `;
8275
+ const computedStyle = getComputedStyle(element);
8276
+ if (computedStyle.position === "static") {
8277
+ element.style.position = "relative";
8278
+ }
8279
+ element.appendChild(fallbackIframe);
8280
+ const iWindow = fallbackIframe.contentWindow;
8281
+ if (iWindow) {
8282
+ iWindow.addEventListener("resize", () => {
8283
+ const rect2 = element.getBoundingClientRect();
8284
+ handleResize({
8285
+ contentRect: rect2
8286
+ });
8287
+ });
8288
+ }
8289
+ }
8290
+ return stop;
8291
+ }
8292
+ function stop() {
8293
+ if (observer) {
8294
+ observer.disconnect();
8295
+ observer = null;
8296
+ }
8297
+ if (fallbackIframe) {
8298
+ fallbackIframe.remove();
8299
+ fallbackIframe = null;
8300
+ }
8301
+ if (debounceTimer) {
8302
+ clearTimeout(debounceTimer);
8303
+ debounceTimer = null;
8304
+ }
8305
+ }
8306
+ onUnmounted(() => {
8307
+ stop();
8308
+ });
8309
+ return {
8310
+ width: readonly(width),
8311
+ height: readonly(height),
8312
+ bind,
8313
+ stop
8314
+ };
8315
+ }
8316
+ function getScrollInfoFromContainer(container, lastScrollLeft, lastScrollTop) {
8317
+ let scrollLeft = 0, scrollTop = 0, scrollLeftMax = 0, scrollTopMax = 0;
8318
+ if (container === window) {
8319
+ scrollLeft = window.scrollX || document.documentElement.scrollLeft;
8320
+ scrollTop = window.scrollY || document.documentElement.scrollTop;
8321
+ scrollLeftMax = document.documentElement.scrollWidth - window.innerWidth;
8322
+ scrollTopMax = document.documentElement.scrollHeight - window.innerHeight;
8323
+ } else {
8324
+ const el = container;
8325
+ scrollLeft = el.scrollLeft;
8326
+ scrollTop = el.scrollTop;
8327
+ scrollLeftMax = el.scrollWidth - el.clientWidth;
8328
+ scrollTopMax = el.scrollHeight - el.clientHeight;
8329
+ }
8330
+ const progressX = scrollLeftMax > 0 ? scrollLeft / scrollLeftMax : 0;
8331
+ const progressY = scrollTopMax > 0 ? scrollTop / scrollTopMax : 0;
8332
+ const directionX = scrollLeft !== lastScrollLeft ? scrollLeft > lastScrollLeft ? 1 : -1 : 0;
8333
+ const directionY = scrollTop !== lastScrollTop ? scrollTop > lastScrollTop ? 1 : -1 : 0;
8334
+ return {
8335
+ scrollLeft,
8336
+ scrollTop,
8337
+ scrollLeftMax,
8338
+ scrollTopMax,
8339
+ progressX,
8340
+ progressY,
8341
+ directionX,
8342
+ directionY
8343
+ };
8344
+ }
8345
+ function useScroll(options = {}) {
8346
+ const { throttle: throttle2 = 0, passive = true } = options;
8347
+ const scrollLeft = ref(0);
8348
+ const scrollTop = ref(0);
8349
+ const progressX = ref(0);
8350
+ const progressY = ref(0);
8351
+ const directionX = ref(0);
8352
+ const directionY = ref(0);
8353
+ const isScrolling = ref(false);
8354
+ let container = null, lastScrollLeft = 0, lastScrollTop = 0, scrollHandler = null, throttleTimer = null, scrollTimeout = null;
8355
+ const info = computed(() => ({
8356
+ scrollLeft: scrollLeft.value,
8357
+ scrollTop: scrollTop.value,
8358
+ scrollLeftMax: 0,
8359
+ scrollTopMax: 0,
8360
+ progressX: progressX.value,
8361
+ progressY: progressY.value,
8362
+ directionX: directionX.value,
8363
+ directionY: directionY.value
8364
+ }));
8365
+ function updateScrollInfo(_e) {
8366
+ if (!container) return;
8367
+ const currentThrottle = unref(throttle2);
8368
+ function doUpdate() {
8369
+ const scrollInfo = getScrollInfoFromContainer(container, lastScrollLeft, lastScrollTop);
8370
+ scrollLeft.value = scrollInfo.scrollLeft;
8371
+ scrollTop.value = scrollInfo.scrollTop;
8372
+ progressX.value = scrollInfo.progressX;
8373
+ progressY.value = scrollInfo.progressY;
8374
+ directionX.value = scrollInfo.directionX;
8375
+ directionY.value = scrollInfo.directionY;
8376
+ lastScrollLeft = scrollInfo.scrollLeft;
8377
+ lastScrollTop = scrollInfo.scrollTop;
8378
+ isScrolling.value = true;
8379
+ if (scrollTimeout) {
8380
+ clearTimeout(scrollTimeout);
8381
+ }
8382
+ scrollTimeout = setTimeout(() => {
8383
+ isScrolling.value = false;
8384
+ }, 150);
8385
+ }
8386
+ if (currentThrottle && currentThrottle > 0) {
8387
+ if (!throttleTimer) {
8388
+ throttleTimer = setTimeout(() => {
8389
+ doUpdate();
8390
+ throttleTimer = null;
8391
+ }, currentThrottle);
8392
+ }
8393
+ } else {
8394
+ doUpdate();
8395
+ }
8396
+ }
8397
+ function bind(element) {
8398
+ if (!isBrowser()) return () => {
8399
+ };
8400
+ stop();
8401
+ if (element) {
8402
+ container = element;
8403
+ } else {
8404
+ container = window;
8405
+ }
8406
+ const initialInfo = getScrollInfoFromContainer(container, 0, 0);
8407
+ scrollLeft.value = initialInfo.scrollLeft;
8408
+ scrollTop.value = initialInfo.scrollTop;
8409
+ progressX.value = initialInfo.progressX;
8410
+ progressY.value = initialInfo.progressY;
8411
+ lastScrollLeft = initialInfo.scrollLeft;
8412
+ lastScrollTop = initialInfo.scrollTop;
8413
+ scrollHandler = updateScrollInfo;
8414
+ container.addEventListener("scroll", scrollHandler, { passive });
8415
+ return stop;
8416
+ }
8417
+ function stop() {
8418
+ if (container && scrollHandler) {
8419
+ container.removeEventListener("scroll", scrollHandler);
8420
+ }
8421
+ if (throttleTimer) {
8422
+ clearTimeout(throttleTimer);
8423
+ throttleTimer = null;
8424
+ }
8425
+ if (scrollTimeout) {
8426
+ clearTimeout(scrollTimeout);
8427
+ scrollTimeout = null;
8428
+ }
8429
+ container = null;
8430
+ scrollHandler = null;
8431
+ }
8432
+ function scrollTo(opts) {
8433
+ if (!container) return;
8434
+ const { top, left, behavior = "smooth" } = opts;
8435
+ if (container === window) {
8436
+ window.scrollTo({
8437
+ top,
8438
+ left,
8439
+ behavior
8440
+ });
8441
+ } else {
8442
+ const el = container;
8443
+ if (top !== void 0) el.scrollTop = top;
8444
+ if (left !== void 0) el.scrollLeft = left;
8445
+ }
8446
+ }
8447
+ onUnmounted(() => {
8448
+ stop();
8449
+ });
8450
+ return {
8451
+ scrollLeft: readonly(scrollLeft),
8452
+ scrollTop: readonly(scrollTop),
8453
+ progressX: readonly(progressX),
8454
+ progressY: readonly(progressY),
8455
+ directionX: readonly(directionX),
8456
+ directionY: readonly(directionY),
8457
+ isScrolling: readonly(isScrolling),
8458
+ info: readonly(info),
8459
+ bind,
8460
+ stop,
8461
+ scrollTo
8462
+ };
8463
+ }
8464
+ const DEFAULT_DIRECTIONS = ["left", "right", "up", "down"];
8465
+ function getSwipeDirection(deltaX, deltaY, allowedDirections) {
8466
+ const absX = Math.abs(deltaX);
8467
+ const absY = Math.abs(deltaY);
8468
+ if (absX > absY) {
8469
+ const direction = deltaX > 0 ? "right" : "left";
8470
+ return allowedDirections.includes(direction) ? direction : null;
8471
+ } else {
8472
+ const direction = deltaY > 0 ? "down" : "up";
8473
+ return allowedDirections.includes(direction) ? direction : null;
8474
+ }
8475
+ }
8476
+ function useSwipe(options = {}) {
8477
+ const {
8478
+ handler,
8479
+ threshold = 30,
8480
+ maxTime = 500,
8481
+ directions = DEFAULT_DIRECTIONS,
8482
+ preventScrollOnSwipe = true,
8483
+ mouse = true,
8484
+ onLeft,
8485
+ onRight,
8486
+ onUp,
8487
+ onDown
8488
+ } = options;
8489
+ const direction = ref(null);
8490
+ const lengthX = ref(0);
8491
+ const lengthY = ref(0);
8492
+ const isSwiping = ref(false);
8493
+ let currentElement = null, startX = 0, startY = 0, startTime = 0;
8494
+ function triggerSwipe2(deltaX, deltaY, deltaTime, event) {
8495
+ var _a;
8496
+ const currentThreshold = unref(threshold);
8497
+ const currentMaxTime = unref(maxTime);
8498
+ if (deltaTime > currentMaxTime) return;
8499
+ const distance = Math.max(Math.abs(deltaX), Math.abs(deltaY));
8500
+ if (distance < currentThreshold) return;
8501
+ const swipeDirection = getSwipeDirection(deltaX, deltaY, directions);
8502
+ if (!swipeDirection) return;
8503
+ direction.value = swipeDirection;
8504
+ lengthX.value = deltaX;
8505
+ lengthY.value = deltaY;
8506
+ if (preventScrollOnSwipe && event.cancelable) {
8507
+ event.preventDefault();
8508
+ }
8509
+ handler == null ? void 0 : handler(swipeDirection, event);
8510
+ const callbacks = {
8511
+ left: onLeft,
8512
+ right: onRight,
8513
+ up: onUp,
8514
+ down: onDown
8515
+ };
8516
+ (_a = callbacks[swipeDirection]) == null ? void 0 : _a.call(callbacks);
8517
+ currentElement == null ? void 0 : currentElement.dispatchEvent(new CustomEvent("swipe", {
8518
+ detail: { direction: swipeDirection, deltaX, deltaY, deltaTime }
8519
+ }));
8520
+ }
8521
+ function handleStart(clientX, clientY) {
8522
+ startX = clientX;
8523
+ startY = clientY;
8524
+ startTime = Date.now();
8525
+ isSwiping.value = true;
8526
+ direction.value = null;
8527
+ lengthX.value = 0;
8528
+ lengthY.value = 0;
8529
+ }
8530
+ function handleEnd(clientX, clientY, event) {
8531
+ if (!isSwiping.value) return;
8532
+ isSwiping.value = false;
8533
+ const deltaX = clientX - startX;
8534
+ const deltaY = clientY - startY;
8535
+ const deltaTime = Date.now() - startTime;
8536
+ triggerSwipe2(deltaX, deltaY, deltaTime, event);
8537
+ }
8538
+ function touchStart(e) {
8539
+ handleStart(e.touches[0].clientX, e.touches[0].clientY);
8540
+ }
8541
+ function touchMove(e) {
8542
+ if (!isSwiping.value || !preventScrollOnSwipe) return;
8543
+ e.preventDefault();
8544
+ }
8545
+ function touchEnd(e) {
8546
+ const touch = e.changedTouches[0];
8547
+ handleEnd(touch.clientX, touch.clientY, e);
8548
+ }
8549
+ function mouseDown(e) {
8550
+ handleStart(e.clientX, e.clientY);
8551
+ }
8552
+ function mouseUp(e) {
8553
+ handleEnd(e.clientX, e.clientY, e);
8554
+ }
8555
+ function mouseLeave(e) {
8556
+ if (isSwiping.value) {
8557
+ handleEnd(e.clientX, e.clientY, e);
8558
+ }
8559
+ }
8560
+ function bind(element) {
8561
+ if (!isBrowser()) return () => {
8562
+ };
8563
+ unbind();
8564
+ currentElement = element;
8565
+ element.style.touchAction = "none";
8566
+ element.style.userSelect = "none";
8567
+ element.addEventListener("touchstart", touchStart, { passive: true });
8568
+ element.addEventListener("touchmove", touchMove, { passive: false });
8569
+ element.addEventListener("touchend", touchEnd);
8570
+ element.addEventListener("touchcancel", touchEnd);
8571
+ if (unref(mouse)) {
8572
+ element.addEventListener("mousedown", mouseDown);
8573
+ element.addEventListener("mouseup", mouseUp);
8574
+ element.addEventListener("mouseleave", mouseLeave);
8575
+ }
8576
+ return unbind;
8577
+ }
8578
+ function unbind() {
8579
+ if (!currentElement) return;
8580
+ currentElement.removeEventListener("touchstart", touchStart);
8581
+ currentElement.removeEventListener("touchmove", touchMove);
8582
+ currentElement.removeEventListener("touchend", touchEnd);
8583
+ currentElement.removeEventListener("touchcancel", touchEnd);
8584
+ if (unref(mouse)) {
8585
+ currentElement.removeEventListener("mousedown", mouseDown);
8586
+ currentElement.removeEventListener("mouseup", mouseUp);
8587
+ currentElement.removeEventListener("mouseleave", mouseLeave);
8588
+ }
8589
+ currentElement = null;
8590
+ }
8591
+ onUnmounted(() => {
8592
+ unbind();
8593
+ });
8594
+ return {
8595
+ direction: readonly(direction),
8596
+ lengthX: readonly(lengthX),
8597
+ lengthY: readonly(lengthY),
8598
+ isSwiping: readonly(isSwiping),
8599
+ bind
8600
+ };
8601
+ }
8602
+ function useThrottle(options) {
8603
+ const {
8604
+ handler,
8605
+ wait = 300,
8606
+ leading = true,
8607
+ trailing = true
8608
+ } = options;
8609
+ let timerId = null, lastArgs = null, lastThis = null, lastCallTime = 0;
8610
+ const getWait = () => unref(wait);
8611
+ const getLeading = () => unref(leading);
8612
+ const getTrailing = () => unref(trailing);
8613
+ const invokeFunc = () => {
8614
+ if (lastArgs) {
8615
+ handler.apply(lastThis, lastArgs);
8616
+ lastArgs = null;
8617
+ lastThis = null;
8618
+ }
8619
+ };
8620
+ function run(...args) {
8621
+ const now = Date.now();
8622
+ const currentWait = getWait();
8623
+ if (!lastCallTime && !getLeading()) {
8624
+ lastCallTime = now;
8625
+ }
8626
+ const remaining = currentWait - (now - lastCallTime);
8627
+ lastArgs = args;
8628
+ lastThis = this;
8629
+ if (remaining <= 0 || remaining > currentWait) {
8630
+ if (timerId) {
8631
+ clearTimeout(timerId);
8632
+ timerId = null;
8633
+ }
8634
+ lastCallTime = now;
8635
+ invokeFunc();
8636
+ } else if (!timerId && getTrailing()) {
8637
+ timerId = setTimeout(() => {
8638
+ lastCallTime = getLeading() ? Date.now() : 0;
8639
+ timerId = null;
8640
+ invokeFunc();
8641
+ }, remaining);
8642
+ }
8643
+ }
8644
+ function cancel() {
8645
+ if (timerId) {
8646
+ clearTimeout(timerId);
8647
+ timerId = null;
8648
+ }
8649
+ lastCallTime = 0;
8650
+ lastArgs = null;
8651
+ lastThis = null;
8652
+ }
8653
+ onUnmounted(() => {
8654
+ cancel();
8655
+ });
8656
+ return {
8657
+ run,
8658
+ cancel
8659
+ };
8660
+ }
8661
+ function throttleFn(fn, wait = 300, options) {
8662
+ return throttle(fn, wait, options);
8663
+ }
8664
+ function useTouch(options = {}) {
8665
+ const {
8666
+ onSwipe,
8667
+ onSwipeLeft,
8668
+ onSwipeRight,
8669
+ onSwipeUp,
8670
+ onSwipeDown,
8671
+ onPinch,
8672
+ onRotate,
8673
+ onTap,
8674
+ onLongPress,
8675
+ swipeThreshold = 30,
8676
+ longPressDuration = 500,
8677
+ tapDuration = 250,
8678
+ disabled = false
8679
+ } = options;
8680
+ const gesture = ref(null);
8681
+ let currentElement = null, startX = 0, startY = 0, startTime = 0, longPressTimer = null, initialPinchDistance = 0, initialAngle = 0;
8682
+ function getTouchCenter(touches) {
8683
+ let x = 0, y = 0;
8684
+ for (let i = 0; i < touches.length; i++) {
8685
+ x += touches[i].clientX;
8686
+ y += touches[i].clientY;
8687
+ }
8688
+ return { x: x / touches.length, y: y / touches.length };
8689
+ }
8690
+ function getDistance2(touch1, touch2) {
8691
+ const dx = touch1.clientX - touch2.clientX;
8692
+ const dy = touch1.clientY - touch2.clientY;
8693
+ return Math.sqrt(dx * dx + dy * dy);
8694
+ }
8695
+ function getAngle2(touch1, touch2) {
8696
+ return Math.atan2(touch2.clientY - touch1.clientY, touch2.clientX - touch1.clientX) * (180 / Math.PI);
8697
+ }
8698
+ function handleTouchStart(e) {
8699
+ if (unref(disabled)) return;
8700
+ startTime = Date.now();
8701
+ gesture.value = null;
8702
+ if (e.touches.length === 1) {
8703
+ startX = e.touches[0].clientX;
8704
+ startY = e.touches[0].clientY;
8705
+ if (onLongPress) {
8706
+ longPressTimer = setTimeout(() => {
8707
+ gesture.value = "longPress";
8708
+ onLongPress({
8709
+ type: "longPress",
8710
+ center: { x: startX, y: startY },
8711
+ event: e
8712
+ });
8713
+ }, longPressDuration);
8714
+ }
8715
+ } else if (e.touches.length === 2) {
8716
+ initialPinchDistance = getDistance2(e.touches[0], e.touches[1]);
8717
+ initialAngle = getAngle2(e.touches[0], e.touches[1]);
8718
+ }
8719
+ }
8720
+ function handleTouchMove(e) {
8721
+ if (unref(disabled)) return;
8722
+ if (longPressTimer) {
8723
+ clearTimeout(longPressTimer);
8724
+ longPressTimer = null;
8725
+ }
8726
+ if (e.touches.length === 2 && (onPinch || onRotate)) {
8727
+ const currentDistance = getDistance2(e.touches[0], e.touches[1]);
8728
+ const currentAngle = getAngle2(e.touches[0], e.touches[1]);
8729
+ if (onPinch && initialPinchDistance > 0) {
8730
+ const scale = currentDistance / initialPinchDistance;
8731
+ gesture.value = "pinch";
8732
+ onPinch({
8733
+ type: "pinch",
8734
+ scale,
8735
+ center: getTouchCenter(e.touches),
8736
+ event: e
8737
+ });
8738
+ }
8739
+ if (onRotate) {
8740
+ const rotation = currentAngle - initialAngle;
8741
+ gesture.value = "rotate";
8742
+ onRotate({
8743
+ type: "rotate",
8744
+ rotation,
8745
+ center: getTouchCenter(e.touches),
8746
+ event: e
8747
+ });
8748
+ }
8749
+ }
8750
+ }
8751
+ function handleTouchEnd(e) {
8752
+ if (unref(disabled)) return;
8753
+ if (longPressTimer) {
8754
+ clearTimeout(longPressTimer);
8755
+ longPressTimer = null;
8756
+ }
8757
+ const duration = Date.now() - startTime;
8758
+ if (e.changedTouches.length === 1) {
8759
+ const endX = e.changedTouches[0].clientX;
8760
+ const endY = e.changedTouches[0].clientY;
8761
+ const deltaX = endX - startX;
8762
+ const deltaY = endY - startY;
8763
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
8764
+ if (distance >= swipeThreshold) {
8765
+ gesture.value = "swipe";
8766
+ let direction;
8767
+ if (Math.abs(deltaX) > Math.abs(deltaY)) {
8768
+ direction = deltaX > 0 ? "right" : "left";
8769
+ } else {
8770
+ direction = deltaY > 0 ? "down" : "up";
8771
+ }
8772
+ const event = {
8773
+ type: "swipe",
8774
+ direction,
8775
+ distance,
8776
+ angle: Math.atan2(deltaY, deltaX) * (180 / Math.PI),
8777
+ center: { x: endX, y: endY },
8778
+ event: e
8779
+ };
8780
+ onSwipe == null ? void 0 : onSwipe(event);
8781
+ switch (direction) {
8782
+ case "left":
8783
+ onSwipeLeft == null ? void 0 : onSwipeLeft(event);
8784
+ break;
8785
+ case "right":
8786
+ onSwipeRight == null ? void 0 : onSwipeRight(event);
8787
+ break;
8788
+ case "up":
8789
+ onSwipeUp == null ? void 0 : onSwipeUp(event);
8790
+ break;
8791
+ case "down":
8792
+ onSwipeDown == null ? void 0 : onSwipeDown(event);
8793
+ break;
8794
+ }
8795
+ } else if (distance < 10 && duration < tapDuration && onTap) {
8796
+ gesture.value = "tap";
8797
+ onTap({
8798
+ type: "tap",
8799
+ center: { x: endX, y: endY },
8800
+ event: e
8801
+ });
8802
+ }
8803
+ }
8804
+ gesture.value = null;
8805
+ }
8806
+ function bind(element) {
8807
+ if (!isBrowser()) return () => {
8808
+ };
8809
+ unbind();
8810
+ currentElement = element;
8811
+ element.addEventListener("touchstart", handleTouchStart, { passive: true });
8812
+ element.addEventListener("touchmove", handleTouchMove, { passive: true });
8813
+ element.addEventListener("touchend", handleTouchEnd);
8814
+ element.addEventListener("touchcancel", handleTouchEnd);
8815
+ return unbind;
8816
+ }
8817
+ function unbind() {
8818
+ if (currentElement) {
8819
+ currentElement.removeEventListener("touchstart", handleTouchStart);
8820
+ currentElement.removeEventListener("touchmove", handleTouchMove);
8821
+ currentElement.removeEventListener("touchend", handleTouchEnd);
8822
+ currentElement.removeEventListener("touchcancel", handleTouchEnd);
8823
+ }
8824
+ if (longPressTimer) {
8825
+ clearTimeout(longPressTimer);
8826
+ longPressTimer = null;
8827
+ }
8828
+ currentElement = null;
8829
+ gesture.value = null;
8830
+ }
8831
+ onUnmounted(() => {
8832
+ unbind();
8833
+ });
8834
+ return {
8835
+ gesture: readonly(gesture),
8836
+ bind
8837
+ };
8838
+ }
8839
+ function escapeRegex(str) {
8840
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8841
+ }
8842
+ function trimText(text, position = "both", chars) {
8843
+ const charPattern = chars ? `[\\s${escapeRegex(chars)}]` : "\\s";
8844
+ switch (position) {
8845
+ case "start":
8846
+ return text.replace(new RegExp(`^${charPattern}+`, "g"), "");
8847
+ case "end":
8848
+ return text.replace(new RegExp(`${charPattern}+$`, "g"), "");
8849
+ case "both":
8850
+ default:
8851
+ return text.replace(new RegExp(`^${charPattern}+|${charPattern}+$`, "g"), "");
8852
+ }
8853
+ }
8854
+ function useTrim(options) {
8855
+ const {
8856
+ text,
8857
+ position = "both",
8858
+ chars
8859
+ } = options;
8860
+ const original = ref(unref(text));
8861
+ const trimmed = ref("");
8862
+ const wasTrimmed = ref(false);
8863
+ function calculate() {
8864
+ const textValue = unref(text);
8865
+ const positionValue = unref(position);
8866
+ const charsValue = unref(chars);
8867
+ original.value = textValue;
8868
+ trimmed.value = trimText(textValue, positionValue, charsValue);
8869
+ wasTrimmed.value = trimmed.value !== textValue;
8870
+ }
8871
+ watch(
8872
+ () => [unref(text), unref(position), unref(chars)],
8873
+ () => calculate(),
8874
+ { immediate: true }
8875
+ );
8876
+ return {
8877
+ trimmed,
8878
+ original,
8879
+ wasTrimmed
8880
+ };
8881
+ }
8882
+ function createTrimmer(position = "both", chars) {
8883
+ return (text) => trimText(text, position, chars);
8884
+ }
8885
+ function uppercaseText(text, firstOnly = false) {
8886
+ if (!text) return text;
8887
+ if (firstOnly) {
8888
+ return text.charAt(0).toUpperCase() + text.slice(1);
8889
+ }
8890
+ return text.toUpperCase();
8891
+ }
8892
+ function useUppercase(options) {
8893
+ const {
8894
+ text,
8895
+ first = false
8896
+ } = options;
8897
+ const original = ref(unref(text));
8898
+ const transformed = ref("");
8899
+ function calculate() {
8900
+ const textValue = unref(text);
8901
+ const firstValue = unref(first);
8902
+ original.value = textValue;
8903
+ transformed.value = uppercaseText(textValue, firstValue);
8904
+ }
8905
+ watch(
8906
+ () => [unref(text), unref(first)],
8907
+ () => calculate(),
8908
+ { immediate: true }
8909
+ );
8910
+ return {
8911
+ transformed,
8912
+ original
8913
+ };
8914
+ }
8915
+ function createUppercaser(first = false) {
8916
+ return (text) => uppercaseText(text, first);
8917
+ }
8918
+ function useVirtualList(options) {
8919
+ const {
8920
+ items,
8921
+ itemSize = 50,
8922
+ height = 400,
8923
+ overscan = 3,
8924
+ keyField: _keyField = "id"
8925
+ } = options;
8926
+ const containerRef = ref(null);
8927
+ const scrollTop = ref(0);
8928
+ const startIndex = ref(0);
8929
+ const endIndex = ref(0);
8930
+ const getItems = () => unref(items);
8931
+ const getItemSizeValue = () => unref(itemSize);
8932
+ const getHeight = () => unref(height);
8933
+ const getOverscan = () => unref(overscan);
8934
+ const totalHeight = computed(() => {
8935
+ const itemsList = getItems();
8936
+ const size = getItemSizeValue();
8937
+ if (typeof size === "function") {
8938
+ let total = 0;
8939
+ for (let i = 0; i < itemsList.length; i++) {
8940
+ total += size(i);
8941
+ }
8942
+ return total;
8943
+ }
8944
+ return size * itemsList.length;
8945
+ });
8946
+ function calculateVisibleRange2() {
8947
+ const itemsList = getItems();
8948
+ const size = getItemSizeValue();
8949
+ const containerHeight = getHeight();
8950
+ const overscanValue = getOverscan();
8951
+ const currentScrollTop = scrollTop.value;
8952
+ let start = 0, end = 0, offsetY = 0;
8953
+ if (typeof size === "function") {
8954
+ let currentOffset = 0;
8955
+ for (let i = 0; i < itemsList.length; i++) {
8956
+ const itemHeight = size(i);
8957
+ if (currentOffset + itemHeight > currentScrollTop) {
8958
+ start = i;
8959
+ offsetY = currentOffset;
8960
+ break;
8961
+ }
8962
+ currentOffset += itemHeight;
8963
+ }
8964
+ end = start;
8965
+ currentOffset = offsetY;
8966
+ while (end < itemsList.length && currentOffset < currentScrollTop + containerHeight) {
8967
+ currentOffset += size(end);
8968
+ end++;
8969
+ }
8970
+ start = Math.max(0, start - overscanValue);
8971
+ end = Math.min(itemsList.length, end + overscanValue);
8972
+ currentOffset = 0;
8973
+ for (let i = 0; i < start; i++) {
8974
+ currentOffset += size(i);
8975
+ }
8976
+ offsetY = currentOffset;
8977
+ } else {
8978
+ start = Math.max(0, Math.floor(currentScrollTop / size) - overscanValue);
8979
+ end = Math.min(itemsList.length, Math.ceil((currentScrollTop + containerHeight) / size) + overscanValue);
8980
+ offsetY = start * size;
8981
+ }
8982
+ return { start, end, offsetY };
8983
+ }
8984
+ const visibleItems = computed(() => {
8985
+ const itemsList = getItems();
8986
+ const size = getItemSizeValue();
8987
+ const { start, end, offsetY } = calculateVisibleRange2();
8988
+ startIndex.value = start;
8989
+ endIndex.value = end;
8990
+ const result = [];
8991
+ let currentOffset = offsetY;
8992
+ for (let i = start; i < end; i++) {
8993
+ const item = itemsList[i];
8994
+ if (item !== void 0) {
8995
+ const itemHeight = typeof size === "function" ? size(i) : size;
8996
+ result.push({
8997
+ item,
8998
+ index: i,
8999
+ style: {
9000
+ position: "absolute",
9001
+ top: `${currentOffset}px`,
9002
+ height: `${itemHeight}px`,
9003
+ width: "100%"
9004
+ }
9005
+ });
9006
+ currentOffset += itemHeight;
9007
+ }
9008
+ }
9009
+ return result;
9010
+ });
9011
+ const listStyle = computed(() => ({
9012
+ height: `${getHeight()}px`,
9013
+ overflow: "auto",
9014
+ position: "relative"
9015
+ }));
9016
+ function handleScroll(event) {
9017
+ const target = event.target;
9018
+ scrollTop.value = target.scrollTop;
9019
+ }
9020
+ function scrollToIndex(index) {
9021
+ if (!containerRef.value) return;
9022
+ const size = getItemSizeValue();
9023
+ const itemsList = getItems();
9024
+ if (typeof size === "function") {
9025
+ let offset = 0;
9026
+ for (let i = 0; i < Math.min(index, itemsList.length); i++) {
9027
+ offset += size(i);
9028
+ }
9029
+ containerRef.value.scrollTop = offset;
9030
+ } else {
9031
+ containerRef.value.scrollTop = index * size;
9032
+ }
9033
+ }
9034
+ function scrollTo(position) {
9035
+ if (!containerRef.value) return;
9036
+ containerRef.value.scrollTop = position;
9037
+ }
9038
+ onMounted(() => {
9039
+ if (containerRef.value) {
9040
+ containerRef.value.addEventListener("scroll", handleScroll, { passive: true });
9041
+ }
9042
+ });
9043
+ onUnmounted(() => {
9044
+ if (containerRef.value) {
9045
+ containerRef.value.removeEventListener("scroll", handleScroll);
9046
+ }
9047
+ });
9048
+ return {
9049
+ visibleItems,
9050
+ totalHeight,
9051
+ scrollTop,
9052
+ startIndex,
9053
+ endIndex,
9054
+ scrollToIndex,
9055
+ scrollTo,
9056
+ containerRef,
9057
+ listStyle
9058
+ };
9059
+ }
9060
+ function useVisible(options = {}) {
9061
+ const {
9062
+ initial = true,
9063
+ useHidden = false,
9064
+ onChange
9065
+ } = options;
9066
+ const visible = ref(unref(initial));
9067
+ let currentElement = null, originalDisplay = "", originalVisibility = "";
9068
+ function show() {
9069
+ visible.value = true;
9070
+ }
9071
+ function hide() {
9072
+ visible.value = false;
9073
+ }
9074
+ function toggle() {
9075
+ visible.value = !visible.value;
9076
+ }
9077
+ function applyVisibility2(isVisible) {
9078
+ if (!currentElement) return;
9079
+ if (isVisible) {
9080
+ currentElement.classList.remove("v-hidden");
9081
+ currentElement.classList.add("v-visible");
9082
+ if (useHidden) {
9083
+ currentElement.style.visibility = originalVisibility || "visible";
9084
+ } else {
9085
+ currentElement.style.display = originalDisplay;
9086
+ }
9087
+ } else {
9088
+ currentElement.classList.remove("v-visible");
9089
+ currentElement.classList.add("v-hidden");
9090
+ if (useHidden) {
9091
+ currentElement.style.visibility = "hidden";
9092
+ } else {
9093
+ currentElement.style.display = "none";
9094
+ }
9095
+ }
9096
+ }
9097
+ function bind(element) {
9098
+ if (!isBrowser()) return () => {
9099
+ };
9100
+ unbind();
9101
+ currentElement = element;
9102
+ originalDisplay = element.style.display;
9103
+ originalVisibility = element.style.visibility;
9104
+ applyVisibility2(visible.value);
9105
+ return unbind;
9106
+ }
9107
+ function unbind() {
9108
+ if (currentElement) {
9109
+ currentElement.style.display = originalDisplay;
9110
+ currentElement.style.visibility = originalVisibility;
9111
+ currentElement.classList.remove("v-hidden", "v-visible");
9112
+ }
9113
+ currentElement = null;
9114
+ }
9115
+ watch(visible, (newValue, oldValue) => {
9116
+ if (newValue !== oldValue) {
9117
+ applyVisibility2(newValue);
9118
+ onChange == null ? void 0 : onChange(newValue);
9119
+ }
9120
+ });
9121
+ if (typeof initial === "object" && "value" in initial) {
9122
+ watch(initial, (newValue) => {
9123
+ visible.value = newValue;
9124
+ });
9125
+ }
9126
+ onUnmounted(() => {
9127
+ unbind();
9128
+ });
9129
+ return {
9130
+ visible,
9131
+ show,
9132
+ hide,
9133
+ toggle,
9134
+ bind
9135
+ };
9136
+ }
9137
+ function createWatermarkCanvas(options) {
9138
+ const canvas = document.createElement("canvas");
9139
+ const ctx = canvas.getContext("2d");
9140
+ if (!ctx) {
9141
+ throw new Error("[Directix] useWatermark: Could not get canvas context");
9142
+ }
9143
+ const {
9144
+ content,
9145
+ width,
9146
+ height,
9147
+ fontSize,
9148
+ fontFamily,
9149
+ fontWeight,
9150
+ color,
9151
+ rotate
9152
+ } = options;
9153
+ canvas.width = width;
9154
+ canvas.height = height;
9155
+ ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
9156
+ ctx.fillStyle = color;
9157
+ ctx.textAlign = "center";
9158
+ ctx.textBaseline = "middle";
9159
+ ctx.translate(width / 2, height / 2);
9160
+ ctx.rotate(rotate * Math.PI / 180);
9161
+ const contentArray = Array.isArray(content) ? content : [content];
9162
+ const lineHeight = fontSize * 1.5;
9163
+ const startY = -((contentArray.length - 1) * lineHeight) / 2;
9164
+ contentArray.forEach((text, index) => {
9165
+ ctx.fillText(text, 0, startY + index * lineHeight);
9166
+ });
9167
+ return canvas;
9168
+ }
9169
+ function useWatermark(options) {
9170
+ const {
9171
+ content,
9172
+ width = 300,
9173
+ height = 200,
9174
+ rotate = -22,
9175
+ fontSize = 16,
9176
+ fontFamily = "sans-serif",
9177
+ fontWeight = "normal",
9178
+ color = "rgba(128, 128, 128, 0.15)",
9179
+ gap = [100, 100],
9180
+ zIndex = 9999,
9181
+ disabled = false,
9182
+ protect: _protect = true
9183
+ } = options;
9184
+ const canvas = ref(null);
9185
+ const dataUrl = ref("");
9186
+ const disabledRef = ref(unref(disabled));
9187
+ function generate() {
9188
+ const contentValue = unref(content);
9189
+ const widthValue = unref(width);
9190
+ const heightValue = unref(height);
9191
+ const rotateValue = unref(rotate);
9192
+ const fontSizeValue = unref(fontSize);
9193
+ const fontFamilyValue = unref(fontFamily);
9194
+ const fontWeightValue = unref(fontWeight);
9195
+ const colorValue = unref(color);
9196
+ canvas.value = createWatermarkCanvas({
9197
+ content: contentValue,
9198
+ width: widthValue,
9199
+ height: heightValue,
9200
+ fontSize: fontSizeValue,
9201
+ fontFamily: fontFamilyValue,
9202
+ fontWeight: fontWeightValue,
9203
+ color: colorValue,
9204
+ rotate: rotateValue
9205
+ });
9206
+ dataUrl.value = canvas.value.toDataURL();
9207
+ }
9208
+ const style = ref({
9209
+ position: "absolute",
9210
+ top: "0",
9211
+ left: "0",
9212
+ width: "100%",
9213
+ height: "100%",
9214
+ pointerEvents: "none",
9215
+ zIndex: unref(zIndex),
9216
+ backgroundImage: "",
9217
+ backgroundRepeat: "repeat",
9218
+ backgroundPosition: "0 0",
9219
+ backgroundSize: ""
9220
+ });
9221
+ function updateStyle() {
9222
+ const gapValue = unref(gap);
9223
+ const zIndexValue = unref(zIndex);
9224
+ const gapArray = Array.isArray(gapValue) ? gapValue : [gapValue, gapValue];
9225
+ const widthValue = unref(width);
9226
+ const heightValue = unref(height);
9227
+ style.value = __spreadProps(__spreadValues({}, style.value), {
9228
+ zIndex: zIndexValue,
9229
+ backgroundImage: `url("${dataUrl.value}")`,
9230
+ backgroundPosition: `${gapArray[0] / 2}px ${gapArray[1] / 2}px`,
9231
+ backgroundSize: `${widthValue + gapArray[0]}px ${heightValue + gapArray[1]}px`
9232
+ });
9233
+ }
9234
+ function update(newOptions) {
9235
+ Object.assign(options, newOptions);
9236
+ generate();
9237
+ updateStyle();
9238
+ }
9239
+ function enable() {
9240
+ disabledRef.value = false;
9241
+ }
9242
+ function disable() {
9243
+ disabledRef.value = true;
9244
+ }
9245
+ watch(
9246
+ () => [
9247
+ unref(content),
9248
+ unref(width),
9249
+ unref(height),
9250
+ unref(rotate),
9251
+ unref(fontSize),
9252
+ unref(fontFamily),
9253
+ unref(fontWeight),
9254
+ unref(color),
9255
+ unref(gap),
9256
+ unref(zIndex)
9257
+ ],
9258
+ () => {
9259
+ generate();
9260
+ updateStyle();
9261
+ },
9262
+ { immediate: true }
9263
+ );
9264
+ watch(disabledRef, (isDisabled) => {
9265
+ style.value.display = isDisabled ? "none" : "block";
9266
+ });
9267
+ if (unref(disabled)) {
9268
+ style.value.display = "none";
9269
+ }
9270
+ onUnmounted(() => {
9271
+ });
9272
+ return {
9273
+ canvas,
9274
+ dataUrl,
9275
+ style,
9276
+ disabled: disabledRef,
9277
+ update,
9278
+ enable,
9279
+ disable
9280
+ };
9281
+ }
9282
+ function createWatermarkUrl(content, options = {}) {
9283
+ var _a, _b, _c, _d, _e;
9284
+ const canvas = createWatermarkCanvas({
9285
+ content,
9286
+ width: (_a = options.width) != null ? _a : 300,
9287
+ height: (_b = options.height) != null ? _b : 200,
9288
+ fontSize: (_c = options.fontSize) != null ? _c : 16,
9289
+ fontFamily: "sans-serif",
9290
+ fontWeight: "normal",
9291
+ color: (_d = options.color) != null ? _d : "rgba(128, 128, 128, 0.15)",
9292
+ rotate: (_e = options.rotate) != null ? _e : -22
9293
+ });
9294
+ return canvas.toDataURL();
9295
+ }
6281
9296
  const allDirectives = {
6282
9297
  "click-outside": vClickOutside,
6283
9298
  "click-delay": vClickDelay,
@@ -6363,32 +9378,31 @@ export {
6363
9378
  Directix,
6364
9379
  addCleanup$1 as addCleanupVue2,
6365
9380
  addCleanup as addCleanupVue3,
6366
- vCapitalcase as capitalcase,
6367
- vClickDelay as clickDelay,
6368
- vClickOutside as clickOutside,
6369
- configurePermission,
6370
- vCopy as copy,
6371
- vCountdown as countdown,
9381
+ calculateTime,
9382
+ capitalizeText,
9383
+ capitalizeWord,
9384
+ createCapitalizer,
9385
+ createDelayedClick,
9386
+ createLowercaser,
9387
+ createMoneyFormatter,
9388
+ createNumberFormatter,
9389
+ createPermissionChecker,
9390
+ createTrimmer,
9391
+ createUppercaser,
6372
9392
  createVue2Directive,
6373
9393
  createVue3Directive,
6374
- vDebounce as debounce,
6375
- debounce as debounceFn,
9394
+ createWatermarkUrl,
9395
+ debounceFn,
6376
9396
  deepClone,
6377
9397
  deepMerge,
6378
9398
  defineDirective,
6379
9399
  defineDirectiveGroup,
6380
- vDraggable as draggable,
6381
- vEllipsis as ellipsis,
6382
- vFocus as focus,
9400
+ formatMoney,
9401
+ formatNumber,
9402
+ formatTime,
6383
9403
  generateId,
6384
9404
  get,
6385
- getPermissionConfig,
6386
9405
  getVueVersion,
6387
- vHotkey as hotkey,
6388
- vHover as hover,
6389
- vImagePreview as imagePreview,
6390
- vInfiniteScroll as infiniteScroll,
6391
- vIntersect as intersect,
6392
9406
  isArray,
6393
9407
  isBoolean,
6394
9408
  isBrowser,
@@ -6402,39 +9416,54 @@ export {
6402
9416
  isVue2,
6403
9417
  isVue27,
6404
9418
  isVue3,
6405
- vLazy as lazy,
6406
- vLoading as loading,
6407
- vLongPress as longPress,
6408
- vLowercase as lowercase,
6409
- vMask as mask,
6410
- vMoney as money,
6411
- vMutation as mutation,
6412
- vNumber as number,
9419
+ lowercaseText,
9420
+ parseMoney,
9421
+ parseNumber,
9422
+ parseTargetTime,
6413
9423
  parseTime,
6414
- vPermission as permission,
6415
- vPrint as print,
6416
- vPullRefresh as pullRefresh,
9424
+ quickPrint,
6417
9425
  resetVueVersion,
6418
- vResize as resize,
6419
- vRipple as ripple,
6420
- vSanitize as sanitize,
6421
- vScroll as scroll,
6422
9426
  set,
6423
9427
  setVueVersion,
6424
- vSticky as sticky,
6425
9428
  supportsClipboard,
6426
9429
  supportsIntersectionObserver,
6427
9430
  supportsMutationObserver,
6428
9431
  supportsPassive,
6429
9432
  supportsResizeObserver,
6430
- vSwipe as swipe,
6431
- vThrottle as throttle,
6432
- throttle as throttleFn,
6433
- vTooltip as tooltip,
6434
- vTouch as touch,
6435
- vTrim as trim,
6436
- vTruncate as truncate,
6437
- vUppercase as uppercase,
9433
+ throttleFn,
9434
+ trimText,
9435
+ truncateText,
9436
+ uppercaseText,
9437
+ useCapitalcase,
9438
+ useClickDelay,
9439
+ useClickOutside,
9440
+ useCopy,
9441
+ useCountdown,
9442
+ useDebounce,
9443
+ useDraggable,
9444
+ useEllipsis,
9445
+ useFocus,
9446
+ useHotkey,
9447
+ useHover,
9448
+ useImagePreview,
9449
+ useIntersect,
9450
+ useLongPress,
9451
+ useLowercase,
9452
+ useMoney,
9453
+ useNumber,
9454
+ usePermission,
9455
+ usePrint,
9456
+ usePullRefresh,
9457
+ useResize,
9458
+ useScroll,
9459
+ useSwipe,
9460
+ useThrottle,
9461
+ useTouch,
9462
+ useTrim,
9463
+ useUppercase,
9464
+ useVirtualList,
9465
+ useVisible,
9466
+ useWatermark,
6438
9467
  vCapitalcase,
6439
9468
  vClickDelay,
6440
9469
  vClickOutside,
@@ -6475,8 +9504,6 @@ export {
6475
9504
  vVirtualList,
6476
9505
  vVisible,
6477
9506
  vWatermark,
6478
- vVirtualList as virtualList,
6479
- vVisible as visible,
6480
- vWatermark as watermark
9507
+ wouldTextTruncate
6481
9508
  };
6482
9509
  //# sourceMappingURL=index.mjs.map