@tastic/hud 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -130,12 +130,12 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
130
130
  height: canvasSize,
131
131
  width: canvasSize
132
132
  };
133
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native17.View, { style: [styles14.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
134
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
135
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
133
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native17.View, { style: [styles14.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
134
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
135
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
136
136
  ] }) });
137
137
  }
138
- var import_react_native_skia, import_core8, import_react8, import_react_native17, import_react_native_reanimated, import_jsx_runtime15, UNLIT_THICKNESS, LIT_THICKNESS, DASH_GAP_PX, ARC_GAP, DEFAULT_START_DEG, MIN_DASH_ANGLE_DEG, MOUNT_DURATION_MS, MOUNT_STAGGER_MS, SELECTION_TRANSITION_DURATION_MS, styles14;
138
+ var import_react_native_skia, import_core8, import_react8, import_react_native17, import_react_native_reanimated, import_jsx_runtime16, UNLIT_THICKNESS, LIT_THICKNESS, DASH_GAP_PX, ARC_GAP, DEFAULT_START_DEG, MIN_DASH_ANGLE_DEG, MOUNT_DURATION_MS, MOUNT_STAGGER_MS, SELECTION_TRANSITION_DURATION_MS, styles14;
139
139
  var init_TriggerGauge = __esm({
140
140
  "src/TriggerGauge.tsx"() {
141
141
  "use strict";
@@ -144,7 +144,7 @@ var init_TriggerGauge = __esm({
144
144
  import_react8 = require("react");
145
145
  import_react_native17 = require("react-native");
146
146
  import_react_native_reanimated = require("react-native-reanimated");
147
- import_jsx_runtime15 = require("react/jsx-runtime");
147
+ import_jsx_runtime16 = require("react/jsx-runtime");
148
148
  UNLIT_THICKNESS = 3;
149
149
  LIT_THICKNESS = 7;
150
150
  DASH_GAP_PX = 9;
@@ -192,6 +192,7 @@ __export(index_exports, {
192
192
  PressAwayOverlay: () => PressAwayOverlay,
193
193
  ReadyButton: () => ReadyButton,
194
194
  RotatedFrame: () => RotatedFrame,
195
+ SecondaryButton: () => SecondaryButton,
195
196
  SectionedDropdown: () => SectionedDropdown,
196
197
  SharedActionBand: () => SharedActionBand,
197
198
  StaggeredWord: () => StaggeredWord,
@@ -438,7 +439,7 @@ function ActivityStatSection({ stats, fg, fgMuted, sectionBg }) {
438
439
  // src/BaseSettingsDialog.tsx
439
440
  var import_auto_paper7 = require("@rific/auto-paper");
440
441
  var import_core4 = require("@rific/core");
441
- var import_feedback_press2 = require("@rific/feedback-press");
442
+ var import_feedback_press3 = require("@rific/feedback-press");
442
443
  var import_updater = require("@rific/updater");
443
444
  var import_core5 = require("@tastic/core");
444
445
  var import_react6 = require("react");
@@ -448,7 +449,7 @@ var import_react_native_safe_area_context2 = require("react-native-safe-area-con
448
449
 
449
450
  // src/ConfirmDialog.tsx
450
451
  var import_auto_paper6 = require("@rific/auto-paper");
451
- var import_feedback_press = require("@rific/feedback-press");
452
+ var import_feedback_press2 = require("@rific/feedback-press");
452
453
  var import_core2 = require("@tastic/core");
453
454
  var import_react3 = require("react");
454
455
  var import_react_native11 = require("react-native");
@@ -581,6 +582,14 @@ var styles7 = import_react_native9.StyleSheet.create({
581
582
  card: { overflow: "hidden" }
582
583
  });
583
584
 
585
+ // src/SecondaryButton.tsx
586
+ var import_feedback_press = require("@rific/feedback-press");
587
+ var import_jsx_runtime9 = require("react/jsx-runtime");
588
+ function SecondaryButton({ style, ...props }) {
589
+ const { fg } = useOverlayCardColors();
590
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press.Button, { mode: "outlined", textColor: fg, ...props, style: [overlayActionStyles.actionButton, style] });
591
+ }
592
+
584
593
  // src/useCompactDialog.ts
585
594
  var import_core = require("@tastic/core");
586
595
  var import_react2 = require("react");
@@ -599,7 +608,7 @@ function useCompactDialog(rotation = 0) {
599
608
  }
600
609
 
601
610
  // src/ConfirmDialog.tsx
602
- var import_jsx_runtime9 = require("react/jsx-runtime");
611
+ var import_jsx_runtime10 = require("react/jsx-runtime");
603
612
  function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
604
613
  const { colors } = (0, import_auto_paper6.useAutoPaperTheme)();
605
614
  const { fg } = useOverlayCardColors();
@@ -620,12 +629,12 @@ function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onC
620
629
  const accent = destructive ? colors.danger : colors.primary;
621
630
  const onAccent = destructive ? colors.onDanger : colors.onPrimary;
622
631
  const showCancel = cancelLabel !== void 0 && onCancel !== void 0;
623
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper7.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(OverlayBackdrop, { style: styles8.overlay, onLayout, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(OverlayCard, { style: [styles8.card, (0, import_core2.toRotationStyle)(rotation)], children: [
624
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DialogHeader, { icon, title, color: accent, compact }),
625
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper7.Text, { variant: "bodyLarge", style: [styles8.body, { color: fg }], children: message }),
626
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native11.View, { style: overlayActionStyles.actions, children: [
627
- showCancel && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press.Button, { mode: "outlined", onPress: onCancel, style: overlayActionStyles.actionButton, children: cancelLabel }),
628
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_feedback_press.Button, { mode: "contained", onPress: onConfirm, style: showCancel ? overlayActionStyles.actionButton : overlayActionStyles.actionButtonSingle, buttonColor: accent, textColor: onAccent, children: confirmLabel })
632
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper7.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(OverlayBackdrop, { style: styles8.overlay, onLayout, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(OverlayCard, { style: [styles8.card, (0, import_core2.toRotationStyle)(rotation)], children: [
633
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DialogHeader, { icon, title, color: accent, compact }),
634
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper7.Text, { variant: "bodyLarge", style: [styles8.body, { color: fg }], children: message }),
635
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: overlayActionStyles.actions, children: [
636
+ showCancel && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SecondaryButton, { onPress: onCancel, children: cancelLabel }),
637
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: onConfirm, style: showCancel ? overlayActionStyles.actionButton : overlayActionStyles.actionButtonSingle, buttonColor: accent, textColor: onAccent, children: confirmLabel })
629
638
  ] })
630
639
  ] }) }) });
631
640
  }
@@ -656,7 +665,7 @@ var import_react4 = require("react");
656
665
  var import_react_native12 = require("react-native");
657
666
  var import_react_native_paper8 = require("react-native-paper");
658
667
  var import_react_native_safe_area_context = require("react-native-safe-area-context");
659
- var import_jsx_runtime10 = require("react/jsx-runtime");
668
+ var import_jsx_runtime11 = require("react/jsx-runtime");
660
669
  function RotatedFrame({ children, rotation: rotationOverride, rotatedSafeArea = false, portalHost = false, passThrough = false, maxContentWidth }) {
661
670
  const ambientRotation = (0, import_core3.useRotation)();
662
671
  const rotation = rotationOverride ?? ambientRotation;
@@ -665,8 +674,8 @@ function RotatedFrame({ children, rotation: rotationOverride, rotatedSafeArea =
665
674
  const rawInsets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
666
675
  const insets = (0, import_react4.useMemo)(() => rotatedSafeArea ? (0, import_core3.rotateInsets)(rawInsets, rotation) : rawInsets, [rotatedSafeArea, rawInsets, rotation]);
667
676
  const cappedWidth = maxContentWidth !== void 0 && width > height ? maxContentWidth : void 0;
668
- const column = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: [styles9.column, cappedWidth !== void 0 && { maxWidth: cappedWidth }], pointerEvents: passThrough ? "box-none" : void 0, children });
669
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_core3.FakeLandscapeView, { rotation, passThrough, style: styles9.root, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_safe_area_context.SafeAreaInsetsContext.Provider, { value: insets, children: portalHost ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Portal.Host, { children: column }) : column }) });
677
+ const column = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native12.View, { style: [styles9.column, cappedWidth !== void 0 && { maxWidth: cappedWidth }], pointerEvents: passThrough ? "box-none" : void 0, children });
678
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_core3.FakeLandscapeView, { rotation, passThrough, style: styles9.root, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_safe_area_context.SafeAreaInsetsContext.Provider, { value: insets, children: portalHost ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper8.Portal.Host, { children: column }) : column }) });
670
679
  }
