@falcon-ui/falcon-ui 1.0.0 → 1.1.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.
Files changed (51) hide show
  1. package/README.md +1 -0
  2. package/THIRD_PARTY_NOTICES.md +51 -0
  3. package/cjs/components/index.cjs +1131 -4
  4. package/cjs/components/index.cjs.map +1 -1
  5. package/cjs/components/loading/index.cjs +1186 -0
  6. package/cjs/components/loading/index.cjs.map +1 -0
  7. package/cjs/components/loading/src/loading.cjs +72 -0
  8. package/cjs/components/loading/src/loading.cjs.map +1 -0
  9. package/cjs/index.cjs +1132 -4
  10. package/cjs/index.cjs.map +1 -1
  11. package/esm/components/index.mjs +1130 -6
  12. package/esm/components/index.mjs.map +1 -1
  13. package/esm/components/loading/index.mjs +1179 -0
  14. package/esm/components/loading/index.mjs.map +1 -0
  15. package/esm/components/loading/src/loading.mjs +66 -0
  16. package/esm/components/loading/src/loading.mjs.map +1 -0
  17. package/esm/index.mjs +1131 -6
  18. package/esm/index.mjs.map +1 -1
  19. package/global.d.ts +2 -0
  20. package/package.json +7 -1
  21. package/theme/index.css +1 -1
  22. package/theme/index.scss +1 -0
  23. package/theme/src/loading.scss +52 -0
  24. package/types/components/barcode/index.d.ts +1 -1
  25. package/types/components/barcode/src/barcode.vue.d.ts +1 -1
  26. package/types/components/index.d.ts +2 -0
  27. package/types/components/input/index.d.ts +1 -1
  28. package/types/components/input/src/input.vue.d.ts +1 -1
  29. package/types/components/input-number/index.d.ts +3 -3
  30. package/types/components/input-number/src/input-number.vue.d.ts +1 -1
  31. package/types/components/loading/index.d.ts +183 -0
  32. package/types/components/loading/src/FlLoading.vue.d.ts +109 -0
  33. package/types/components/loading/src/animations/composing.d.ts +2 -0
  34. package/types/components/loading/src/animations/earth.d.ts +12 -0
  35. package/types/components/loading/src/animations/listening.d.ts +2 -0
  36. package/types/components/loading/src/animations/searching.d.ts +2 -0
  37. package/types/components/loading/src/animations/shaping.d.ts +2 -0
  38. package/types/components/loading/src/animations/solving.d.ts +2 -0
  39. package/types/components/loading/src/animations/working.d.ts +2 -0
  40. package/types/components/loading/src/earth-points.d.ts +22 -0
  41. package/types/components/loading/src/loading-frame.d.ts +4 -0
  42. package/types/components/loading/src/loading-geometry.d.ts +66 -0
  43. package/types/components/loading/src/loading-presets.d.ts +6 -0
  44. package/types/components/loading/src/loading-profiles.d.ts +7 -0
  45. package/types/components/loading/src/loading-renderer.d.ts +4 -0
  46. package/types/components/loading/src/loading.d.ts +65 -0
  47. package/types/components/loading/src/use-fl-loading.d.ts +15 -0
  48. package/types/components/loading/src/use-loading-animation.d.ts +13 -0
  49. package/types/components/loading/src/use-loading-color.d.ts +6 -0
  50. package/umd/falcon-ui.umd.js +1137 -7
  51. package/umd/falcon-ui.umd.js.map +1 -1
@@ -200,13 +200,13 @@
200
200
  "update:modelValue": (value) => typeof value === "boolean"
201
201
  };
202
202
  }));
203
- var _hoisted_1$7, dialog_vue_vue_type_script_setup_true_lang_default;
203
+ var _hoisted_1$8, dialog_vue_vue_type_script_setup_true_lang_default;
204
204
  var init_dialog_vue_vue_type_script_setup_true_lang = __esmMin((() => {
205
205
  init_hooks();
206
206
  init_utils();
207
207
  init_button();
208
208
  init_dialog$1();
209
- _hoisted_1$7 = ["onKeydown"];
209
+ _hoisted_1$8 = ["onKeydown"];
210
210
  dialog_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
211
211
  name: "FlDialog",
212
212
  inheritAttrs: false,
@@ -341,7 +341,7 @@
341
341
  }, [(0, vue.createVNode)((0, vue.unref)(element_plus.ElIcon), null, {
342
342
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)((0, vue.unref)(__element_plus_icons_vue.FullScreen))]),
343
343
  _: 1
344
- })], 42, _hoisted_1$7), (0, vue.createVNode)((0, vue.unref)(FlButton), {
344
+ })], 42, _hoisted_1$8), (0, vue.createVNode)((0, vue.unref)(FlButton), {
345
345
  icon: (0, vue.unref)(__element_plus_icons_vue.Close),
346
346
  class: (0, vue.normalizeClass)((0, vue.unref)(headerActionIconClass)),
347
347
  "aria-label": "Close",
@@ -641,6 +641,1133 @@
641
641
  init_utils();
642
642
  FlButton = withInstall(button_default);
643
643
  }));