671
680
  var styles9 = import_react_native12.StyleSheet.create({
672
681
  // A centred column: full width up to `maxWidth`, so a capped frame sits in the middle of a wider window.
@@ -701,9 +710,9 @@ function useUpdateConfirmBridge() {
701
710
  }
702
711
 
703
712
  // src/BaseSettingsDialog.tsx
704
- var import_jsx_runtime11 = require("react/jsx-runtime");
713
+ var import_jsx_runtime12 = require("react/jsx-runtime");
705
714
  function SettingIcon({ source, color, containerColor }) {
706
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native13.View, { style: [styles10.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Icon, { source, size: 18, color }) });
715
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: [styles10.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Icon, { source, size: 18, color }) });
707
716
  }
708
717
  function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, onShowHowToPlay, children }) {
709
718
  const { colors } = (0, import_auto_paper7.useAutoPaperTheme)();
@@ -715,12 +724,12 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
715
724
  const insets = (0, import_core5.rotateInsets)((0, import_react_native_safe_area_context2.useSafeAreaInsets)(), rotation);
716
725
  const sheetWidth = Math.min(overlayStyles.card.maxWidth, (turned ? window.height : window.width) - 2 * Math.max(insets.left, insets.right, SHEET_GUTTER));
717
726
  const isTouchPrimary = (0, import_core5.useIsTouchPrimaryDevice)();
718
- const { settings: hapticSettings, set: setHapticSettings } = (0, import_feedback_press2.useHapticSettings)();
719
- const { settings: soundSettings, set: setSoundSettings } = (0, import_feedback_press2.useSoundSettings)();
727
+ const { settings: hapticSettings, set: setHapticSettings } = (0, import_feedback_press3.useHapticSettings)();
728
+ const { settings: soundSettings, set: setSoundSettings } = (0, import_feedback_press3.useSoundSettings)();
720
729
  const { settings: keepAwakeSettings, set: setKeepAwakeSettings } = (0, import_core4.useKeepAwakeSettings)();
721
730
  const expoKeepAwake = (0, import_core4.useExpoKeepAwake)();
722
- const sound = (0, import_react6.useContext)(import_feedback_press2.SoundContext);
723
- const { forceShort: forceHapticFeedback } = (0, import_feedback_press2.useVibration)();
731
+ const sound = (0, import_react6.useContext)(import_feedback_press3.SoundContext);
732
+ const { forceShort: forceHapticFeedback } = (0, import_feedback_press3.useVibration)();
724
733
  const { settings: themeSettings, set: setThemeSettings } = (0, import_auto_paper7.useThemeSettings)();
725
734
  const expoBlur = (0, import_auto_paper7.useBlurModule)();
726
735
  const [infoMessage, setInfoMessage] = (0, import_react6.useState)(null);
@@ -744,36 +753,36 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
744
753
  const showBlur = showAppearance && import_react_native13.Platform.OS !== "android" && expoBlur !== void 0 && expoBlur !== null;
745
754
  const showUpdateCheck = import_react_native13.Platform.OS !== "web" && !hideUpdateCheck;
746
755
  if (!opened) return null;
747
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(RotatedFrame, { rotation, rotatedSafeArea: true, portalHost: true, passThrough: true, children: [
748
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_auto_paper7.Dialog, { visible, onDismiss, style: [styles10.dialog, { width: sheetWidth }], children: [
749
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_auto_paper7.Dialog.ScrollArea, { style: styles10.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_auto_paper7.FadingScrollView, { contentContainerStyle: styles10.scrollContent, showsVerticalScrollIndicator: false, children: [
750
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DialogHeader, { icon: "cog", title: "Settings", compact: compactHeader }),
751
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.content, children: [
752
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleGroup, children: [
753
- showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles10.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
754
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.tertiary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.tertiaryContainer : colors.surfaceVariant }),
755
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
756
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
757
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pin current layout" })
756
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(RotatedFrame, { rotation, rotatedSafeArea: true, portalHost: true, passThrough: true, children: [
757
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_auto_paper7.Dialog, { visible, onDismiss, style: [styles10.dialog, { width: sheetWidth }], children: [
758
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_auto_paper7.Dialog.ScrollArea, { style: styles10.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_auto_paper7.FadingScrollView, { contentContainerStyle: styles10.scrollContent, showsVerticalScrollIndicator: false, children: [
759
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DialogHeader, { icon: "cog", title: "Settings", compact: compactHeader }),
760
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.content, children: [
761
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.toggleGroup, children: [
762
+ showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles10.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
763
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.tertiary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.tertiaryContainer : colors.surfaceVariant }),
764
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
765
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
766
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pin current layout" })
758
767
  ] })
759
768
  ] }) }),
760
- showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles10.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
761
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.tertiary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.tertiaryContainer : colors.surfaceVariant }),
762
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
763
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
764
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Require second swipe" })
769
+ showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles10.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
770
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.tertiary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.tertiaryContainer : colors.surfaceVariant }),
771
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
772
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
773
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Require second swipe" })
765
774
  ] })
766
775
  ] }) }),
767
- showKeepAwake && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => setKeepAwakeSettings({ enabled: !keepAwakeSettings.enabled }), style: styles10.toggleButton, accessibilityLabel: `Keep awake ${keepAwakeSettings.enabled ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
768
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: keepAwakeSettings.enabled ? "eye" : "eye-closed", color: keepAwakeSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: keepAwakeSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
769
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
770
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Keep Awake" }),
771
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Stop auto-lock mid-match" })
776
+ showKeepAwake && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => setKeepAwakeSettings({ enabled: !keepAwakeSettings.enabled }), style: styles10.toggleButton, accessibilityLabel: `Keep awake ${keepAwakeSettings.enabled ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
777
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingIcon, { source: keepAwakeSettings.enabled ? "eye" : "eye-closed", color: keepAwakeSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: keepAwakeSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
778
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
779
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Keep Awake" }),
780
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Stop auto-lock mid-match" })
772
781
  ] })
773
782
  ] }) }),
774
- (showSound || showHaptics) && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleRow, children: [
775
- showSound && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
776
- import_feedback_press2.TouchableRipple,
783
+ (showSound || showHaptics) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.toggleRow, children: [
784
+ showSound && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
785
+ import_feedback_press3.TouchableRipple,
777
786
  {
778
787
  soundDisabled: true,
779
788
  onPress: () => {
@@ -783,14 +792,14 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
783
792
  },
784
793
  style: styles10.toggleButtonInRow,
785
794
  accessibilityLabel: `Sound ${soundSettings.enabled ? "on" : "off"}`,
786
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
787
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: soundSettings.enabled ? "volume-high" : "volume-off", color: soundSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: soundSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
788
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Sound" })
795
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
796
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingIcon, { source: soundSettings.enabled ? "volume-high" : "volume-off", color: soundSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: soundSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
797
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Sound" })
789
798
  ] })
790
799
  }