644
+ const flLoadingAnimations = [
645
+ "working",
646
+ "searching",
647
+ "solving",
648
+ "listening",
649
+ "composing",
650
+ "shaping",
651
+ "earth"
652
+ ];
653
+ const flLoadingSizes = [
654
+ 20,
655
+ 32,
656
+ 48,
657
+ 64,
658
+ 96
659
+ ];
660
+ const flLoadingProps = {
661
+ active: {
662
+ type: Boolean,
663
+ default: true
664
+ },
665
+ animation: {
666
+ type: String,
667
+ default: "searching",
668
+ validator: (v) => flLoadingAnimations.includes(v)
669
+ },
670
+ size: {
671
+ type: Number,
672
+ default: 64,
673
+ validator: (v) => flLoadingSizes.includes(v)
674
+ },
675
+ color: {
676
+ type: String,
677
+ default: ""
678
+ },
679
+ theme: {
680
+ type: String,
681
+ default: "auto"
682
+ },
683
+ speed: {
684
+ type: Number,
685
+ default: 1
686
+ },
687
+ paused: {
688
+ type: Boolean,
689
+ default: false
690
+ },
691
+ text: {
692
+ type: String,
693
+ default: ""
694
+ },
695
+ layout: {
696
+ type: String,
697
+ default: "inline"
698
+ },
699
+ ariaLabel: {
700
+ type: String,
701
+ default: "加载中"
702
+ }
703
+ };
704
+ const normalizeAnimation = (v) => flLoadingAnimations.includes(v) ? v : "searching";
705
+ const normalizeSize = (v) => flLoadingSizes.includes(v) ? v : 64;
706
+ const normalizeSpeed = (v) => Number.isFinite(v) ? Math.max(.25, Math.min(3, v)) : 1;
707
+ function useLoadingColor(host, options) {
708
+ const color = (0, vue.ref)("#20252b");
709
+ let mounted = false;
710
+ let observer;
711
+ let media;
712
+ let probe;
713
+ let observedHost;
714
+ const resolve = () => {
715
+ if (!mounted) return;
716
+ const target = host() || document.documentElement;
717
+ if (target !== observedHost) {
718
+ observer?.disconnect();
719
+ probe?.remove();
720
+ probe = document.createElement("span");
721
+ probe.setAttribute("aria-hidden", "true");
722
+ probe.style.cssText = "position:absolute;visibility:hidden;pointer-events:none;width:0;height:0;overflow:hidden";
723
+ target.appendChild(probe);
724
+ for (let el = target; el; el = el.parentElement) observer?.observe(el, {
725
+ attributes: true,
726
+ attributeFilter: [
727
+ "class",
728
+ "style",
729
+ "data-theme"
730
+ ]
731
+ });
732
+ observedHost = target;
733
+ }
734
+ const { color: explicit, theme = "auto" } = options();
735
+ let dark = theme === "dark";
736
+ if (theme === "auto") {
737
+ dark = media?.matches ?? false;
738
+ for (let el = target; el; el = el.parentElement) {
739
+ const marker = el.dataset.theme;
740
+ if (marker === "dark" || marker === "light") {
741
+ dark = marker === "dark";
742
+ break;
743
+ }
744
+ if (el.classList.contains("dark") || el.classList.contains("light")) {
745
+ dark = el.classList.contains("dark");
746
+ break;
747
+ }
748
+ }
749
+ }
750
+ const variable = getComputedStyle(target).getPropertyValue("--fl-loading-color").trim();
751
+ const fallback = dark ? "#f0f3f7" : "#20252b";
752
+ if (probe) {
753
+ probe.style.color = fallback;
754
+ if (explicit || variable) probe.style.color = explicit || variable;
755
+ color.value = getComputedStyle(probe).color || fallback;
756
+ }
757
+ };
758
+ (0, vue.watch)([
759
+ host,
760
+ () => options().color,
761
+ () => options().theme
762
+ ], resolve, { flush: "post" });
763
+ (0, vue.onMounted)(() => {
764
+ mounted = true;
765
+ media = window.matchMedia?.("(prefers-color-scheme: dark)");
766
+ observer = typeof MutationObserver === "undefined" ? void 0 : new MutationObserver(resolve);
767
+ media?.addEventListener("change", resolve);
768
+ resolve();
769
+ });
770
+ (0, vue.onScopeDispose)(() => {
771
+ mounted = false;
772
+ observer?.disconnect();
773
+ media?.removeEventListener("change", resolve);
774
+ probe?.remove();
775
+ });
776
+ return color;
777
+ }
778
+ var COUNT_PAIRS = [
779
+ ["latRings", "lonDensity"],
780
+ ["rings", "lonDensity"],
781
+ ["lanes", "segs"]
782
+ ];
783
+ var COUNT_KEYS = [
784
+ "orbitN",
785
+ "ghostN",
786
+ "nodeN",
787
+ "strandN",
788
+ "signals"
789
+ ];
790
+ var ICON_DENSITY_KEYS = ["iconD"];
791
+ var RADIUS_KEYS = [
792
+ "rBase",
793
+ "rDepth",
794
+ "rActive",
795
+ "rDot",
796
+ "ghostR",
797
+ "partR",
798
+ "partRDepth",
799
+ "nodeR",
800
+ "nodeRDepth"
801
+ ];
802
+ function scaleCounts(opts, scale) {
803
+ const out = { ...opts };
804
+ const done = /* @__PURE__ */ new Set();
805
+ const rt = Math.sqrt(scale);
806
+ for (const [a, b] of COUNT_PAIRS) {
807
+ const va = out[a];
808
+ const vb = out[b];
809
+ if (va != null && vb != null && !done.has(a) && !done.has(b)) {
810
+ out[a] = Math.max(2, Math.round(va * rt));
811
+ out[b] = Math.max(2, Math.round(vb * rt));
812
+ done.add(a);
813
+ done.add(b);
814
+ }
815
+ }
816
+ for (const k of COUNT_KEYS) {
817
+ const v = out[k];
818
+ if (v != null && v !== 0 && !done.has(k)) out[k] = Math.max(1, Math.round(v * scale));
819
+ }
820
+ for (const k of ICON_DENSITY_KEYS) {
821
+ const v = out[k];
822
+ if (v != null) out[k] = Math.max(.02, v * scale);
823
+ }
824
+ return out;
825
+ }
826
+ function scaleRadii(opts, scale) {
827
+ const out = { ...opts };
828
+ for (const k of RADIUS_KEYS) {
829
+ const v = out[k];
830
+ if (v != null) out[k] = v * scale;
831
+ }
832
+ out.rSizeMul = (out.rSizeMul ?? 1) * scale;
833
+ return out;
834
+ }
835
+ const BASE_PROFILES = {
836
+ globe: {
837
+ latRings: 17,
838
+ lonDensity: 44,
839
+ rBase: .6,
840
+ rDepth: 1.7,
841
+ rBoost: 1,
842
+ inkFar: .62,
843
+ inkSpan: .54,
844
+ rsPow: .6,
845
+ rMin: .3
846
+ },
847
+ orbits: {
848
+ orbitN: 12,
849
+ ghostN: 40,
850
+ ghostR: .9,
851
+ ghostA: .5,
852
+ particles: 3,
853
+ partR: 1.2,
854
+ partRDepth: 1.6,
855
+ rsPow: .6,
856
+ rMin: .3
857
+ },
858
+ rubik: {
859
+ latRings: 15,
860
+ lonDensity: 40,
861
+ moveCount: 14,
862
+ rBase: .6,
863
+ rDepth: 1.7,
864
+ rActive: .3,
865
+ inkFar: .62,
866
+ inkSpan: .54,
867
+ rsPow: .6,
868
+ rMin: .3
869
+ },
870
+ wave: {
871
+ rings: 15,
872
+ lonDensity: 40,
873
+ rBase: .6,
874
+ rDepth: 1.7,
875
+ rsPow: .6,
876
+ rMin: .3
877
+ },
878
+ web: {
879
+ nodeN: 30,
880
+ thr: .72,
881
+ signals: 5,
882
+ nodeR: 1.4,
883
+ nodeRDepth: 1.8,
884
+ lineW: .8,
885
+ rsPow: .6,
886
+ rMin: .3
887
+ },
888
+ braid: {
889
+ strandN: 52,
890
+ turns: 3,
891
+ ghostN: 150,
892
+ rBase: 1.2,
893
+ rDepth: 1.8,
894
+ rsPow: .6,
895
+ rMin: .3
896
+ },
897
+ ribbon: {
898
+ lanes: 5,
899
+ segs: 88,
900
+ ghostN: 150,
901
+ rBase: 1.1,
902
+ rDepth: 1.7,
903
+ rsPow: .6,
904
+ rMin: .3
905
+ },
906
+ ring: {
907
+ lanes: 5,
908
+ segs: 88,
909
+ ghostN: 0,
910
+ faceOn: 1,
911
+ rBase: 1.1,
912
+ rDepth: 1.7,
913
+ rsPow: .6,
914
+ rMin: .3
915
+ },
916
+ morph: {
917
+ rDot: .021,
918
+ iconD: 1,
919
+ rMin: .25
920
+ }
921
+ };
922
+ var presets = {
923
+ working: [
924
+ "orbits",
925
+ 1.885,
926
+ 1,
927
+ 1,
928
+ 3.9,
929
+ .238,
930
+ 2.4
931
+ ],
932
+ searching: [
933
+ "globe",
934
+ 2.015,
935
+ .42,
936
+ 1.15,
937
+ 2.665,
938
+ .105,
939
+ 1.75
940
+ ],
941
+ solving: [
942
+ "rubik",
943
+ 1.82,
944
+ .35,
945
+ 1.05,
946
+ 1.95,
947
+ .088,
948
+ 1.9
949
+ ],
950
+ listening: [
951
+ "wave",
952
+ 4.388,
953
+ .341,
954
+ 1,
955
+ 3.998,
956
+ .105,
957
+ 1.6
958
+ ],
959
+ composing: [
960
+ "ribbon",
961
+ 2.34,
962
+ .25,
963
+ .85,
964
+ 3.12,
965
+ .051,
966
+ 1.073
967
+ ],
968
+ shaping: [
969
+ "morph",
970
+ 2.405,
971
+ .702,
972
+ .395,
973
+ 2.08,
974
+ .53,
975
+ 1.011
976
+ ]
977
+ };
978
+ var cache$1 = /* @__PURE__ */ new Map();
979
+ function resolvePreset(animation, size) {
980
+ const key = `${animation}-${size}`;
981
+ const hit = cache$1.get(key);
982
+ if (hit) return hit;
983
+ if (animation === "earth") return {
984
+ speed: 1,
985
+ opts: {}
986
+ };
987
+ const [mode, bigSpeed, bigCount, bigRadius, smallSpeed, smallCount, smallRadius] = presets[animation];
988
+ const blend = Math.max(0, Math.min(1, (size - 20) / 44));
989
+ const count = smallCount + (bigCount - smallCount) * blend;
990
+ const radius = smallRadius + (bigRadius - smallRadius) * blend;
991
+ let opts = scaleRadii(scaleCounts(BASE_PROFILES[mode], count), radius);
992
+ if (animation === "searching") opts = {
993
+ ...opts,
994
+ scanMul: 4.08,
995
+ dimBase: .45
996
+ };
997
+ if (animation === "composing") opts = {
998
+ ...opts,
999
+ spin: 0,
1000
+ bandMul: 3.9,
1001
+ wobMul: 1
1002
+ };
1003
+ if (animation === "shaping") opts = {
1004
+ ...opts,
1005
+ spread: 1.45
1006
+ };
1007
+ const resolved = {
1008
+ speed: smallSpeed + (bigSpeed - smallSpeed) * blend,
1009
+ opts
1010
+ };
1011
+ cache$1.set(key, resolved);
1012
+ return resolved;
1013
+ }
1014
+ function hashD(a, b) {
1015
+ const h$8 = Math.sin(a * 12.9898 + b * 78.233) * 43758.5453;
1016
+ return h$8 - Math.floor(h$8);
1017
+ }
1018
+ function fibDir(i, n) {
1019
+ const golden = Math.PI * (3 - Math.sqrt(5));
1020
+ const y = 1 - 2 * (i + .5) / n;
1021
+ const rad = Math.sqrt(1 - y * y);
1022
+ const a = i * golden;
1023
+ return [
1024
+ rad * Math.cos(a),
1025
+ y,
1026
+ rad * Math.sin(a)
1027
+ ];
1028
+ }
1029
+ function angleDelta(a, b) {
1030
+ return Math.atan2(Math.sin(a - b), Math.cos(a - b));
1031
+ }
1032
+ function makeProj(yaw, tilt, cx, cy, scale) {
1033
+ const st = Math.sin(tilt);
1034
+ const ct = Math.cos(tilt);
1035
+ const sy = Math.sin(yaw);
1036
+ const cyw = Math.cos(yaw);
1037
+ return (x, y, z) => {
1038
+ const x1 = x * cyw + z * sy;
1039
+ const z1 = -x * sy + z * cyw;
1040
+ const y1 = y * ct - z1 * st;
1041
+ const z2 = y * st + z1 * ct;
1042
+ return [
1043
+ cx + x1 * scale,
1044
+ cy - y1 * scale,
1045
+ z2
1046
+ ];
1047
+ };
1048
+ }
1049
+ function finalizeFrame(dots, lines, rMin = .3) {
1050
+ const visible = [];
1051
+ for (const d of dots) {
1052
+ if ((d.a ?? 1) < .02) continue;
1053
+ d.r = Math.max(rMin, d.r);
1054
+ visible.push(d);
1055
+ }
1056
+ visible.sort((a, b) => a.z - b.z);
1057
+ return {
1058
+ dots: visible,
1059
+ lines: lines.filter((l) => (l.a ?? 1) >= .02)
1060
+ };
1061
+ }
1062
+ function radiusScale(size, pow) {
1063
+ return (size / 300) ** pow;
1064
+ }
1065
+ const frameGlobe = (size, t, o) => {
1066
+ const spin = .5;
1067
+ const cx = size / 2;
1068
+ const cy = size / 2;
1069
+ const radius = size / 2 * .82;
1070
+ const tilt = .4 + .06 * Math.sin(t * .35);
1071
+ const pt = makeProj(t * spin, tilt, cx, cy, radius);
1072
+ const scan = t * (spin + (1.7 - spin) * (o.scanMul ?? 1));
1073
+ const rs = radiusScale(size, o.rsPow ?? .6);
1074
+ const dimBase = o.dimBase ?? 1;
1075
+ const dots = [];
1076
+ const latRings = o.latRings ?? 17;
1077
+ const lonDensity = o.lonDensity ?? 44;
1078
+ for (let li = 0; li <= latRings; li++) {
1079
+ const lat = -Math.PI / 2 + li / latRings * Math.PI;
1080
+ const cosLat = Math.cos(lat);
1081
+ const sinLat = Math.sin(lat);
1082
+ const lonCount = Math.max(1, Math.round(Math.abs(cosLat) * lonDensity));
1083
+ for (let lj = 0; lj < lonCount; lj++) {
1084
+ const lon = lj / lonCount * 2 * Math.PI;
1085
+ const [px, py, z] = pt(cosLat * Math.cos(lon), sinLat, cosLat * Math.sin(lon));
1086
+ const depth = (z + 1) / 2;
1087
+ const d = angleDelta(lon + t * spin, scan);
1088
+ const boost = Math.exp(-(d * d) / .18) * Math.max(0, z);
1089
+ dots.push({
1090
+ x: px,
1091
+ y: py,
1092
+ z,
1093
+ r: ((o.rBase ?? .6) + (o.rDepth ?? 1.7) * depth + (o.rBoost ?? 1) * boost) * rs,
1094
+ white: (o.inkFar ?? .62) - (o.inkSpan ?? .54) * depth,
1095
+ a: dimBase + (1 - dimBase) * Math.min(1, boost)
1096
+ });
1097
+ }
1098
+ }
1099
+ return finalizeFrame(dots, [], o.rMin);
1100
+ };
1101
+ function solveCycle(time, count, slotDur, rest) {
1102
+ const tc = time % (2 * count * slotDur + rest);
1103
+ const amount = new Array(count).fill(0);
1104
+ let active = -1;
1105
+ if (tc < 2 * count * slotDur) {
1106
+ const slot = Math.floor(tc / slotDur);
1107
+ const p = (tc - slot * slotDur) / slotDur;
1108
+ const ep = 1 - (1 - Math.min(1, p / .7)) ** 3;
1109
+ if (slot < count) {
1110
+ for (let i = 0; i < slot; i++) amount[i] = 1;
1111
+ amount[slot] = ep;
1112
+ active = slot;
1113
+ } else {
1114
+ const u = 2 * count - 1 - slot;
1115
+ for (let i = 0; i < u; i++) amount[i] = 1;
1116
+ amount[u] = 1 - ep;
1117
+ active = u;
1118
+ }
1119
+ }
1120
+ return {
1121
+ amount,
1122
+ active
1123
+ };
1124
+ }
1125
+ function applyMoves(pt3, moves, sc) {
1126
+ let [x, y, z] = pt3;
1127
+ let inActive = false;
1128
+ for (let i = 0; i < moves.length; i++) {
1129
+ if (sc.amount[i] <= 0) continue;
1130
+ const mv = moves[i];
1131
+ const coord = mv.axis === 0 ? x : mv.axis === 1 ? y : z;
1132
+ if (coord < mv.lo || coord >= mv.hi) continue;
1133
+ if (i === sc.active) inActive = true;
1134
+ const a = mv.ang * sc.amount[i];
1135
+ const ca = Math.cos(a);
1136
+ const sa = Math.sin(a);
1137
+ if (mv.axis === 0) {
1138
+ const y2 = y * ca - z * sa;
1139
+ z = y * sa + z * ca;
1140
+ y = y2;
1141
+ } else if (mv.axis === 1) {
1142
+ const x2 = x * ca + z * sa;
1143
+ z = -x * sa + z * ca;
1144
+ x = x2;
1145
+ } else {
1146
+ const x2 = x * ca - y * sa;
1147
+ y = x * sa + y * ca;
1148
+ x = x2;
1149
+ }
1150
+ }
1151
+ return [
1152
+ x,
1153
+ y,
1154
+ z,
1155
+ inActive
1156
+ ];
1157
+ }
1158
+ function makeMoves(count) {
1159
+ const moves = [];
1160
+ for (let i = 0; i < count; i++) {
1161
+ const axis = Math.min(2, Math.floor(hashD(i, 2.3) * 3));
1162
+ const lo = -1 + .5 * Math.min(3, Math.floor(hashD(i, 5.9) * 4));
1163
+ const dir = hashD(i, 7.7) < .5 ? 1 : -1;
1164
+ moves.push({
1165
+ axis,
1166
+ lo,
1167
+ hi: lo + .5,
1168
+ ang: dir * Math.PI / 2
1169
+ });
1170
+ }
1171
+ return moves;
1172
+ }
1173
+ const frameRubik = (size, t, o) => {
1174
+ const cx = size / 2;
1175
+ const cy = size / 2;
1176
+ const R = size / 2 * .82;
1177
+ const pt = makeProj(t * .55, .35 + .1 * Math.sin(t * .9), cx, cy, R);
1178
+ const rs = radiusScale(size, o.rsPow ?? .6);
1179
+ const moveCount = o.moveCount ?? 14;
1180
+ const moves = makeMoves(moveCount);
1181
+ const sc = solveCycle(t, moveCount, .42, 1.2);
1182
+ const dots = [];
1183
+ const latRings = o.latRings ?? 15;
1184
+ const lonDensity = o.lonDensity ?? 40;
1185
+ for (let li = 0; li <= latRings; li++) {
1186
+ const lat = -Math.PI / 2 + li / latRings * Math.PI;
1187
+ const cosLat = Math.cos(lat);
1188
+ const sinLat = Math.sin(lat);
1189
+ const lonCount = Math.max(1, Math.round(Math.abs(cosLat) * lonDensity));
1190
+ for (let lj = 0; lj < lonCount; lj++) {
1191
+ const lon = lj / lonCount * 2 * Math.PI;
1192
+ const [x, y, z, inActive] = applyMoves([
1193
+ cosLat * Math.cos(lon),
1194
+ sinLat,
1195
+ cosLat * Math.sin(lon)
1196
+ ], moves, sc);
1197
+ const [px, py, zr] = pt(x, y, z);
1198
+ const depth = (zr + 1) / 2;
1199
+ dots.push({
1200
+ x: px,
1201
+ y: py,
1202
+ z: zr,
1203
+ r: ((o.rBase ?? .6) + (o.rDepth ?? 1.7) * depth + (inActive ? o.rActive ?? .3 : 0)) * rs,
1204
+ white: (o.inkFar ?? .62) - (o.inkSpan ?? .54) * depth - (inActive ? .14 : 0)
1205
+ });
1206
+ }
1207
+ }
1208
+ return finalizeFrame(dots, [], o.rMin);
1209
+ };
1210
+ const frameWave = (size, t, o) => {
1211
+ const cx = size / 2;
1212
+ const cy = size / 2;
1213
+ const R = size / 2 * .874;
1214
+ const pt = makeProj(t * .18, .38, cx, cy, 1);
1215
+ const rs = radiusScale(size, o.rsPow ?? .6);
1216
+ const dots = [];
1217
+ const rings = o.rings ?? 15;
1218
+ const lonDensity = o.lonDensity ?? 40;
1219
+ for (let ri = 0; ri <= rings; ri++) {
1220
+ const lat = -Math.PI / 2 + ri / rings * Math.PI;
1221
+ const cosLat = Math.cos(lat);
1222
+ const sinLat = Math.sin(lat);
1223
+ const w = .62 * Math.sin(t * 2.1 - ri * .52) + .38 * Math.sin(t * 1.27 + ri * .83);
1224
+ const rr = R * (.88 + .105 * w);
1225
+ const lonCount = Math.max(1, Math.round(Math.abs(cosLat) * lonDensity));
1226
+ for (let lj = 0; lj < lonCount; lj++) {
1227
+ const lon = lj / lonCount * 2 * Math.PI;
1228
+ const [px, py, z] = pt(cosLat * Math.cos(lon) * rr, sinLat * rr, cosLat * Math.sin(lon) * rr);
1229
+ const depth = (z / R + 1) / 2;
1230
+ const crest = Math.max(0, w);
1231
+ dots.push({
1232
+ x: px,
1233
+ y: py,
1234
+ z,
1235
+ r: ((o.rBase ?? .6) + (o.rDepth ?? 1.7) * depth) * (1 + .4 * crest) * rs,
1236
+ white: .66 - .56 * depth - .1 * crest
1237
+ });
1238
+ }
1239
+ }
1240
+ return finalizeFrame(dots, [], o.rMin);
1241
+ };
1242
+ const frameOrbits = (size, t, o) => {
1243
+ const cx = size / 2;
1244
+ const cy = size / 2;
1245
+ const R = size / 2 * .82;
1246
+ const pt = makeProj(t * .12, .3, cx, cy, 1);
1247
+ const rs = radiusScale(size, o.rsPow ?? .6);
1248
+ const dots = [];
1249
+ const orbitN = o.orbitN ?? 12;
1250
+ const ghostN = o.ghostN ?? 40;
1251
+ const particles = o.particles ?? 3;
1252
+ for (let orb = 0; orb < orbitN; orb++) {
1253
+ const h1 = hashD(orb, 1.7);
1254
+ const h2 = hashD(orb, 5.2);
1255
+ const h3 = hashD(orb, 8.9);
1256
+ const ro = R * (.45 + .52 * h1);
1257
+ const th = h1 * 2 * Math.PI;
1258
+ const phi = Math.acos(2 * h2 - 1);
1259
+ const nx = Math.sin(phi) * Math.cos(th);
1260
+ const ny = Math.cos(phi);
1261
+ const nz = Math.sin(phi) * Math.sin(th);
1262
+ let ux = -ny;
1263
+ let uy = nx;
1264
+ const uz = 0;
1265
+ const ul = Math.max(1e-6, Math.sqrt(ux * ux + uy * uy));
1266
+ ux /= ul;
1267
+ uy /= ul;
1268
+ const vx = ny * uz - nz * uy;
1269
+ const vy = nz * ux - nx * uz;
1270
+ const vz = nx * uy - ny * ux;
1271
+ const speed = (.25 + .55 * h3) * (h3 > .5 ? 1 : -1);
1272
+ for (let k = 0; k < ghostN; k++) {
1273
+ const a = k / ghostN * 2 * Math.PI;
1274
+ const [px, py, z] = pt((ux * Math.cos(a) + vx * Math.sin(a)) * ro, (uy * Math.cos(a) + vy * Math.sin(a)) * ro, (uz * Math.cos(a) + vz * Math.sin(a)) * ro);
1275
+ const depth = (z / ro + 1) / 2;
1276
+ dots.push({
1277
+ x: px,
1278
+ y: py,
1279
+ z,
1280
+ r: (o.ghostR ?? .9) * rs,
1281
+ white: .72,
1282
+ a: (o.ghostA ?? .5) * (.4 + .6 * depth)
1283
+ });
1284
+ }
1285
+ for (let m = 0; m < particles; m++) {
1286
+ const a = t * speed + m / particles * 2 * Math.PI + h2 * 6;
1287
+ const [px, py, z] = pt((ux * Math.cos(a) + vx * Math.sin(a)) * ro, (uy * Math.cos(a) + vy * Math.sin(a)) * ro, (uz * Math.cos(a) + vz * Math.sin(a)) * ro);
1288
+ const depth = (z / ro + 1) / 2;
1289
+ dots.push({
1290
+ x: px,
1291
+ y: py,
1292
+ z,
1293
+ r: ((o.partR ?? 1.2) + (o.partRDepth ?? 1.6) * depth) * rs,
1294
+ white: .3 - .22 * depth
1295
+ });
1296
+ }
1297
+ }
1298
+ return finalizeFrame(dots, [], o.rMin);
1299
+ };
1300
+ const frameRibbon = (size, t, o) => {
1301
+ const cx = size / 2;
1302
+ const cy = size / 2;
1303
+ const R = size / 2 * .78;
1304
+ const spin = o.spin ?? 1;
1305
+ const camTilt = .3;
1306
+ const pt = makeProj(t * .1 * spin, camTilt, cx, cy, 1);
1307
+ const rs = radiusScale(size, o.rsPow ?? .6);
1308
+ const dots = [];
1309
+ const ghostN = o.ghostN ?? 150;
1310
+ for (let i = 0; i < ghostN; i++) {
1311
+ const d = fibDir(i, ghostN);
1312
+ const [px, py, z] = pt(d[0] * R, d[1] * R, d[2] * R);
1313
+ const depth = (z / R + 1) / 2;
1314
+ dots.push({
1315
+ x: px,
1316
+ y: py,
1317
+ z,
1318
+ r: .8 * rs,
1319
+ white: .78,
1320
+ a: .1 + .22 * depth
1321
+ });
1322
+ }
1323
+ const ya = t * .24 * spin;
1324
+ const ta = o.faceOn ? -camTilt : .55 + .3 * Math.sin(t * .18) * spin;
1325
+ const ux = Math.cos(ya);
1326
+ const uy = 0;
1327
+ const uz = Math.sin(ya);
1328
+ const vx = -uz * Math.sin(ta);
1329
+ const vy = Math.cos(ta);
1330
+ const vz = ux * Math.sin(ta);
1331
+ const nx = uy * vz - uz * vy;
1332
+ const ny = uz * vx - ux * vz;
1333
+ const nz = ux * vy - uy * vx;
1334
+ const wobAmp = .23 * (o.wobMul ?? 1);
1335
+ const baseR = o.faceOn ? R / (1 + .85 * wobAmp) : R;
1336
+ const baseLanes = o.lanes ?? 5;
1337
+ const segs = o.segs ?? 88;
1338
+ const lanes = Math.max(1, Math.round(baseLanes * (o.bandMul ?? 1)));
1339
+ for (let w = 0; w < lanes; w++) {
1340
+ const laneOff = (w - (lanes - 1) / 2) * .075;
1341
+ const edge = Math.abs(w - (lanes - 1) / 2) / Math.max(1, (lanes - 1) / 2);
1342
+ for (let k = 0; k < segs; k++) {
1343
+ const a = k / segs * 2 * Math.PI;
1344
+ const wob = (.16 * Math.sin(a * 3 - t * 1.7 + w * .22) + .07 * Math.sin(a * 5 + t * 1.1)) * (o.wobMul ?? 1);
1345
+ const radial = o.faceOn ? 1 + wob : 1;
1346
+ const off$1 = o.faceOn ? laneOff : laneOff + wob;
1347
+ const x = ux * Math.cos(a) + vx * Math.sin(a) + nx * off$1;
1348
+ const y = uy * Math.cos(a) + vy * Math.sin(a) + ny * off$1;
1349
+ const z = uz * Math.cos(a) + vz * Math.sin(a) + nz * off$1;
1350
+ const l = Math.sqrt(x * x + y * y + z * z);
1351
+ const rr = baseR * radial;
1352
+ const [px, py, zr] = pt(x / l * rr, y / l * rr, z / l * rr);
1353
+ const depth = (zr / R + 1) / 2;
1354
+ dots.push({
1355
+ x: px,
1356
+ y: py,
1357
+ z: zr,
1358
+ r: ((o.rBase ?? 1.1) + (o.rDepth ?? 1.7) * depth) * (1 - .25 * edge) * rs,
1359
+ white: .52 - .44 * depth + .18 * edge,
1360
+ a: .4 + .6 * depth
1361
+ });
1362
+ }
1363
+ }
1364
+ return finalizeFrame(dots, [], o.rMin);
1365
+ };
1366
+ function smoothE(x) {
1367
+ return x * x * (3 - 2 * x);
1368
+ }
1369
+ function polyPath(verts) {
1370
+ const V = verts.length;
1371
+ const L = [];
1372
+ let total = 0;
1373
+ for (let i = 0; i < V; i++) {
1374
+ const a = verts[i];
1375
+ const b = verts[(i + 1) % V];
1376
+ const l = Math.hypot(b[0] - a[0], b[1] - a[1]);
1377
+ L.push(l);
1378
+ total += l;
1379
+ }
1380
+ return (f) => {
1381
+ let target = f * total;
1382
+ let i = 0;
1383
+ while (target > L[i] && i < V - 1) {
1384
+ target -= L[i];
1385
+ i++;
1386
+ }
1387
+ const a = verts[i];
1388
+ const b = verts[(i + 1) % V];
1389
+ const ff = L[i] ? Math.min(1, target / L[i]) : 0;
1390
+ return [a[0] + (b[0] - a[0]) * ff, a[1] + (b[1] - a[1]) * ff];
1391
+ };
1392
+ }
1393
+ var CIRCLE = (f) => {
1394
+ const a = -Math.PI / 2 + f * 2 * Math.PI;
1395
+ return [Math.cos(a) * .24, Math.sin(a) * .24];
1396
+ };
1397
+ var CYCLE = [
1398
+ CIRCLE,
1399
+ polyPath([
1400
+ [0, -.26],
1401
+ [.24, .16],
1402
+ [-.24, .16]
1403
+ ]),
1404
+ polyPath([
1405
+ [0, -.2],
1406
+ [.2, -.2],
1407
+ [.2, .2],
1408
+ [-.2, .2],
1409
+ [-.2, -.2]
1410
+ ])
1411
+ ];
1412
+ function morphN(d) {
1413
+ return Math.max(6, Math.round(34 * d));
1414
+ }
1415
+ var HOLD = 1.4;
1416
+ var MORPH = .9;
1417
+ var SEG = HOLD + MORPH;
1418
+ const frameMorph = (size, t, o) => {
1419
+ const K = CYCLE.length;
1420
+ const tc = t % (SEG * K);
1421
+ const k = Math.floor(tc / SEG);
1422
+ const local = tc - k * SEG;
1423
+ const m = local > HOLD ? smoothE((local - HOLD) / MORPH) : 0;
1424
+ const sprd = o.spread ?? 1;
1425
+ const pA = CYCLE[k];
1426
+ const pB = CYCLE[(k + 1) % K];
1427
+ const M = 160;
1428
+ const pts = [];
1429
+ for (let i = 0; i < M; i++) {
1430
+ const f = i / M;
1431
+ const a = pA(f);
1432
+ const b = pB(f);
1433
+ pts.push([(a[0] + (b[0] - a[0]) * m) * sprd, (a[1] + (b[1] - a[1]) * m) * sprd]);
1434
+ }
1435
+ const L = [];
1436
+ let total = 0;
1437
+ for (let i = 0; i < M; i++) {
1438
+ const a = pts[i];
1439
+ const b = pts[(i + 1) % M];
1440
+ const l = Math.hypot(b[0] - a[0], b[1] - a[1]);
1441
+ L.push(l);
1442
+ total += l;
1443
+ }
1444
+ const n = morphN(o.iconD ?? 1);
1445
+ const re = (o.rDot ?? .021) * 1.35 * sprd;
1446
+ const pulse = 1 + .02 * Math.sin(local * 3.1);
1447
+ const dots = [];
1448
+ const c2 = size / 2;
1449
+ let seg = 0;
1450
+ let acc = 0;
1451
+ for (let k2 = 0; k2 < n; k2++) {
1452
+ const target = k2 / n * total;
1453
+ while (acc + L[seg] < target && seg < M - 1) {
1454
+ acc += L[seg];
1455
+ seg++;
1456
+ }
1457
+ const a = pts[seg];
1458
+ const b = pts[(seg + 1) % M];
1459
+ const f = L[seg] ? Math.min(1, (target - acc) / L[seg]) : 0;
1460
+ const x = (a[0] + (b[0] - a[0]) * f) * pulse;
1461
+ const y = (a[1] + (b[1] - a[1]) * f) * pulse;
1462
+ dots.push({
1463
+ x: c2 + x * size,
1464
+ y: c2 + y * size,
1465
+ z: 0,
1466
+ r: Math.max(.35, re * size),
1467
+ white: .1
1468
+ });
1469
+ }
1470
+ return finalizeFrame(dots, [], o.rMin);
1471
+ };
1472
+ const earthPointData = {
1473
+ "20": {
1474
+ rings: 9,
1475
+ flags: "01100000000000000000000000000000100010000100000011000110011000000000011111100000011001001100011000111010"
1476
+ },
1477
+ "32": {
1478
+ rings: 17,
1479
+ flags: "011001001111000000000000000000000100000000000000000000010000000000000000000000000110000010000000101000000000000111000001110000001110000000000001111000011100000000000000000000001110000011110000001000000000000000100000111111000000000000000000100000001111111010100000000000011000000110011111111000000011110000101001111100000011110001111111100011100001111111000000010000"
1480
+ },
1481
+ "48": {
1482
+ rings: 29,
1483
+ flags: "111011111111001011001111111100000000000000101111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000001000000000000001100000000000000000000000001100000000000000000001100000000001100000000000011111000000000000000000001110000000001110100000000001111100000000000000000000011111000000001111010000000000011100000000000000000000001111110000000011110000000000000001100000000000000000000011111111000000011111000000000000000010100000000000000000000111100000000001111100000000000100000000000000000000000000011100000000111111111000001000000000000000000000000000000100000000001111111111000001000100000000000000000000000101001000000001111111111100110110000000000000000000001110010000000001111111111001111111100000000000000000111110000000000111110111111111111000000000000000011111100000000100001111111111110010000000000011111100000000101101111111111100000000000111111010000011111111111111100000000011110100000100111111111110100011111010100010111111111111111010010001011111110001001100001000000110000000"
1484
+ },
1485
+ "64": {
1486
+ rings: 37,
1487
+ flags: "111011111111011110011111111100000001000111111111110000000000000000001101111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000011100000000000010000000000000001000111000000000000000000000000111100000000000011100000000000000011111110000000000000000000000000111100000000000011110100000000000011111110000000000000000000000000001111110000000000111100100000000000000111110000000000000000000000000001111111100000000001111110100000000000000011000000000000000000000000000001111111110000000000111110000000000000000000000001000000000000000000000000111111111000000000011111100000000000000000000100000000000000000000000000001111110000000000001111111000000000000101100000000000000000000000000000000001111100000000000011111111000000000011001000000000000000000000000000000000001100000000011111111111110000010000010000000000000000000000000000000011000000000000011111111111110000011000110000000000000000000000000000011000010000000000111111111111111000110011000000000000000000000000000011000100000000000111111111111110011111111110000000000000000000000011100000000000000011111111111111111111111100000000000000000000011111110000000000001110000111111111111110000000000000000000011111110000000000010000011101111111111000000000000000000011111111000000000010110010111111111111000000000000001111111101000000111111111111111111110000000000001111101110000011111111111111111110000000001111100100000010101111111111110010011111111010100000111111111111111101111010011000011111111111100001110110000001110000001011101000000000000000000"
1488
+ },
1489
+ "96": {
1490
+ rings: 53,
1491
+ flags: "111111111111001111011111111100111110011111111111110000110111000111111111111110000000000001000000111111111111111100000000000000000000000000110111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000001000000000000000000000000011100000000000000000000000000000000000000000000000000001000000000000000000000000011110000000000000000000000000000000000000000000000110000001000000000000000000000000000111100000000000000000011000000000000000000000010000111000000000000000000000000000000000001111100000000000000000111100000000000000000000011111111110000000000000000000000000000000000011111100000000000000001111100000000000000000000011111111110000000000000000000000000000000000000111111100000000000000001111110010000000000000000001111111111000000000000000000000000000000000000001111111100000000000000011111100100000000000000000000111111110000000000000000000000000000000000000001111111110000000000000011111111011000000000000000000001111101000000000000000000000000000000000000000111111111110000000000000001111111100000000000000000000000001101000000000000000000000000000000000000000011111111111100000000000000111111110000000000000000000000000000000100000000000000000000000000000000000000111111111111100000000000000111111100000000000000000000110000000111000000000000000000000000000000000000000111111111111000000000000000111111110000000000000000000101101000111000000000000000000000000000000000000000011111111100000000000000000111111111100000000000000000100110000000000000000000000000000000000000000000000000111111100000000000000000011111111111000000000000000110001000000000000000000000000000000000000000000000000111111000000000000001111111111111111100000000010000010000001000000000000000000000000000000000000000000000011100000000000000111111111111111111100000000000000000000000000000000000000000000000000000000000000011000000000000000000011111111111111111110000000110000011100000000000000000000000000000000000000000001110000000000000000000011111111111111110111000000110001111000000000000000000000000000000000000000001100100010000000000000001111111111111110111110000111101111000000000000000000000000000000000000000011100000000000000000000001111111111111111111100111111111111111000000000000000000000000000000000011100001000000000000000001111111111110111011111111111111111100000000000000000000000000000000111111110000000000000000000111111111111111111111111111111111000000000000000000000000000000111111111000000000000000000111100000011111111111111111111100100000000000000000000000001111111111100000000000000011000000011111011111111111111100100000000000000000000000011111111111000000000000000110100111111001111111111111101000000000000000000000001111111111110000000000000011101110010111111111111111111010000000000000000000111111111101010000000000111111111111111111111111111100000000000000000011111111111111000000000111111111111111111111111111100000000000000011111111011110000000000001111111111111111111110001000000000001111110001100000000000010111111111111111111000100000111111111100100010000000101111111111111111111010001111111111111001000100010111111111111111111110111111001010011000001111111111111111111000001111101110000000101111111100000000010011100000000110000000000011110010000000000000101100000000000000000000"
1492
+ }
1493
+ };
1494
+ var cache = /* @__PURE__ */ new Map();
1495
+ function getEarthPoints(size) {
1496
+ const hit = cache.get(size);
1497
+ if (hit) return hit;
1498
+ const { rings, flags } = earthPointData[size];
1499
+ const points = [];
1500
+ let index$1 = 0;
1501
+ for (let row = 0; row < rings; row++) {
1502
+ const lat = -Math.PI / 2 + (row + .5) / rings * Math.PI;
1503
+ const count = Math.max(1, Math.round(2 * rings * Math.cos(lat)));
1504
+ for (let col = 0; col < count; col++, index$1++) {
1505
+ const lon = -Math.PI + col / count * 2 * Math.PI;
1506
+ const land = flags[index$1] === "1";
1507
+ if (!land && index$1 % 3 !== 0) continue;
1508
+ points.push({
1509
+ x: Math.cos(lat) * Math.cos(lon),
1510
+ y: Math.sin(lat),
1511
+ z: Math.cos(lat) * Math.sin(lon),
1512
+ lon,
1513
+ land
1514
+ });
1515
+ }
1516
+ }
1517
+ cache.set(size, points);
1518
+ return points;
1519
+ }
1520
+ function frameEarth(size, time) {
1521
+ const project = makeProj(35 * Math.PI / 180 - Math.PI / 2 + time * .22, .18, size / 2, size / 2, size * .43);
1522
+ const dots = [];
1523
+ for (const p of getEarthPoints(size)) {
1524
+ const [x, y, z] = project(p.x, p.y, p.z);
1525
+ if (z <= 0) continue;
1526
+ const scan = Math.exp(-Math.pow(angleDelta(p.lon, time * .9), 2) / .08);
1527
+ const edge = Math.min(1, z / .14);
1528
+ dots.push({
1529
+ x,
1530
+ y,
1531
+ z,
1532
+ r: (size <= 32 ? .48 : .52) * (size / 64) ** .25 * (1 + .2 * z + (p.land ? .22 * scan : 0)),
1533
+ white: p.land ? .08 + .2 * (1 - z) : .65,
1534
+ a: edge * (p.land ? .82 + scan * .18 : .2)
1535
+ });
1536
+ }
1537
+ return finalizeFrame(dots, [], .3);
1538
+ }
1539
+ var frames = {
1540
+ searching: frameGlobe,
1541
+ solving: frameRubik,
1542
+ listening: frameWave,
1543
+ working: frameOrbits,
1544
+ composing: frameRibbon,
1545
+ shaping: frameMorph
1546
+ };
1547
+ function createLoadingFrame(animation, size, time) {
1548
+ if (animation === "earth") return frameEarth(size, time);
1549
+ const { speed, opts } = resolvePreset(animation, size);
1550
+ const frame = frames[animation](size, time * speed, opts);
1551
+ if (size === 20 && frame.dots.length > 120) {
1552
+ const count = frame.dots.length;
1553
+ frame.dots = Array.from({ length: 120 }, (_, i) => frame.dots[Math.floor(i * count / 120)]);
1554
+ }
1555
+ return frame;
1556
+ }
1557
+ function paintLoadingFrame(ctx, frame, color) {
1558
+ ctx.fillStyle = color;
1559
+ for (const dot of frame.dots) {
1560
+ ctx.globalAlpha = Math.max(0, Math.min(1, (dot.a ?? 1) * (1 - dot.white)));
1561
+ ctx.beginPath();
1562
+ ctx.arc(dot.x, dot.y, dot.r, 0, Math.PI * 2);
1563
+ ctx.fill();
1564
+ }
1565
+ ctx.globalAlpha = 1;
1566
+ }
1567
+ function useLoadingAnimation(canvas, options, color) {
1568
+ const available = (0, vue.ref)(true);
1569
+ let ctx = null;
1570
+ let raf;
1571
+ let previous;
1572
+ let elapsed = 0;
1573
+ let enabled = true;
1574
+ let inView = true;
1575
+ let reduced = false;
1576
+ let mounted = false;
1577
+ let dpr = 1;
1578
+ let observer;
1579
+ let motion;
1580
+ const stop = () => {
1581
+ if (raf !== void 0) cancelAnimationFrame(raf);
1582
+ raf = void 0;
1583
+ previous = void 0;
1584
+ };
1585
+ const running = () => mounted && ctx && enabled && inView && options().active && !options().paused && !reduced && document.visibilityState !== "hidden";
1586
+ const paint = () => {
1587
+ if (!ctx || !canvas.value) return;
1588
+ const size = normalizeSize(options().size);
1589
+ const ratio = Math.min(2, Math.max(1, window.devicePixelRatio || 1));
1590
+ if (canvas.value.width !== Math.round(size * ratio) || ratio !== dpr) {
1591
+ canvas.value.width = Math.round(size * ratio);
1592
+ canvas.value.height = Math.round(size * ratio);
1593
+ }
1594
+ dpr = ratio;
1595
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
1596
+ ctx.clearRect(0, 0, size, size);
1597
+ try {
1598
+ paintLoadingFrame(ctx, createLoadingFrame(normalizeAnimation(options().animation), size, reduced ? .6 : elapsed), color.value);
1599
+ } catch {
1600
+ available.value = false;
1601
+ ctx = null;
1602
+ stop();
1603
+ }
1604
+ };
1605
+ const tick = (now) => {
1606
+ raf = void 0;
1607
+ if (!running()) {
1608
+ previous = void 0;
1609
+ return;
1610
+ }
1611
+ if (previous !== void 0) elapsed += Math.min(100, now - previous) / 1e3 * normalizeSpeed(options().speed);
1612
+ previous = now;
1613
+ paint();
1614
+ if (running()) raf = requestAnimationFrame(tick);
1615
+ };
1616
+ const sync = () => {
1617
+ if (!mounted) return;
1618
+ if (!running()) stop();
1619
+ if (options().active && inView && enabled && document.visibilityState !== "hidden") paint();
1620
+ if (running() && raf === void 0) raf = requestAnimationFrame(tick);
1621
+ };
1622
+ const motionChange = () => {
1623
+ reduced = motion?.matches ?? false;
1624
+ sync();
1625
+ };
1626
+ (0, vue.watch)(() => [
1627
+ options().active,
1628
+ options().paused,
1629
+ options().animation,
1630
+ options().size,
1631
+ options().speed,
1632
+ color.value
1633
+ ], sync, { flush: "post" });
1634
+ (0, vue.onMounted)(() => {
1635
+ mounted = true;
1636
+ try {
1637
+ ctx = canvas.value?.getContext("2d") ?? null;
1638
+ } catch {
1639
+ ctx = null;
1640
+ }
1641
+ available.value = !!ctx;
1642
+ motion = window.matchMedia?.("(prefers-reduced-motion: reduce)");
1643
+ reduced = motion?.matches ?? false;
1644
+ motion?.addEventListener("change", motionChange);
1645
+ if (typeof IntersectionObserver !== "undefined" && canvas.value) {
1646
+ observer = new IntersectionObserver(([entry]) => {
1647
+ inView = entry.isIntersecting;
1648
+ sync();
1649
+ });
1650
+ observer.observe(canvas.value);
1651
+ }
1652
+ document.addEventListener("visibilitychange", sync);
1653
+ window.addEventListener("resize", sync);
1654
+ sync();
1655
+ });
1656
+ (0, vue.onActivated)(() => {
1657
+ enabled = true;
1658
+ sync();
1659
+ });
1660
+ (0, vue.onDeactivated)(() => {
1661
+ enabled = false;
1662
+ stop();
1663
+ });
1664
+ (0, vue.onScopeDispose)(() => {
1665
+ mounted = false;
1666
+ stop();
1667
+ observer?.disconnect();
1668
+ motion?.removeEventListener("change", motionChange);
1669
+ if (typeof document !== "undefined") document.removeEventListener("visibilitychange", sync);
1670
+ if (typeof window !== "undefined") window.removeEventListener("resize", sync);
1671
+ ctx = null;
1672
+ });
1673
+ return { available };
1674
+ }
1675
+ init_utils();
1676
+ var _hoisted_1$7 = [
1677
+ "role",
1678
+ "aria-live",
1679
+ "aria-hidden",
1680
+ "aria-label"
1681
+ ];
1682
+ var FlLoading_default = /* @__PURE__ */ (0, vue.defineComponent)({
1683
+ name: "FlLoading",
1684
+ __name: "FlLoading",
1685
+ props: flLoadingProps,
1686
+ setup(__props) {
1687
+ const props = __props;
1688
+ const ns = useNamespace("loading");
1689
+ const root = (0, vue.ref)();
1690
+ const canvas = (0, vue.ref)();
1691
+ const resolvedSize = (0, vue.computed)(() => normalizeSize(props.size));
1692
+ const resolvedColor = useLoadingColor(() => root.value, () => props);
1693
+ const { available } = useLoadingAnimation(canvas, () => props, resolvedColor);
1694
+ return (_ctx, _cache) => {
1695
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
1696
+ ref_key: "root",
1697
+ ref: root,
1698
+ class: (0, vue.normalizeClass)([
1699
+ (0, vue.unref)(ns).b(),
1700
+ (0, vue.unref)(ns).m(_ctx.layout),
1701
+ (0, vue.unref)(ns).is("inactive", !_ctx.active)
1702
+ ]),
1703
+ style: (0, vue.normalizeStyle)({ "--fl-loading-size": `${resolvedSize.value}px` }),
1704
+ role: _ctx.active ? "status" : void 0,
1705
+ "aria-live": _ctx.active ? "polite" : "off",
1706
+ "aria-hidden": !_ctx.active || void 0,
1707
+ "aria-label": !_ctx.text && !_ctx.$slots.text ? _ctx.ariaLabel : void 0
1708
+ }, [(0, vue.createElementVNode)("span", {
1709
+ class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("visual")),
1710
+ "aria-hidden": "true"
1711
+ }, [(0, vue.withDirectives)((0, vue.createElementVNode)("canvas", {
1712
+ ref_key: "canvas",
1713
+ ref: canvas,
1714
+ class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("canvas")),
1715
+ style: (0, vue.normalizeStyle)({
1716
+ width: `${resolvedSize.value}px`,
1717
+ height: `${resolvedSize.value}px`
1718
+ })
1719
+ }, null, 6), [[vue.vShow, (0, vue.unref)(available)]]), !(0, vue.unref)(available) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
1720
+ key: 0,
1721
+ class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("fallback")),
1722
+ style: (0, vue.normalizeStyle)({ color: (0, vue.unref)(resolvedColor) })
1723
+ }, "●", 6)) : (0, vue.createCommentVNode)("v-if", true)], 2), _ctx.text || _ctx.$slots.text ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
1724
+ key: 0,
1725
+ class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("text"))
1726
+ }, [(0, vue.renderSlot)(_ctx.$slots, "text", {}, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)(_ctx.text), 1)])], 2)) : (0, vue.createCommentVNode)("v-if", true)], 14, _hoisted_1$7);
1727
+ };
1728
+ }
1729
+ });
1730
+ init_utils();
1731
+ function useFlLoading(active, options = {}) {
1732
+ const ns = useNamespace("loading");
1733
+ const alive = (0, vue.ref)(true);
1734
+ const generation = (0, vue.ref)(0);
1735
+ const resolved = (0, vue.computed)(() => (0, vue.toValue)(options));
1736
+ const color = useLoadingColor(() => (0, vue.toValue)(resolved.value.themeTarget), () => resolved.value);
1737
+ (0, vue.watch)(() => (0, vue.toValue)(active), () => generation.value++, { flush: "sync" });
1738
+ (0, vue.onScopeDispose)(() => {
1739
+ alive.value = false;
1740
+ });
1741
+ const Content = (0, vue.defineComponent)({
1742
+ name: "FlLoadingContent",
1743
+ props: { generation: {
1744
+ type: Number,
1745
+ required: true
1746
+ } },
1747
+ setup(props) {
1748
+ const ownGeneration = props.generation;
1749
+ return () => {
1750
+ const { background: _background, customClass: _customClass, themeTarget: _target, ...visual } = resolved.value;
1751
+ return (0, vue.h)(FlLoading_default, {
1752
+ layout: "vertical",
1753
+ ...visual,
1754
+ color: color.value,
1755
+ active: alive.value && (0, vue.toValue)(active) && ownGeneration === generation.value
1756
+ });
1757
+ };
1758
+ }
1759
+ });
1760
+ return (0, vue.computed)(() => {
1761
+ if (!alive.value || !(0, vue.toValue)(active)) return false;
1762
+ return {
1763
+ text: (0, vue.h)(Content, { generation: generation.value }),
1764
+ customClass: [ns.b("adapter"), resolved.value.customClass].filter(Boolean).join(" "),
1765
+ background: resolved.value.background
1766
+ };
1767
+ });
1768
+ }
1769
+ init_utils();
1770
+ const FlLoading = withInstall(FlLoading_default);
644
1771
  init_dialog();