791
800
  ),
792
- showHaptics && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
793
- import_feedback_press2.TouchableRipple,
801
+ showHaptics && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
802
+ import_feedback_press3.TouchableRipple,
794
803
  {
795
804
  hapticDisabled: true,
796
805
  onPress: () => {
@@ -800,15 +809,15 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
800
809
  },
801
810
  style: styles10.toggleButtonInRow,
802
811
  accessibilityLabel: `Haptics ${hapticSettings.vibrate ? "on" : "off"}`,
803
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
804
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: hapticSettings.vibrate ? "vibrate" : "vibrate-off", color: hapticSettings.vibrate ? colors.tertiary : colors.onSurfaceVariant, containerColor: hapticSettings.vibrate ? colors.tertiaryContainer : colors.surfaceVariant }),
805
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Haptics" })
812
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
813
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingIcon, { source: hapticSettings.vibrate ? "vibrate" : "vibrate-off", color: hapticSettings.vibrate ? colors.tertiary : colors.onSurfaceVariant, containerColor: hapticSettings.vibrate ? colors.tertiaryContainer : colors.surfaceVariant }),
814
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Haptics" })
806
815
  ] })
807
816
  }
808
817
  )
809
818
  ] }),
810
- onShowHowToPlay && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
811
- import_feedback_press2.TouchableRipple,
819
+ onShowHowToPlay && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
820
+ import_feedback_press3.TouchableRipple,
812
821
  {
813
822
  onPress: () => {
814
823
  onDismiss();
@@ -816,42 +825,42 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
816
825
  },
817
826
  style: styles10.toggleButton,
818
827
  accessibilityLabel: "How to Play",
819
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
820
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: "help-circle-outline", color: colors.secondary, containerColor: colors.secondaryContainer }),
821
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
822
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "How to Play" }),
823
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Replay quick intro" })
828
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
829
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingIcon, { source: "help-circle-outline", color: colors.secondary, containerColor: colors.secondaryContainer }),
830
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
831
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "How to Play" }),
832
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Replay quick intro" })
824
833
  ] })
825
834
  ] })
826
835
  }
827
836
  )
828
837
  ] }),
829
- showAppearance && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.section, children: [
830
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "labelMedium", style: [styles10.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
831
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_auto_paper7.AutoAppearancePicker, { showLabels: false }),
832
- showBlur && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => setThemeSettings({ blur: !themeSettings.blur }), style: styles10.toggleButton, accessibilityLabel: `Blur ${themeSettings.blur ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
833
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingIcon, { source: themeSettings.blur ? "blur" : "blur-off", color: themeSettings.blur ? colors.tertiary : colors.onSurfaceVariant, containerColor: themeSettings.blur ? colors.tertiaryContainer : colors.surfaceVariant }),
834
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
835
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Blur" }),
836
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Frost behind dialogs" })
838
+ showAppearance && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.section, children: [
839
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "labelMedium", style: [styles10.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
840
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_auto_paper7.AutoAppearancePicker, { showLabels: false }),
841
+ showBlur && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => setThemeSettings({ blur: !themeSettings.blur }), style: styles10.toggleButton, accessibilityLabel: `Blur ${themeSettings.blur ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.toggleContent, children: [
842
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingIcon, { source: themeSettings.blur ? "blur" : "blur-off", color: themeSettings.blur ? colors.tertiary : colors.onSurfaceVariant, containerColor: themeSettings.blur ? colors.tertiaryContainer : colors.surfaceVariant }),
843
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.flexShrink, children: [
844
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Blur" }),
845
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper9.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Frost behind dialogs" })
837
846
  ] })
838
847
  ] }) })
839
848
  ] }),
840
849
  children,
841
- showUpdateCheck && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: styles10.section, children: [
842
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native_paper9.Text, { variant: "labelMedium", style: [styles10.sectionLabel, { color: colors.onSurfaceVariant }], children: [
850
+ showUpdateCheck && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native13.View, { style: styles10.section, children: [
851
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native_paper9.Text, { variant: "labelMedium", style: [styles10.sectionLabel, { color: colors.onSurfaceVariant }], children: [
843
852
  "VERSION ",
844
853
  version,
845
854
  updateReady ? " \xB7 UPDATE READY" : ""
846
855
  ] }),
847
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: check, loading: checking, disabled: checking, children: "Check for Updates" })
856
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.Button, { mode: "outlined", onPress: check, loading: checking, disabled: checking, children: "Check for Updates" })
848
857
  ] })
849
858
  ] })
850
859
  ] }) }),
851
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native13.View, { style: [overlayActionStyles.actions, styles10.footer], children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: onDismiss, style: overlayActionStyles.actionButtonSingle, buttonColor: colors.primary, textColor: colors.onPrimary, children: "Done" }) })
860
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native13.View, { style: [overlayActionStyles.actions, styles10.footer], children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: onDismiss, style: overlayActionStyles.actionButtonSingle, buttonColor: colors.primary, textColor: colors.onPrimary, children: "Done" }) })
852
861
  ] }),
853
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ConfirmDialog, { visible: !!updateManifest, title: "Update Available", message: updateManifestDate ? `Released ${updateManifestDate.toLocaleDateString()} at ${updateManifestDate.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation: 0, onConfirm: () => respondToUpdateConfirm(true), onCancel: () => respondToUpdateConfirm(false) }),
854
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ConfirmDialog, { visible: !!infoMessage, title: infoMessage?.title ?? "", message: infoMessage?.message ?? "", confirmLabel: "OK", icon: "information-outline", rotation: 0, onConfirm: () => setInfoMessage(null), onCancel: () => setInfoMessage(null) })
862
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ConfirmDialog, { visible: !!updateManifest, title: "Update Available", message: updateManifestDate ? `Released ${updateManifestDate.toLocaleDateString()} at ${updateManifestDate.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation: 0, onConfirm: () => respondToUpdateConfirm(true), onCancel: () => respondToUpdateConfirm(false) }),
863
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ConfirmDialog, { visible: !!infoMessage, title: infoMessage?.title ?? "", message: infoMessage?.message ?? "", confirmLabel: "OK", icon: "information-outline", rotation: 0, onConfirm: () => setInfoMessage(null), onCancel: () => setInfoMessage(null) })
855
864
  ] }) });
856
865
  }
857
866
  var SHEET_GUTTER = 24;
@@ -940,12 +949,12 @@ var styles10 = import_react_native13.StyleSheet.create({
940
949
 
941
950
  // src/BaseStatsScreen.tsx
942
951
  var import_auto_paper8 = require("@rific/auto-paper");
943
- var import_feedback_press3 = require("@rific/feedback-press");
952
+ var import_feedback_press4 = require("@rific/feedback-press");
944
953
  var import_core6 = require("@tastic/core");
945
954
  var import_react7 = require("react");
946
955
  var import_react_native14 = require("react-native");
947
956
  var import_react_native_paper10 = require("react-native-paper");
948
- var import_jsx_runtime12 = require("react/jsx-runtime");
957
+ var import_jsx_runtime13 = require("react/jsx-runtime");
949
958
  function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", titleVariant = "headlineSmall", onBack, backLabel = "Back", hitSlop, insets, onReset, resetLabel = "Reset All Stats", resetConfirmTitle = "Reset Everything?", resetConfirmBody = "This permanently erases all stats and achievements. This cannot be undone.", fg: fgOverride, bg: bgOverride, children }) {
950
959
  const { dark, colors } = (0, import_auto_paper8.useAutoPaperTheme)();
951
960
  const ambientRotation = (0, import_core6.useRotation)();
@@ -954,16 +963,16 @@ function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", t
954
963
  const showReset = !!onReset;
955
964
  const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
956
965
  const bg = bgOverride ?? (dark ? "#000000" : "#FFFFFF");
957
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native14.View, { style: [styles11.container, { backgroundColor: bg }], children: [
958
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native14.View, { style: [styles11.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
959
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, hitSlop, onPress: onBack, accessibilityLabel: backLabel }),
960
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_paper10.Text, { variant: titleVariant, style: [styles11.title, { color: fg }], children: title })
966
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: [styles11.container, { backgroundColor: bg }], children: [
967
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native14.View, { style: [styles11.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
968
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press4.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, hitSlop, onPress: onBack, accessibilityLabel: backLabel }),
969
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper10.Text, { variant: titleVariant, style: [styles11.title, { color: fg }], children: title })
961
970
  ] }),
962
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_auto_paper8.FadingScrollView, { style: styles11.scrollView, contentContainerStyle: [styles11.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
971
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_auto_paper8.FadingScrollView, { style: styles11.scrollView, contentContainerStyle: [styles11.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
963
972
  children,
964
- showReset && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.danger, textColor: colors.onDanger, style: styles11.resetButton, children: resetLabel })
973
+ showReset && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_feedback_press4.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.danger, textColor: colors.onDanger, style: styles11.resetButton, children: resetLabel })
965
974
  ] }),
966
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
975
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
967
976
  ConfirmDialog,
968
977
  {
969
978
  visible: confirmResetVisible,
@@ -1016,14 +1025,14 @@ var styles11 = import_react_native14.StyleSheet.create({
1016
1025
  // src/ContentGutter.tsx
1017
1026
  var import_core7 = require("@tastic/core");
1018
1027
  var import_react_native15 = require("react-native");
1019
- var import_jsx_runtime13 = require("react/jsx-runtime");
1028
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1020
1029
  function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
1021
1030
  const { width: windowWidth } = (0, import_core7.useRotatedWindowDimensions)();
1022
1031
  const { contentWidth, gutterWidth } = (0, import_core7.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
1023
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native15.View, { style: [styles12.row, style], children: [
1024
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.View, { style: [styles12.gutter, { width: gutterWidth }], children: leftGutter }),
1025
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.View, { style: { width: contentWidth }, children }),
1026
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.View, { style: [styles12.gutter, { width: gutterWidth }], children: rightGutter })
1032
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: [styles12.row, style], children: [
1033
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.View, { style: [styles12.gutter, { width: gutterWidth }], children: leftGutter }),
1034
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.View, { style: { width: contentWidth }, children }),
1035
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.View, { style: [styles12.gutter, { width: gutterWidth }], children: rightGutter })
1027
1036
  ] });
1028
1037
  }
1029
1038
  var styles12 = import_react_native15.StyleSheet.create({
@@ -1043,14 +1052,14 @@ var import_react_native20 = require("react-native");
1043
1052
 
1044
1053
  // src/SectionedDropdown.tsx
1045
1054
  var import_auto_paper9 = require("@rific/auto-paper");
1046
- var import_feedback_press4 = require("@rific/feedback-press");
1055
+ var import_feedback_press5 = require("@rific/feedback-press");
1047
1056
  var import_core9 = require("@tastic/core");
1048
1057
  var import_react_native19 = require("react-native");
1049
1058
  var import_react_native_paper11 = require("react-native-paper");
1050
1059
 
1051
1060
  // src/PopoverBody.tsx
1052
1061
  var import_react_native16 = require("react-native");
1053
- var import_jsx_runtime14 = require("react/jsx-runtime");
1062
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1054
1063
  var CARET_SIZE = 7;
1055
1064
  var CARET_RING_OFFSET = 2;
1056
1065
  var CARET_DIP = 1;
@@ -1064,11 +1073,11 @@ function PopoverBody({ visible, children, align = "center", verticalAlign = "bel
1064
1073
  const caretFill = above ? "borderTopColor" : "borderBottomColor";
1065
1074
  const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
1066
1075
  const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
1067
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native16.View, { style: [styles13.content, alignStyle, verticalStyle], children: [
1076
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: [styles13.content, alignStyle, verticalStyle], children: [
1068
1077
  children,
1069
- caretColor && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1070
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native16.View, { style: [styles13.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
1071
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native16.View, { style: [styles13.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
1078
+ caretColor && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
1079
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.View, { style: [styles13.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
1080
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.View, { style: [styles13.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
1072
1081
  ] })
1073
1082
  ] });
1074
1083
  }
@@ -1123,10 +1132,10 @@ function loadSkiaWeb() {
1123
1132
  }
1124
1133
 
1125
1134
  // src/TriggerGaugeHost.tsx
1126
- var import_jsx_runtime16 = require("react/jsx-runtime");
1135
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1127
1136
  var LazyTriggerGauge = (0, import_react9.lazy)(() => loadSkiaWeb().then(() => Promise.resolve().then(() => (init_TriggerGauge(), TriggerGauge_exports)).then((mod) => ({ default: mod.TriggerGauge }))));
1128
1137
  function TriggerGaugeHost(props) {
1129
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react9.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(LazyTriggerGauge, { ...props }) });
1138
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react9.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(LazyTriggerGauge, { ...props }) });
1130
1139
  }
1131
1140
 
1132
1141
  // src/useAutoAlign.ts
@@ -1142,7 +1151,7 @@ function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
1142
1151
  const [newDx, newDy, newWidth, newHeight] = rotation === 180 ? [-dx, -dy, width, height] : rotation === 90 ? [-dy, dx, height, width] : [dy, -dx, height, width];
1143
1152
  return { x: cx + newDx - newWidth / 2, y: cy + newDy - newHeight / 2, width: newWidth, height: newHeight };
1144
1153
  }
1145
- function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
1154
+ function useAutoAlign(open, contentWidth, contentHeight, rotation = 0, bounds) {
1146
1155
  const triggerRef = (0, import_react10.useRef)(null);
1147
1156
  const { width: windowWidth, height: windowHeight } = (0, import_react_native18.useWindowDimensions)();
1148
1157
  const [align, setAlign] = (0, import_react10.useState)("center");
@@ -1154,31 +1163,39 @@ function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
1154
1163
  setPrevOpen(open);
1155
1164
  if (open) setMeasured(false);
1156
1165
  }
1157
- const measure = (0, import_react10.useCallback)(() => {
1158
- triggerRef.current?.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
1166
+ (0, import_react10.useEffect)(() => {
1167
+ if (!open) return;
1168
+ const place = (limits) => (rawX, rawY, rawWidth, rawHeight) => {
1159
1169
  const { x, y, width: triggerWidth, height: triggerHeight } = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
1160
1170
  const centerX = x + triggerWidth / 2;
1161
- const overflowsRight = centerX + contentWidth / 2 > windowWidth - EDGE_MARGIN;
1162
- const overflowsLeft = centerX - contentWidth / 2 < EDGE_MARGIN;
1171
+ const overflowsRight = centerX + contentWidth / 2 > limits.right - EDGE_MARGIN;
1172
+ const overflowsLeft = centerX - contentWidth / 2 < limits.left + EDGE_MARGIN;
1163
1173
  if (overflowsRight && !overflowsLeft) setAlign("right");
1164
1174
  else if (overflowsLeft && !overflowsRight) setAlign("left");
1165
1175
  else setAlign("center");
1166
- const roomBelow = windowHeight - (y + triggerHeight) - EDGE_MARGIN;
1167
- const roomAbove = y - EDGE_MARGIN;
1176
+ const roomBelow = limits.bottom - (y + triggerHeight) - EDGE_MARGIN;
1177
+ const roomAbove = y - limits.top - EDGE_MARGIN;
1168
1178
  const above = contentHeight > roomBelow && roomAbove > roomBelow;
1169
1179
  setVerticalAlign(above ? "above" : "below");
1170
1180
  setMaxHeight(Math.max(above ? roomAbove : roomBelow, 0));
1171
1181
  setMeasured(true);
1182
+ };
1183
+ const screen = { left: 0, top: 0, right: windowWidth, bottom: windowHeight };
1184
+ const boundsView = bounds?.current;
1185
+ if (!boundsView) {
1186
+ triggerRef.current?.measureInWindow(place(screen));
1187
+ return;
1188
+ }
1189
+ boundsView.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
1190
+ const b = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
1191
+ triggerRef.current?.measureInWindow(place({ left: Math.max(b.x, 0), top: Math.max(b.y, 0), right: Math.min(b.x + b.width, windowWidth), bottom: Math.min(b.y + b.height, windowHeight) }));
1172
1192
  });
1173
- }, [contentWidth, contentHeight, windowWidth, windowHeight, rotation]);
1174
- (0, import_react10.useEffect)(() => {
1175
- if (open) measure();
1176
- }, [open, measure]);
1193
+ }, [open, contentWidth, contentHeight, windowWidth, windowHeight, rotation, bounds]);
1177
1194
  return { align, maxHeight, measured, triggerRef, verticalAlign };
1178
1195
  }