645
1772
  init_utils();
646
1773
  const FlDialog = withInstall(dialog_default);
@@ -11795,17 +12922,17 @@
11795
12922
  return first || path;
11796
12923
  };
11797
12924
  const createTableProxyDataBuilder = () => {
11798
- const cache = /* @__PURE__ */ new WeakMap();
12925
+ const cache$2 = /* @__PURE__ */ new WeakMap();
11799
12926
  const runtime = {
11800
12927
  onCellChange: () => void 0,
11801
12928
  resolveRowIndex: () => -1,
11802
12929
  rowKeyField: "id",
11803
12930
  maxDepth: 4
11804
12931
  };
11805
- const getCachedProxy = (target, path) => cache.get(target)?.get(path);
12932
+ const getCachedProxy = (target, path) => cache$2.get(target)?.get(path);
11806
12933
  const setCachedProxy = (target, path, proxy) => {
11807
- if (!cache.has(target)) cache.set(target, /* @__PURE__ */ new Map());
11808
- cache.get(target)?.set(path, proxy);
12934
+ if (!cache$2.has(target)) cache$2.set(target, /* @__PURE__ */ new Map());
12935
+ cache$2.get(target)?.set(path, proxy);
11809
12936
  };
11810
12937
  const toNullableRow = (value) => {
11811
12938
  if (!isObjectLike(value)) return null;
@@ -13242,6 +14369,7 @@
13242
14369
  init_hooks();
13243
14370
  init_utils();
13244
14371
  var components = [
14372
+ FlLoading,
13245
14373
  FlBarcode,
13246
14374
  FlButton,
13247
14375
  FlDialog,
@@ -13269,6 +14397,7 @@
13269
14397
  exports.FlInput = FlInput;
13270
14398
  exports.FlInputNumber = FlInputNumber;
13271
14399
  exports.FlInputSearch = FlInputSearch;
14400
+ exports.FlLoading = FlLoading;
13272
14401
  exports.FlQrCode = FlQrCode;
13273
14402
  exports.FlRadialMenu = FlRadialMenu;
13274
14403
  exports.FlRadialMenuItem = FlRadialMenuItem;
@@ -13288,6 +14417,7 @@
13288
14417
  exports.open = open;
13289
14418
  exports.useClearableState = useClearableState;
13290
14419
  exports.useDialog = useDialog;
14420
+ exports.useFlLoading = useFlLoading;
13291
14421
  exports.useMergedAttrs = useMergedAttrs;
13292
14422
  exports.useMergedExpose = useMergedExpose;
13293
14423
  exports.useNamespace = useNamespace;