1179
1196
 
1180
1197
  // src/SectionedDropdown.tsx
1181
- var import_jsx_runtime17 = require("react/jsx-runtime");
1198
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1182
1199
  var MENU_BORDER_WIDTH = 1;
1183
1200
  var TRIGGER_SIZE = 44;
1184
1201
  var MENU_MIN_WIDTH = 200;
@@ -1231,14 +1248,14 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
1231
1248
  const anchorStyle = [styles15.anchor, open && styles15.anchorOpen];
1232
1249
  const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
1233
1250
  const dividerStyle = { backgroundColor: menuBorderColor };
1234
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { style: anchorStyle, children: [
1235
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { ref: triggerRef, collapsable: false, style: styles15.triggerBox, children: [
1236
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
1237
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press4.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
1251
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: anchorStyle, children: [
1252
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { ref: triggerRef, collapsable: false, style: styles15.triggerBox, children: [
1253
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
1254
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press5.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
1238
1255
  ] }),
1239
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native19.ScrollView, { style: [styles15.menu, menuStyle], contentContainerStyle: styles15.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { children: [
1240
- sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native19.View, { style: [styles15.divider, dividerStyle] }),
1241
- section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1256
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native19.ScrollView, { style: [styles15.menu, menuStyle], contentContainerStyle: styles15.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { children: [
1257
+ sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native19.View, { style: [styles15.divider, dividerStyle] }),
1258
+ section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1242
1259
  SingleSection,
1243
1260
  {
1244
1261
  section,
@@ -1251,7 +1268,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
1251
1268
  if (autoDismiss) host.close();
1252
1269
  }
1253
1270
  }
1254
- ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
1271
+ ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
1255
1272
  ] }, section.id)) }) })
1256
1273
  ] });
1257
1274
  }
@@ -1263,18 +1280,18 @@ function SingleSection({
1263
1280
  labelFontFamily,
1264
1281
  onSelect
1265
1282
  }) {
1266
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: section.options.map((option) => {
1283
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: section.options.map((option) => {
1267
1284
  const selected = option.value === section.value;
1268
1285
  const taken = !selected && option.value === section.takenValue;
1269
1286
  const rowColor = selected ? onAccentColor : mutedColor;
1270
1287
  const itemStyle = [styles15.item, selected && { backgroundColor: accentColor }, taken && styles15.itemTaken];
1271
1288
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
1272
1289
  const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
1273
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press4.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { style: styles15.itemRow, children: [
1274
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper11.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1275
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { style: styles15.itemLabelColumn, children: [
1276
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper11.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
1277
- option.description && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper11.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
1290
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press5.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: styles15.itemRow, children: [
1291
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1292
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: styles15.itemLabelColumn, children: [
1293
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
1294
+ option.description && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
1278
1295
  ] })
1279
1296
  ] }) }, option.value);
1280
1297
  }) });
@@ -1288,7 +1305,7 @@ function MultiSection({
1288
1305
  allClearLabels
1289
1306
  }) {
1290
1307
  const allSelected = section.value.length === section.options.length;
1291
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1308
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
1292
1309
  section.options.map((option, i) => {
1293
1310
  const selected = section.value.includes(option.value);
1294
1311
  const rowColor = selected ? onAccentColor : mutedColor;
@@ -1296,12 +1313,12 @@ function MultiSection({
1296
1313
  const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
1297
1314
  const itemStyle = [styles15.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
1298
1315
  const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
1299
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { style: styles15.itemRow, children: [
1300
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper11.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1301
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper11.Text, { variant: "labelLarge", style: [styles15.itemLabelFlex, labelStyle], children: option.label })
1316
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press5.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: styles15.itemRow, children: [
1317
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
1318
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Text, { variant: "labelLarge", style: [styles15.itemLabelFlex, labelStyle], children: option.label })
1302
1319
  ] }) }, option.value);
1303
1320
  }),
1304
- section.allClear && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles15.item, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper11.Text, { variant: "labelLarge", style: [styles15.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
1321
+ section.allClear && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press5.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles15.item, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_paper11.Text, { variant: "labelLarge", style: [styles15.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
1305
1322
  ] });
1306
1323
  }
1307
1324
  var styles15 = import_react_native19.StyleSheet.create({
@@ -1374,21 +1391,21 @@ var styles15 = import_react_native19.StyleSheet.create({
1374
1391
  });
1375
1392
 
1376
1393
  // src/ControlSchemePicker.tsx
1377
- var import_jsx_runtime18 = require("react/jsx-runtime");
1394
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1378
1395
  function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily }) {
1379
1396
  const isTouchPrimary = (0, import_core10.useIsTouchPrimaryDevice)();
1380
1397
  if (import_react_native20.Platform.OS !== "web" || isTouchPrimary) return null;
1381
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily });
1398
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily });
1382
1399
  }
1383
1400
 
1384
1401
  // src/CornerActionButtons.tsx
1385
- var import_feedback_press5 = require("@rific/feedback-press");
1402
+ var import_feedback_press6 = require("@rific/feedback-press");
1386
1403
  var import_react_native21 = require("react-native");
1387
- var import_jsx_runtime19 = require("react/jsx-runtime");
1404
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1388
1405
  function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow-left", backLabel = "Back", hitSlop }) {
1389
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
1390
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_feedback_press5.IconButton, { icon: backIcon, iconColor: fg, size: 24, style: [styles16.back, { top: 8 + insets.top, left: 8 + insets.left }], hitSlop, onPress: onBack, accessibilityLabel: backLabel }),
1391
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_feedback_press5.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles16.topRight, { top: 8 + insets.top, right: 8 + insets.right }], hitSlop, onPress: onSettings, accessibilityLabel: "Settings" })
1406
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
1407
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_feedback_press6.IconButton, { icon: backIcon, iconColor: fg, size: 24, style: [styles16.back, { top: 8 + insets.top, left: 8 + insets.left }], hitSlop, onPress: onBack, accessibilityLabel: backLabel }),
1408
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_feedback_press6.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles16.topRight, { top: 8 + insets.top, right: 8 + insets.right }], hitSlop, onPress: onSettings, accessibilityLabel: "Settings" })
1392
1409
  ] });
1393
1410
  }
1394
1411
  var styles16 = import_react_native21.StyleSheet.create({
@@ -1403,17 +1420,17 @@ var styles16 = import_react_native21.StyleSheet.create({
1403
1420
  // src/CornerStatusBadges.tsx
1404
1421
  var import_react_native22 = require("react-native");
1405
1422
  var import_react_native_paper12 = require("react-native-paper");
1406
- var import_jsx_runtime20 = require("react/jsx-runtime");
1423
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1407
1424
  var BADGE_SIZE = 30;
1408
1425
  function StatusBadge({ icon }) {
1409
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: styles17.badge, children: icon && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_paper12.Icon, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
1426
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native22.View, { style: styles17.badge, children: icon && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper12.Icon, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
1410
1427
  }
1411
1428
  function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
1412
1429
  const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
1413
1430
  const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
1414
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
1415
- p1 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { pointerEvents: "none", style: p1OnRightSide ? styles17.bottomRight : styles17.bottomLeft, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StatusBadge, { icon: p1.icon }) }),
1416
- p2 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { pointerEvents: "none", style: p2OnLeftSide ? styles17.topLeft : styles17.topRight, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StatusBadge, { icon: p2.icon }) })
1431
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
1432
+ p1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native22.View, { pointerEvents: "none", style: p1OnRightSide ? styles17.bottomRight : styles17.bottomLeft, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { icon: p1.icon }) }),
1433
+ p2 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native22.View, { pointerEvents: "none", style: p2OnLeftSide ? styles17.topLeft : styles17.topRight, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusBadge, { icon: p2.icon }) })
1417
1434
  ] });
1418
1435
  }
1419
1436
  var styles17 = import_react_native22.StyleSheet.create({
@@ -1436,14 +1453,15 @@ var styles17 = import_react_native22.StyleSheet.create({
1436
1453
 
1437
1454
  // src/InlineColorPicker.tsx
1438
1455
  var import_auto_paper10 = require("@rific/auto-paper");
1439
- var import_feedback_press6 = require("@rific/feedback-press");
1456
+ var import_feedback_press7 = require("@rific/feedback-press");
1440
1457
  var import_core11 = require("@tastic/core");
1441
1458
  var import_react_native23 = require("react-native");
1442
1459
  var import_react_native_paper13 = require("react-native-paper");
1443
- var import_jsx_runtime21 = require("react/jsx-runtime");
1460
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1444
1461
  var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
1445
1462
  var DEFAULT_SIZE = 48;
1446
1463
  var SWATCH_SIZE = 28;
1464
+ var SWATCH_RING_WIDTH = 2;
1447
1465
  var SWATCHES_PADDING = 8;
1448
1466
  var SWATCHES_GAP = 6;
1449
1467
  var SWATCHES_BORDER_WIDTH = 2;
@@ -1461,14 +1479,17 @@ function getInlineColorPickerContentSize(swatchCount, windowWidth, columns) {
1461
1479
  const height = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * rows + SWATCHES_GAP * (rows - 1);
1462
1480
  return { width, height };
1463
1481
  }
1464
- function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper10.defaultColors, takenValue, allowSwapTaken, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
1482
+ function SwatchDrawing({ size, children }) {
1483
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native23.View, { style: [styles18.drawing, { borderRadius: size / 2, height: size, width: size }], children });
1484
+ }
1485
+ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper10.defaultColors, takenValue, allowSwapTaken, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE, renderSwatch, bounds }) {
1465
1486
  const ambientRotation = (0, import_core11.useRotation)();
1466
1487
  const rotation = rotationOverride ?? ambientRotation;
1467
1488
  const menuBg = dark ? "#000000" : "#FFFFFF";
1468
1489
  const { width: windowWidth } = (0, import_react_native23.useWindowDimensions)();
1469
1490
  const { width: swatchesWidth, height: swatchesHeight } = getInlineColorPickerContentSize(swatches.length, windowWidth, columns);
1470
1491
  const open = host.openId === id;
1471
- const auto = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation);
1492
+ const auto = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation, bounds);
1472
1493
  const placement = alignOverride ?? auto;
1473
1494
  const { maxHeight, measured, triggerRef, verticalAlign } = placement;
1474
1495
  const align = forcedAlign ?? placement.align;
@@ -1476,15 +1497,23 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
1476
1497
  const displayValue = displayFor(value);
1477
1498
  const contrastColor = (0, import_auto_paper10.getContrastColor)(displayValue);
1478
1499
  const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
1479
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_native23.View, { style: [styles18.anchor, open && styles18.anchorOpen], children: [
1480
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_feedback_press6.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles18.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native23.View, { ref: triggerRef, collapsable: false, style: styles18.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper13.Text, { style: [styles18.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper13.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
1481
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native23.ScrollView, { style: [styles18.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles18.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
1500
+ const triggerDrawing = renderSwatch?.(displayValue, size, "trigger") ?? null;
1501
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native23.View, { style: [styles18.anchor, open && styles18.anchorOpen], children: [
1502
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles18.trigger, triggerDrawing === null && { backgroundColor: displayValue }, { borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native23.View, { ref: triggerRef, collapsable: false, style: styles18.triggerMeasure, children: [
1503
+ triggerDrawing !== null && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SwatchDrawing, { size, children: triggerDrawing }),
1504
+ tag ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Text, { style: [styles18.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: icon, size: size * 0.6, color: contrastColor })
1505
+ ] }) }),
1506
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native23.ScrollView, { style: [styles18.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles18.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
1482
1507
  const selected = swatch.value.toLowerCase() === value.toLowerCase();
1483
1508
  const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
1484
1509
  const swappable = taken && allowSwapTaken;
1485
1510
  const swatchDisplay = displayFor(swatch.value);
1486
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1487
- import_feedback_press6.TouchableRipple,
1511
+ const contrast = (0, import_auto_paper10.getContrastColor)(swatchDisplay);
1512
+ const drawnSize = selected ? SWATCH_SIZE - 2 * SWATCH_RING_WIDTH : SWATCH_SIZE;
1513
+ const drawing = renderSwatch?.(swatchDisplay, drawnSize, "swatch") ?? null;
1514
+ const mark = selected ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: "check", size: 16, color: contrast }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: "swap-horizontal", size: 16, color: contrast }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper13.Icon, { source: "close", size: 16, color: contrast }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native23.View, {});
1515
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1516
+ import_feedback_press7.TouchableRipple,
1488
1517
  {
1489
1518
  disabled: taken && !swappable,
1490
1519
  onPress: () => {
@@ -1492,8 +1521,11 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
1492
1521
  if (autoDismiss) host.close();
1493
1522
  },
1494
1523
  borderless: true,
1495
- style: [styles18.swatch, { backgroundColor: swatchDisplay }, selected && styles18.swatchSelected, taken && !swappable && styles18.swatchTaken],
1496
- children: selected ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper13.Icon, { source: "check", size: 16, color: (0, import_auto_paper10.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper13.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper10.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native_paper13.Icon, { source: "close", size: 16, color: (0, import_auto_paper10.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native23.View, {})
1524
+ style: [styles18.swatch, drawing === null && { backgroundColor: swatchDisplay }, selected && styles18.swatchSelected, taken && !swappable && styles18.swatchTaken],
1525
+ children: drawing !== null ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native23.View, { style: styles18.swatchFace, children: [
1526
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SwatchDrawing, { size: drawnSize, children: drawing }),
1527
+ mark
1528
+ ] }) : mark
1497
1529
  },
1498
1530
  swatch.value
1499
1531
  );
@@ -1510,6 +1542,14 @@ var styles18 = import_react_native23.StyleSheet.create({
1510
1542
  anchorOpen: {
1511
1543
  zIndex: 100
1512
1544
  },
1545
+ // A renderSwatch drawing (see SwatchDrawing).
1546
+ drawing: {
1547
+ left: 0,
1548
+ overflow: "hidden",
1549
+ pointerEvents: "none",
1550
+ position: "absolute",
1551
+ top: 0
1552
+ },
1513
1553
  swatch: {
1514
1554
  alignItems: "center",
1515
1555
  borderRadius: SWATCH_SIZE / 2,
@@ -1517,9 +1557,19 @@ var styles18 = import_react_native23.StyleSheet.create({
1517
1557
  justifyContent: "center",
1518
1558
  width: SWATCH_SIZE
1519
1559
  },
1560
+ // A drawn swatch (see SwatchDrawing) and its mark: the whole circle inside the selected one's ring.
1561
+ swatchFace: {
1562
+ alignItems: "center",
1563
+ bottom: 0,
1564
+ justifyContent: "center",
1565
+ left: 0,
1566
+ position: "absolute",
1567
+ right: 0,
1568
+ top: 0
1569
+ },
1520
1570
  swatchSelected: {
1521
1571
  borderColor: "#ffffff",
1522
- borderWidth: 2
1572
+ borderWidth: SWATCH_RING_WIDTH
1523
1573
  },
1524
1574
  swatchTaken: {
1525
1575
  opacity: 0.35
@@ -1573,10 +1623,10 @@ var styles18 = import_react_native23.StyleSheet.create({
1573
1623
 
1574
1624
  // src/LabeledDropdown.tsx
1575
1625
  var import_auto_paper11 = require("@rific/auto-paper");
1576
- var import_feedback_press7 = require("@rific/feedback-press");
1626
+ var import_feedback_press8 = require("@rific/feedback-press");
1577
1627
  var import_react_native24 = require("react-native");
1578
1628
  var import_react_native_paper14 = require("react-native-paper");
1579
- var import_jsx_runtime22 = require("react/jsx-runtime");
1629
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1580
1630
  var TRIGGER_HEIGHT = 28;
1581
1631
  var POPOVER_WIDTH = 180;
1582
1632
  var ROW_HEIGHT = 36;
@@ -1599,17 +1649,17 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
1599
1649
  onChange(option.value);
1600
1650
  host.close();
1601
1651
  };
1602
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native24.View, { style: [styles19.anchor, open && styles19.anchorOpen], children: [
1603
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), style: styles19.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native24.View, { ref: triggerRef, collapsable: false, style: styles19.triggerInner, children: [
1604
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper14.Text, { style: [styles19.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
1605
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper14.Icon, { source: "menu-down", size: 16, color })
1652
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native24.View, { style: [styles19.anchor, open && styles19.anchorOpen], children: [
1653
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_feedback_press8.TouchableRipple, { onPress: () => host.toggle(id), style: styles19.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native24.View, { ref: triggerRef, collapsable: false, style: styles19.triggerInner, children: [
1654
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper14.Text, { style: [styles19.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
1655
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper14.Icon, { source: "menu-down", size: 16, color })
1606
1656
  ] }) }),
1607
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native24.ScrollView, { style: [styles19.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles19.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
1657
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native24.ScrollView, { style: [styles19.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles19.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
1608
1658
  const isSelected = option.value === value;
1609
1659
  const onColor = (0, import_auto_paper11.getContrastColor)(color);
1610
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => handleSelect(option), style: [styles19.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native24.View, { style: styles19.rowInner, children: [
1611
- option.icon && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper14.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
1612
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native_paper14.Text, { style: [styles19.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
1660
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_feedback_press8.TouchableRipple, { onPress: () => handleSelect(option), style: [styles19.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native24.View, { style: styles19.rowInner, children: [
1661
+ option.icon && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper14.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
1662
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper14.Text, { style: [styles19.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
1613
1663
  ] }) }, option.value);
1614
1664
  }) }) })
1615
1665
  ] });
@@ -1677,15 +1727,15 @@ var import_react_native27 = require("react-native");
1677
1727
  var import_react_native_paper16 = require("react-native-paper");
1678
1728
 
1679
1729
  // src/ReadyButton.tsx
1680
- var import_feedback_press8 = require("@rific/feedback-press");
1730
+ var import_feedback_press9 = require("@rific/feedback-press");
1681
1731
  var import_react_native25 = require("react-native");
1682
1732
  var import_react_native_paper15 = require("react-native-paper");
1683
- var import_jsx_runtime23 = require("react/jsx-runtime");
1733
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1684
1734
  function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
1685
1735
  const readyButtonStyle = [styles20.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
1686
1736
  const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
1687
1737
  const labelColorStyle = { color: ready ? "#000000" : color };
1688
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_feedback_press8.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native_paper15.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
1738
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_feedback_press9.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_paper15.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
1689
1739
  }
1690
1740
  var styles20 = import_react_native25.StyleSheet.create({
1691
1741
  readyButton: {
@@ -1750,7 +1800,7 @@ function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
1750
1800
  }
1751
1801
 
1752
1802
  // src/PlayerSetupPanel.tsx
1753
- var import_jsx_runtime24 = require("react/jsx-runtime");
1803
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1754
1804
  function getColorPopoverId(idPrefix) {
1755
1805
  return `${idPrefix}-color`;
1756
1806
  }
@@ -1773,13 +1823,13 @@ function PlayerSetupPanel({ idPrefix, host, label, labelFontFamily, color, onCol
1773
1823
  const seatPickerId = showProfilePicker ? getProfilePopoverId(idPrefix) : getCpuDifficultyPopoverId(idPrefix);
1774
1824
  const seatPickerSize = showProfilePicker ? (0, import_profile2.getProfilePickerContentSize)(profiles.length, !!onManageProfiles, colorSection) : (0, import_profile2.getOptionPickerContentSize)(cpuDifficultyOptions?.length ?? 0, colorSection);
1775
1825
  const seatPickerAlign = useZoneClampedAlign(seatButton && popover.openId === seatPickerId, seatPickerSize.width, seatPickerSize.height);
1776
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native27.View, { style: [styles21.panel, ownPopoverOpen && styles21.panelOpen], children: [
1777
- showProfilePicker ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_profile2.ProfilePicker, { idPrefix, host: popover, profiles, selectedId: selectedProfileId ?? null, takenId: takenProfileId, color, dark, guestLabel: guestLabel ?? "GUEST", onSelect: (profile) => onProfileSelect?.(profile), onManage: onManageProfiles, colorSection, alignOverride: seatPickerAlign }) : showCpuDifficulty ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_profile2.OptionPicker, { id: getCpuDifficultyPopoverId(idPrefix), host: popover, options: cpuDifficultyOptions, value: cpuDifficulty, onChange: onCpuDifficultyChange, color, dark, icon: cpuIcon, colorSection, alignOverride: seatPickerAlign }) : label && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_native_paper16.Text, { variant: "labelSmall", style: { color, fontFamily: labelFontFamily }, children: label }),
1778
- (!seatButton || secondPicker) && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native27.View, { style: [styles21.pickerRow, pickerRowPopoverOpen && styles21.pickerRowOpen], children: [
1779
- !seatButton && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(InlineColorPicker, { id: getColorPopoverId(idPrefix), host: popover, value: color, onChange: onColorChange, swatches, takenValue: takenColor, allowSwapTaken, alignOverride: colorAlignOverride, rotation: colorRotation, dark, tag: isHuman ? selectedProfile?.tag : void 0, icon: isHuman ? humanIcon : cpuIcon }),
1826
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native27.View, { style: [styles21.panel, ownPopoverOpen && styles21.panelOpen], children: [
1827
+ showProfilePicker ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_profile2.ProfilePicker, { idPrefix, host: popover, profiles, selectedId: selectedProfileId ?? null, takenId: takenProfileId, color, dark, guestLabel: guestLabel ?? "GUEST", onSelect: (profile) => onProfileSelect?.(profile), onManage: onManageProfiles, colorSection, alignOverride: seatPickerAlign }) : showCpuDifficulty ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_profile2.OptionPicker, { id: getCpuDifficultyPopoverId(idPrefix), host: popover, options: cpuDifficultyOptions, value: cpuDifficulty, onChange: onCpuDifficultyChange, color, dark, icon: cpuIcon, colorSection, alignOverride: seatPickerAlign }) : label && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native_paper16.Text, { variant: "labelSmall", style: { color, fontFamily: labelFontFamily }, children: label }),
1828
+ (!seatButton || secondPicker) && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native27.View, { style: [styles21.pickerRow, pickerRowPopoverOpen && styles21.pickerRowOpen], children: [
1829
+ !seatButton && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(InlineColorPicker, { id: getColorPopoverId(idPrefix), host: popover, value: color, onChange: onColorChange, swatches, takenValue: takenColor, allowSwapTaken, alignOverride: colorAlignOverride, rotation: colorRotation, dark, tag: isHuman ? selectedProfile?.tag : void 0, icon: isHuman ? humanIcon : cpuIcon }),
1780
1830
  secondPicker
1781
1831
  ] }),
1782
- isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ReadyButton, { color, ready: ready ?? false, onToggleReady })
1832
+ isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ReadyButton, { color, ready: ready ?? false, onToggleReady })
1783
1833
  ] });
1784
1834
  }
1785
1835
  var styles21 = import_react_native27.StyleSheet.create({
@@ -1815,23 +1865,23 @@ var styles21 = import_react_native27.StyleSheet.create({
1815
1865
 
1816
1866
  // src/PressAwayOverlay.tsx
1817
1867
  var import_react_native28 = require("react-native");
1818
- var import_jsx_runtime25 = require("react/jsx-runtime");
1868
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1819
1869
  function PressAwayOverlay({ active, onPress, style }) {
1820
1870
  if (!active) return null;
1821
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native28.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native28.StyleSheet.absoluteFill, style] });
1871
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native28.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native28.StyleSheet.absoluteFill, style] });
1822
1872
  }
1823
1873
 
1824
1874
  // src/SharedActionBand.tsx
1825
- var import_feedback_press9 = require("@rific/feedback-press");
1875
+ var import_feedback_press10 = require("@rific/feedback-press");
1826
1876
  var import_react_native29 = require("react-native");
1827
- var import_jsx_runtime26 = require("react/jsx-runtime");
1877
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1828
1878
  function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
1829
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native29.View, { style: [styles22.column, popoverOpen && styles22.columnOpen], children: [
1830
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_native29.View, { style: styles22.actionsRow, children: [
1831
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_feedback_press9.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
1832
- onRandomize && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_feedback_press9.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
1833
- onReset && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_feedback_press9.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
1834
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_feedback_press9.IconButton, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
1879
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react_native29.View, { style: [styles22.column, popoverOpen && styles22.columnOpen], children: [
1880
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react_native29.View, { style: styles22.actionsRow, children: [
1881
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_feedback_press10.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
1882
+ onRandomize && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_feedback_press10.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
1883
+ onReset && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_feedback_press10.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
1884
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_feedback_press10.IconButton, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
1835
1885
  ] }),
1836
1886
  children
1837
1887
  ] });
@@ -1855,7 +1905,7 @@ var styles22 = import_react_native29.StyleSheet.create({
1855
1905
  var import_react13 = require("react");
1856
1906
  var import_react_native30 = require("react-native");
1857
1907
  var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
1858
- var import_jsx_runtime27 = require("react/jsx-runtime");
1908
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1859
1909
  var STAGGER_MS = 45;
1860
1910
  var LETTER_DURATION_MS = 320;
1861
1911
  function getStaggeredWordDuration(letterCount) {
@@ -1871,10 +1921,10 @@ function AnimatedLetter({ char, index, color, reducedMotion, fontFamily, fontSiz
1871
1921
  opacity: progress.value,
1872
1922
  transform: [{ translateY: (1 - progress.value) * 12 }, { scale: 0.85 + progress.value * 0.15 }]
1873
1923
  }));
1874
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native_reanimated2.default.Text, { allowFontScaling: false, style: [{ color, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, style], children: char });
1924
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native_reanimated2.default.Text, { allowFontScaling: false, style: [{ color, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, style], children: char });
1875
1925
  }
1876
1926
  function StaggeredWord({ word, color, fontFamily, fontSize, lineHeight, reducedMotion, startIndex = 0, fontWeight = "bold", letterSpacing, style, onLayout }) {
1877
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native30.View, { style: [styles23.row, style], onLayout, children: word.split("").map((char, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(AnimatedLetter, { char, index: startIndex + i, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, i)) });
1927
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native30.View, { style: [styles23.row, style], onLayout, children: word.split("").map((char, i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(AnimatedLetter, { char, index: startIndex + i, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, i)) });
1878
1928
  }
1879
1929
  var styles23 = import_react_native30.StyleSheet.create({
1880
1930
  row: {
@@ -1884,12 +1934,12 @@ var styles23 = import_react_native30.StyleSheet.create({
1884
1934
 
1885
1935
  // src/UpdateDialog.tsx
1886
1936
  var import_updater2 = require("@rific/updater");
1887
- var import_jsx_runtime28 = require("react/jsx-runtime");
1937
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1888
1938
  function UpdateDialog({ rotation = 0, autoCheck = true, autoPrompt = true, onError }) {
1889
1939
  const { manifest, onConfirm, respond } = useUpdateConfirmBridge();
1890
1940
  (0, import_updater2.useUpdater)({ autoCheck, autoPrompt, onConfirm, onError });
1891
1941
  const date = manifest ? new Date(manifest.createdAt) : null;
1892
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ConfirmDialog, { visible: !!manifest, title: "Update Available", message: date ? `Released ${date.toLocaleDateString()} at ${date.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation, onConfirm: () => respond(true), onCancel: () => respond(false) });
1942
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ConfirmDialog, { visible: !!manifest, title: "Update Available", message: date ? `Released ${date.toLocaleDateString()} at ${date.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation, onConfirm: () => respond(true), onCancel: () => respond(false) });
1893
1943
  }
1894
1944
 
1895
1945
  // src/useQuitConfirmation.ts
@@ -1938,6 +1988,7 @@ function useQuitConfirmation(hasProgress, onConfirmedBack) {
1938
1988
  PressAwayOverlay,
1939
1989
  ReadyButton,
1940
1990
  RotatedFrame,
1991
+ SecondaryButton,
1941
1992
  SectionedDropdown,
1942
1993
  SharedActionBand,
1943
1994
  StaggeredWord,