@buoy-gg/image-overlay 7.0.73 → 7.0.75

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.
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImageOverlayModal=ImageOverlayModal;exports.ImageOverlayToolView=ImageOverlayToolView;var _imageClipboard=require("../utils/imageClipboard");var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _ImageOverlayController=require("../utils/ImageOverlayController");var _fiberScanner=require("../utils/fiberScanner");var _TargetList=require("./TargetList");var _OverlayControls=require("./OverlayControls");var _jsxRuntime=require("react/jsx-runtime");let persistedImageUrl="";function ImageOverlayModal({visible:c,onClose:p,onBack:v,onMinimize:T,enableSharedModalDimensions:P=false,initialModalState:C,minimizeTargetPosition:j,inline:I=false,initialView:d}){const[o,l]=(0,_react.useState)(()=>{if(d)return d;const e=_ImageOverlayController.ImageOverlayController.getState();if(e.mode==="free")return"free";if(e.targetRect)return"controls";return"idle"});const[h,g]=(0,_react.useState)(()=>d==="targets"?(0,_fiberScanner.scanForImageTargets)():[]);const[t,O]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.getState());const[n,i]=(0,_react.useState)(persistedImageUrl);const[u,w]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.isAutoTracking());(0,_react.useEffect)(()=>{persistedImageUrl=n},[n]);(0,_react.useEffect)(()=>{return _ImageOverlayController.ImageOverlayController.subscribe(O)},[]);(0,_react.useEffect)(()=>{_ImageOverlayController.ImageOverlayController.setAutoTrack(u);return()=>{}},[u]);const b=(0,_react.useCallback)(()=>{const e=(0,_fiberScanner.scanForImageTargets)();g(e);l("targets")},[]);const S=(0,_react.useCallback)(async e=>{await _ImageOverlayController.ImageOverlayController.setTarget(e.instance,e.label,e.fiber);if(persistedImageUrl.trim()){await _ImageOverlayController.ImageOverlayController.setImageUri(persistedImageUrl.trim());_ImageOverlayController.ImageOverlayController.setEnabled(true)}l("controls")},[]);const s=(0,_react.useCallback)(async()=>{const e=persistedImageUrl.trim();if(!e)return;if(o==="free"){await _ImageOverlayController.ImageOverlayController.startFreeMode(e)}else{await _ImageOverlayController.ImageOverlayController.setImageUri(e);_ImageOverlayController.ImageOverlayController.setEnabled(true)}},[o]);const x=(0,_react.useCallback)(async()=>{let e=null;try{e=(0,_imageClipboard.loadImageClipboard)()}catch{}let a=null;if(!e){try{const r=(0,_imageClipboard.loadTextClipboard)();a=r.default||r}catch{}}if(!e&&!a){_reactNative.Alert.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(e&&typeof e.hasImageAsync==="function"){const R=await e.hasImageAsync();if(R){const y=await e.getImageAsync({format:"png"});if(y?.data){if(o==="free"){await _ImageOverlayController.ImageOverlayController.startFreeMode(y.data)}else{await _ImageOverlayController.ImageOverlayController.setImageUri(y.data);_ImageOverlayController.ImageOverlayController.setEnabled(true)}return}}}let r=null;if(e&&typeof e.getStringAsync==="function"){r=await e.getStringAsync()}else if(a&&typeof a.getString==="function"){r=await a.getString()}if(r&&(r.startsWith("http")||r.startsWith("data:"))){i(r);persistedImageUrl=r;return}if(!e){_reactNative.Alert.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}else{_reactNative.Alert.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there.")}}catch{_reactNative.Alert.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[o]);const B=(0,_react.useCallback)(()=>{_ImageOverlayController.ImageOverlayController.reset();persistedImageUrl="";l("idle");i("");g([])},[]);const V=(0,_react.useCallback)(()=>{if(o==="controls"){const e=(0,_fiberScanner.scanForImageTargets)();g(e);l("targets")}else if(o==="targets"||o==="free"){_ImageOverlayController.ImageOverlayController.reset();l("idle")}else{l("idle")}},[o]);const D=(()=>{switch(o){case"targets":return`Targets (${h.length})`;case"controls":return t.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})();const m={showToggleButton:false,customContent:(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:o!=="idle"?V:v}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:D,testID:"buoy-image-overlay-title"}),(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader.Actions,{children:[o==="targets"&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerTextButton,onPress:b,testID:"buoy-image-overlay-scan",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.headerTextButtonLabel,children:"Scan"})}),(o==="controls"||o==="free")&&t.imageUri&&(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:t.enabled,onToggle:()=>_ImageOverlayController.ImageOverlayController.toggle(),accessibilityLabel:"Toggle image overlay",testID:"buoy-image-overlay-power"}),o!=="idle"&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerActionButton,onPress:B,testID:"buoy-image-overlay-clear",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_sharedUi.Trash2,{size:14,color:_sharedUi.night.color.textSecondary})})]})]})};const f=(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[o==="idle"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.homeContainer,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.homeSubtitle,testID:"buoy-image-overlay-home",children:"Choose a mode"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.modeGrid,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.modePanel,onPress:b,testID:"buoy-image-overlay-mode-component",activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.modeIconCircle,{backgroundColor:_sharedUi.night.color.accentSoft}],children:(0,_jsxRuntime.jsx)(_sharedUi.SquareDashed,{size:24,color:_sharedUi.night.color.accent})}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.modePanelTitle,children:["Component","\n","Match"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.modePanelDesc,children:"Overlay on a tagged component"})]}),(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.modePanel,onPress:()=>l("free"),testID:"buoy-image-overlay-mode-free",activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.modeIconCircle,{backgroundColor:_sharedUi.night.color.accentSoft}],children:(0,_jsxRuntime.jsx)(_sharedUi.Image,{size:24,color:_sharedUi.night.color.accent})}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.modePanelTitle,children:["Free","\n","Placement"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),o==="targets"&&(0,_jsxRuntime.jsx)(_TargetList.TargetList,{targets:h,onSelect:S}),o==="controls"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlsContainer,children:[t.targetRect&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Component"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoValue,testID:"buoy-image-overlay-info-component",children:t.targetLabel})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Size"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(t.targetRect.width)," x ",Math.round(t.targetRect.height)]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Position"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(t.targetRect.x),", ",Math.round(t.targetRect.y)]})]}),t.imageWidth!=null&&t.imageHeight!=null&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Image"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-image",children:[t.imageWidth," x ",t.imageHeight]})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inputSection,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionLabel,children:"Image"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.pasteButton,onPress:x,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.pasteButtonText,children:"Paste from Clipboard"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.urlRow,children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.urlInput,testID:"buoy-image-overlay-url",value:n,onChangeText:i,placeholder:"or enter URL...",placeholderTextColor:_sharedUi.night.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:s}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.loadButton,!n.trim()&&styles.loadButtonDisabled],onPress:s,disabled:!n.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadButtonText,children:"Load"})})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.toggleSection,children:[(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Show Outline",testID:"buoy-image-overlay-outline-toggle",value:t.showOutline,onValueChange:e=>_ImageOverlayController.ImageOverlayController.setShowOutline(e)}),(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Auto Track",value:u,onValueChange:w,testID:"buoy-image-overlay-autotrack"}),t.imageUri&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Opacity"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.blendButtons,children:[0,25,50,75,100].map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-image-overlay-opacity-${e}`,style:[styles.blendButton,Math.round(t.opacity*100)===e&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.setOpacity(e/100),activeOpacity:.7,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.blendButtonText,Math.round(t.opacity*100)===e&&styles.blendButtonTextActive],children:[e,"%"]})},e))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Flip"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendButtons,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertX&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertX&&styles.blendButtonTextActive],testID:t.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertY&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertY&&styles.blendButtonTextActive],testID:t.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]})]}),t.imageUri&&(0,_jsxRuntime.jsx)(_OverlayControls.OverlayControls,{opacity:t.opacity,scale:t.scale,offsetX:t.offsetX,offsetY:t.offsetY,onOpacityChange:e=>_ImageOverlayController.ImageOverlayController.setOpacity(e),onScaleChange:e=>_ImageOverlayController.ImageOverlayController.setScale(e),onOffsetChange:(e,a)=>_ImageOverlayController.ImageOverlayController.setOffset(e,a)}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actions,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-settings",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Reset Settings"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.remeasure(),activeOpacity:.7,testID:"buoy-image-overlay-remeasure",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Remeasure"})})]})]}),o==="free"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlsContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inputSection,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionLabel,children:"Image"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.pasteButton,onPress:x,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.pasteButtonText,children:"Paste from Clipboard"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.urlRow,children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.urlInput,testID:"buoy-image-overlay-url",value:n,onChangeText:i,placeholder:"or enter URL...",placeholderTextColor:_sharedUi.night.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:s}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.loadButton,!n.trim()&&styles.loadButtonDisabled],onPress:s,disabled:!n.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadButtonText,children:"Load"})})]})]}),t.imageUri&&t.mode==="free"&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Position"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(t.freeX),", ",Math.round(t.freeY)]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Size"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(t.freeWidth)," x ",Math.round(t.freeHeight)]})]}),t.imageWidth!=null&&t.imageHeight!=null&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Original"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-original",children:[t.imageWidth," x ",t.imageHeight]})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inputSection,children:(0,_jsxRuntime.jsx)(_OverlayControls.OverlayControls,{opacity:t.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:e=>_ImageOverlayController.ImageOverlayController.setOpacity(e),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.toggleSection,children:[(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Lock Position",testID:"buoy-image-overlay-lock",tone:"warning",value:t.locked,onValueChange:e=>_ImageOverlayController.ImageOverlayController.setLocked(e)}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Opacity"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.blendButtons,children:[0,25,50,75,100].map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-image-overlay-opacity-${e}`,style:[styles.blendButton,Math.round(t.opacity*100)===e&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.setOpacity(e/100),activeOpacity:.7,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.blendButtonText,Math.round(t.opacity*100)===e&&styles.blendButtonTextActive],children:[e,"%"]})},e))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Flip"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendButtons,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertX&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertX&&styles.blendButtonTextActive],testID:t.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertY&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertY&&styles.blendButtonTextActive],testID:t.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.actions,children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-position",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Reset Position"})})})]})]})]});if(I){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inlineRoot,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inlineHeader,..._sharedUi.windowDragProps,children:m.customContent}),f]})}return(0,_jsxRuntime.jsx)(_sharedUi.JsModal,{visible:c,onClose:p,onMinimize:T,minimizeTargetPosition:j,initialModalState:C,header:m,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:f})}function ImageOverlayToolView(c={}){return(0,_jsxRuntime.jsx)(ImageOverlayModal,{...c,inline:true,visible:true,onClose:()=>{}})}const styles=_reactNative.StyleSheet.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:_sharedUi.macOSColors.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:_sharedUi.macOSColors.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:_sharedUi.night.color.surface,borderRadius:12,borderWidth:1,borderColor:_sharedUi.night.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:_sharedUi.night.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:_sharedUi.night.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:_sharedUi.night.color.accentSoft,borderWidth:1,borderColor:_sharedUi.night.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,fontSize:13,color:_sharedUi.night.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:_sharedUi.night.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:_sharedUi.night.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:_sharedUi.night.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textTertiary},blendButtonTextActive:{color:_sharedUi.night.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:_sharedUi.night.color.textSecondary}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImageOverlayModal=ImageOverlayModal;exports.ImageOverlayToolView=ImageOverlayToolView;var _imageClipboard=require("../utils/imageClipboard");var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _ImageOverlayController=require("../utils/ImageOverlayController");var _fiberScanner=require("../utils/fiberScanner");var _TargetList=require("./TargetList");var _OverlayControls=require("./OverlayControls");var _jsxRuntime=require("react/jsx-runtime");let persistedImageUrl="";function ImageOverlayModal({visible:c,onClose:p,onBack:v,onMinimize:T,enableSharedModalDimensions:P=false,initialModalState:C,minimizeTargetPosition:j,inline:I=false,initialView:d}){const[o,l]=(0,_react.useState)(()=>{if(d)return d;const e=_ImageOverlayController.ImageOverlayController.getState();if(e.mode==="free")return"free";if(e.targetRect)return"controls";return"idle"});const[h,g]=(0,_react.useState)(()=>d==="targets"?(0,_fiberScanner.scanForImageTargets)():[]);const[t,O]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.getState());const[n,i]=(0,_react.useState)(persistedImageUrl);const[u,w]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.isAutoTracking());(0,_react.useEffect)(()=>{persistedImageUrl=n},[n]);(0,_react.useEffect)(()=>{return _ImageOverlayController.ImageOverlayController.subscribe(O)},[]);(0,_react.useEffect)(()=>{_ImageOverlayController.ImageOverlayController.setAutoTrack(u);return()=>{}},[u]);const b=(0,_react.useCallback)(()=>{const e=(0,_fiberScanner.scanForImageTargets)();g(e);l("targets")},[]);const S=(0,_react.useCallback)(async e=>{await _ImageOverlayController.ImageOverlayController.setTarget(e.instance,e.label,e.fiber);if(persistedImageUrl.trim()){await _ImageOverlayController.ImageOverlayController.setImageUri(persistedImageUrl.trim());_ImageOverlayController.ImageOverlayController.setEnabled(true)}l("controls")},[]);const s=(0,_react.useCallback)(async()=>{const e=persistedImageUrl.trim();if(!e)return;if(o==="free"){await _ImageOverlayController.ImageOverlayController.startFreeMode(e)}else{await _ImageOverlayController.ImageOverlayController.setImageUri(e);_ImageOverlayController.ImageOverlayController.setEnabled(true)}},[o]);const x=(0,_react.useCallback)(async()=>{let e=null;try{e=(0,_imageClipboard.loadImageClipboard)()}catch{}let a=null;if(!e){try{const r=(0,_imageClipboard.loadTextClipboard)();a=r.default||r}catch{}}if(!e&&!a){_reactNative.Alert.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(e&&typeof e.hasImageAsync==="function"){const R=await e.hasImageAsync();if(R){const y=await e.getImageAsync({format:"png"});if(y?.data){if(o==="free"){await _ImageOverlayController.ImageOverlayController.startFreeMode(y.data)}else{await _ImageOverlayController.ImageOverlayController.setImageUri(y.data);_ImageOverlayController.ImageOverlayController.setEnabled(true)}return}}}let r=null;if(e&&typeof e.getStringAsync==="function"){r=await e.getStringAsync()}else if(a&&typeof a.getString==="function"){r=await a.getString()}if(r&&(r.startsWith("http")||r.startsWith("data:"))){i(r);persistedImageUrl=r;return}if(!e){_reactNative.Alert.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}else{_reactNative.Alert.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there.")}}catch{_reactNative.Alert.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[o]);const B=(0,_react.useCallback)(()=>{_ImageOverlayController.ImageOverlayController.reset();persistedImageUrl="";l("idle");i("");g([])},[]);const V=(0,_react.useCallback)(()=>{if(o==="controls"){const e=(0,_fiberScanner.scanForImageTargets)();g(e);l("targets")}else if(o==="targets"||o==="free"){_ImageOverlayController.ImageOverlayController.reset();l("idle")}else{l("idle")}},[o]);const D=(()=>{switch(o){case"targets":return`Targets (${h.length})`;case"controls":return t.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})();const m={showToggleButton:false,customContent:(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:o!=="idle"?V:v}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:D,testID:"buoy-image-overlay-title"}),(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader.Actions,{children:[o==="targets"&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerTextButton,onPress:b,testID:"buoy-image-overlay-scan",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.headerTextButtonLabel,children:"Scan"})}),(o==="controls"||o==="free")&&t.imageUri&&(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:t.enabled,onToggle:()=>_ImageOverlayController.ImageOverlayController.toggle(),accessibilityLabel:"Toggle image overlay",testID:"buoy-image-overlay-power"}),o!=="idle"&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerActionButton,onPress:B,testID:"buoy-image-overlay-clear",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_sharedUi.Trash2,{size:14,color:_sharedUi.night.color.textSecondary})})]})]})};const f=(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[o==="idle"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.homeContainer,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.homeSubtitle,testID:"buoy-image-overlay-home",children:"Choose a mode"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.modeGrid,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.modePanel,onPress:b,testID:"buoy-image-overlay-mode-component",activeOpacity:.7,accessibilityRole:"button",accessibilityLabel:"Component Match. Overlay on a tagged component",children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.modeIconCircle,{backgroundColor:_sharedUi.night.color.accentSoft}],children:(0,_jsxRuntime.jsx)(_sharedUi.SquareDashed,{size:24,color:_sharedUi.night.color.accent})}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.modePanelTitle,children:["Component","\n","Match"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.modePanelDesc,children:"Overlay on a tagged component"})]}),(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.modePanel,onPress:()=>l("free"),testID:"buoy-image-overlay-mode-free",activeOpacity:.7,accessibilityRole:"button",accessibilityLabel:"Free Placement. Drag and resize anywhere",children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.modeIconCircle,{backgroundColor:_sharedUi.night.color.accentSoft}],children:(0,_jsxRuntime.jsx)(_sharedUi.Image,{size:24,color:_sharedUi.night.color.accent})}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.modePanelTitle,children:["Free","\n","Placement"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),o==="targets"&&(0,_jsxRuntime.jsx)(_TargetList.TargetList,{targets:h,onSelect:S}),o==="controls"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlsContainer,children:[t.targetRect&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Component"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoValue,testID:"buoy-image-overlay-info-component",children:t.targetLabel})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Size"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(t.targetRect.width)," x ",Math.round(t.targetRect.height)]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Position"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(t.targetRect.x),", ",Math.round(t.targetRect.y)]})]}),t.imageWidth!=null&&t.imageHeight!=null&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Image"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-image",children:[t.imageWidth," x ",t.imageHeight]})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inputSection,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionLabel,children:"Image"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.pasteButton,onPress:x,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.pasteButtonText,children:"Paste from Clipboard"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.urlRow,children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.urlInput,testID:"buoy-image-overlay-url",value:n,onChangeText:i,placeholder:"or enter URL...",placeholderTextColor:_sharedUi.night.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:s}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.loadButton,!n.trim()&&styles.loadButtonDisabled],onPress:s,disabled:!n.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadButtonText,children:"Load"})})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.toggleSection,children:[(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Show Outline",testID:"buoy-image-overlay-outline-toggle",value:t.showOutline,onValueChange:e=>_ImageOverlayController.ImageOverlayController.setShowOutline(e)}),(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Auto Track",value:u,onValueChange:w,testID:"buoy-image-overlay-autotrack"}),t.imageUri&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Opacity"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.blendButtons,children:[0,25,50,75,100].map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-image-overlay-opacity-${e}`,style:[styles.blendButton,Math.round(t.opacity*100)===e&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.setOpacity(e/100),activeOpacity:.7,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.blendButtonText,Math.round(t.opacity*100)===e&&styles.blendButtonTextActive],children:[e,"%"]})},e))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Flip"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendButtons,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertX&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertX&&styles.blendButtonTextActive],testID:t.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertY&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertY&&styles.blendButtonTextActive],testID:t.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]})]}),t.imageUri&&(0,_jsxRuntime.jsx)(_OverlayControls.OverlayControls,{opacity:t.opacity,scale:t.scale,offsetX:t.offsetX,offsetY:t.offsetY,onOpacityChange:e=>_ImageOverlayController.ImageOverlayController.setOpacity(e),onScaleChange:e=>_ImageOverlayController.ImageOverlayController.setScale(e),onOffsetChange:(e,a)=>_ImageOverlayController.ImageOverlayController.setOffset(e,a)}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actions,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-settings",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Reset Settings"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.remeasure(),activeOpacity:.7,testID:"buoy-image-overlay-remeasure",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Remeasure"})})]})]}),o==="free"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlsContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inputSection,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionLabel,children:"Image"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.pasteButton,onPress:x,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.pasteButtonText,children:"Paste from Clipboard"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.urlRow,children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.urlInput,testID:"buoy-image-overlay-url",value:n,onChangeText:i,placeholder:"or enter URL...",placeholderTextColor:_sharedUi.night.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:s}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.loadButton,!n.trim()&&styles.loadButtonDisabled],onPress:s,disabled:!n.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadButtonText,children:"Load"})})]})]}),t.imageUri&&t.mode==="free"&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Position"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(t.freeX),", ",Math.round(t.freeY)]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Size"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(t.freeWidth)," x ",Math.round(t.freeHeight)]})]}),t.imageWidth!=null&&t.imageHeight!=null&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Original"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-original",children:[t.imageWidth," x ",t.imageHeight]})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inputSection,children:(0,_jsxRuntime.jsx)(_OverlayControls.OverlayControls,{opacity:t.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:e=>_ImageOverlayController.ImageOverlayController.setOpacity(e),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.toggleSection,children:[(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Lock Position",testID:"buoy-image-overlay-lock",tone:"warning",value:t.locked,onValueChange:e=>_ImageOverlayController.ImageOverlayController.setLocked(e)}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Opacity"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.blendButtons,children:[0,25,50,75,100].map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-image-overlay-opacity-${e}`,style:[styles.blendButton,Math.round(t.opacity*100)===e&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.setOpacity(e/100),activeOpacity:.7,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.blendButtonText,Math.round(t.opacity*100)===e&&styles.blendButtonTextActive],children:[e,"%"]})},e))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Flip"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendButtons,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertX&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertX&&styles.blendButtonTextActive],testID:t.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertY&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertY&&styles.blendButtonTextActive],testID:t.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.actions,children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-position",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Reset Position"})})})]})]})]});if(I){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inlineRoot,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inlineHeader,..._sharedUi.windowDragProps,children:m.customContent}),f]})}return(0,_jsxRuntime.jsx)(_sharedUi.JsModal,{visible:c,onClose:p,onMinimize:T,minimizeTargetPosition:j,initialModalState:C,header:m,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:f})}function ImageOverlayToolView(c={}){return(0,_jsxRuntime.jsx)(ImageOverlayModal,{...c,inline:true,visible:true,onClose:()=>{}})}const styles=_reactNative.StyleSheet.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:_sharedUi.macOSColors.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:_sharedUi.macOSColors.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:_sharedUi.night.color.surface,borderRadius:12,borderWidth:1,borderColor:_sharedUi.night.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:_sharedUi.night.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:_sharedUi.night.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:_sharedUi.night.color.accentSoft,borderWidth:1,borderColor:_sharedUi.night.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,fontSize:13,color:_sharedUi.night.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:_sharedUi.night.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:_sharedUi.night.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:_sharedUi.night.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textTertiary},blendButtonTextActive:{color:_sharedUi.night.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:_sharedUi.night.color.textSecondary}});
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImageOverlayStandalone=ImageOverlayStandalone;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _ImageOverlayController=require("../utils/ImageOverlayController");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(x,v){if("function"==typeof WeakMap)var w=new WeakMap,p=new WeakMap;return(_interopRequireWildcard=function(r,c){if(!c&&r&&r.__esModule)return r;var a,o,g={__proto__:null,default:r};if(null===r||"object"!=typeof r&&"function"!=typeof r)return g;if(a=c?p:w){if(a.has(r))return a.get(r);a.set(r,g)}for(const n in r)"default"!==n&&{}.hasOwnProperty.call(r,n)&&((o=(a=Object.defineProperty)&&Object.getOwnPropertyDescriptor(r,n))&&(o.get||o.set)?a(g,n,o):g[n]=r[n]);return g})(x,v)}function OverlayImage({uri:x,style:v,invertX:w,invertY:p}){const r=[];if(w)r.push({scaleX:-1});if(p)r.push({scaleY:-1});const c=r.length>0?{transform:r}:{};return(0,_jsxRuntime.jsx)(_reactNative.Image,{testID:"buoy-internal-image-overlay",source:{uri:x},style:[v,c],pointerEvents:"none"})}const FREE_MIN_SIZE=30;function FreePlacement({imageUri:x,x:v,y:w,width:p,height:r,opacity:c,aspectRatio:a,invertX:o,invertY:g,locked:n}){const[y,u]=(0,_react.useState)(false);const I=(0,_react.useRef)({x:0,y:0});const C=(0,_react.useRef)({x:0,y:0,width:0,height:0});const h=_reactNative.Dimensions.get("window");const _=(0,_react.useMemo)(()=>_reactNative.PanResponder.create({onStartShouldSetPanResponder:()=>!n,onMoveShouldSetPanResponder:(b,s)=>!n&&(Math.abs(s.dx)>2||Math.abs(s.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const b=_ImageOverlayController.ImageOverlayController.getState();I.current={x:b.freeX,y:b.freeY};u(true)},onPanResponderMove:(b,s)=>{const j=_ImageOverlayController.ImageOverlayController.getState();const f=Math.max(0,Math.min(I.current.x+s.dx,h.width-j.freeWidth));const d=Math.max(0,Math.min(I.current.y+s.dy,h.height-j.freeHeight));_ImageOverlayController.ImageOverlayController.setFreePosition(f,d)},onPanResponderRelease:()=>u(false),onPanResponderTerminate:()=>u(false)}),[h.width,h.height,n]);const R=(0,_react.useCallback)(b=>_reactNative.PanResponder.create({onStartShouldSetPanResponder:()=>!n,onMoveShouldSetPanResponder:()=>!n,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const s=_ImageOverlayController.ImageOverlayController.getState();C.current={x:s.freeX,y:s.freeY,width:s.freeWidth,height:s.freeHeight};u(true)},onPanResponderMove:(s,j)=>{const{dx:f,dy:d}=j;if(Math.abs(f)<.5&&Math.abs(d)<.5)return;const e=C.current;const l=a>0?a:e.width/e.height;const O=Math.abs(f);const W=Math.abs(d);const P=O>=W;let t;let i;let M=e.x;let m=e.y;switch(b){case"bottomRight":{t=P?e.width+f:(e.height+d)*l;t=Math.max(FREE_MIN_SIZE,Math.min(t,h.width-e.x));i=t/l;break}case"bottomLeft":{t=P?e.width-f:(e.height+d)*l;t=Math.max(FREE_MIN_SIZE,t);i=t/l;M=e.x+e.width-t;M=Math.max(0,M);t=Math.min(t,e.x+e.width);i=t/l;break}case"topRight":{t=P?e.width+f:(e.height-d)*l;t=Math.max(FREE_MIN_SIZE,Math.min(t,h.width-e.x));i=t/l;m=e.y+e.height-i;m=Math.max(0,m);i=Math.min(i,e.y+e.height);t=i*l;break}case"topLeft":{t=P?e.width-f:(e.height-d)*l;t=Math.max(FREE_MIN_SIZE,t);i=t/l;M=e.x+e.width-t;m=e.y+e.height-i;M=Math.max(0,M);m=Math.max(0,m);t=Math.min(t,e.x+e.width);i=t/l;m=e.y+e.height-i;break}}t=Math.max(FREE_MIN_SIZE,Math.round(t));i=Math.max(FREE_MIN_SIZE,Math.round(i));_ImageOverlayController.ImageOverlayController.setFreeDimensions(t,i,Math.round(M),Math.round(m))},onPanResponderRelease:()=>u(false),onPanResponderTerminate:()=>u(false)}),[h.width,h.height,a,n]);const S=(0,_react.useMemo)(()=>({topLeft:R("topLeft"),topRight:R("topRight"),bottomLeft:R("bottomLeft"),bottomRight:R("bottomRight")}),[R]);const H={..._sharedUi.absoluteFill,opacity:c};return(0,_jsxRuntime.jsxs)(_reactNative.View,{testID:"buoy-image-overlay-free-box",style:{position:"absolute",left:v,top:w,width:p,height:r},pointerEvents:n?"none":"auto",children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:_reactNative.StyleSheet.absoluteFill,...n?{}:_.panHandlers,children:(0,_jsxRuntime.jsx)(OverlayImage,{uri:x,style:H,invertX:o,invertY:g})}),(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",style:[styles.freeBorder,y&&styles.freeBorderActive,n&&styles.freeBorderLocked]}),!n&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{...S.topLeft.panHandlers,style:[styles.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.topRight.panHandlers,style:[styles.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.bottomLeft.panHandlers,style:[styles.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.bottomRight.panHandlers,style:[styles.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})})]})]})}function ImageOverlayStandalone(){const[x,v]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.getState());(0,_react.useEffect)(()=>{return _ImageOverlayController.ImageOverlayController.subscribe(v)},[]);const{mode:w,enabled:p,imageUri:r,imageWidth:c,imageHeight:a,targetRect:o,targetLabel:g,showOutline:n,opacity:y,scale:u,offsetX:I,offsetY:C,invertX:h,invertY:_,locked:R,freeX:S,freeY:H,freeWidth:b,freeHeight:s}=x;const j=c&&a&&a>0?c/a:0;if(w==="free"&&p&&r){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:(0,_jsxRuntime.jsx)(FreePlacement,{imageUri:r,x:S,y:H,width:b,height:s,opacity:y,aspectRatio:j,invertX:h,invertY:_,locked:R})})}if(!o)return null;const f=p&&r;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[n&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",testID:"buoy-image-overlay-outline",style:[styles.highlight,{left:o.x-3,top:o.y-3,width:o.width+6,height:o.height+6}]}),g&&(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",style:[styles.label,{left:o.x,top:o.y-20}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.labelText,testID:"buoy-image-overlay-outline-label",children:g})})]}),f&&(()=>{const d=(c??o.width)*u;const e=(a??o.height)*u;const l=o.x+o.width/2;const O=o.y+o.height/2;const W={position:"absolute",left:l-d/2+I,top:O-e/2+C,width:d,height:e,opacity:y};return(0,_jsxRuntime.jsx)(OverlayImage,{uri:r,style:W,invertX:h,invertY:_})})()]})}const styles=_reactNative.StyleSheet.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:_reactNative.Platform.OS==="web"?999:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:_sharedUi.monoFont},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImageOverlayStandalone=ImageOverlayStandalone;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _ImageOverlayController=require("../utils/ImageOverlayController");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(x,v){if("function"==typeof WeakMap)var w=new WeakMap,p=new WeakMap;return(_interopRequireWildcard=function(r,c){if(!c&&r&&r.__esModule)return r;var a,o,g={__proto__:null,default:r};if(null===r||"object"!=typeof r&&"function"!=typeof r)return g;if(a=c?p:w){if(a.has(r))return a.get(r);a.set(r,g)}for(const n in r)"default"!==n&&{}.hasOwnProperty.call(r,n)&&((o=(a=Object.defineProperty)&&Object.getOwnPropertyDescriptor(r,n))&&(o.get||o.set)?a(g,n,o):g[n]=r[n]);return g})(x,v)}function OverlayImage({uri:x,style:v,invertX:w,invertY:p}){const r=[];if(w)r.push({scaleX:-1});if(p)r.push({scaleY:-1});const c=r.length>0?{transform:r}:{};return(0,_jsxRuntime.jsx)(_reactNative.Image,{testID:"buoy-internal-image-overlay",source:{uri:x},style:[v,c,{pointerEvents:"none"}]})}const FREE_MIN_SIZE=30;function FreePlacement({imageUri:x,x:v,y:w,width:p,height:r,opacity:c,aspectRatio:a,invertX:o,invertY:g,locked:n}){const[y,u]=(0,_react.useState)(false);const I=(0,_react.useRef)({x:0,y:0});const C=(0,_react.useRef)({x:0,y:0,width:0,height:0});const h=_reactNative.Dimensions.get("window");const _=(0,_react.useMemo)(()=>_reactNative.PanResponder.create({onStartShouldSetPanResponder:()=>!n,onMoveShouldSetPanResponder:(b,s)=>!n&&(Math.abs(s.dx)>2||Math.abs(s.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const b=_ImageOverlayController.ImageOverlayController.getState();I.current={x:b.freeX,y:b.freeY};u(true)},onPanResponderMove:(b,s)=>{const j=_ImageOverlayController.ImageOverlayController.getState();const f=Math.max(0,Math.min(I.current.x+s.dx,h.width-j.freeWidth));const d=Math.max(0,Math.min(I.current.y+s.dy,h.height-j.freeHeight));_ImageOverlayController.ImageOverlayController.setFreePosition(f,d)},onPanResponderRelease:()=>u(false),onPanResponderTerminate:()=>u(false)}),[h.width,h.height,n]);const R=(0,_react.useCallback)(b=>_reactNative.PanResponder.create({onStartShouldSetPanResponder:()=>!n,onMoveShouldSetPanResponder:()=>!n,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const s=_ImageOverlayController.ImageOverlayController.getState();C.current={x:s.freeX,y:s.freeY,width:s.freeWidth,height:s.freeHeight};u(true)},onPanResponderMove:(s,j)=>{const{dx:f,dy:d}=j;if(Math.abs(f)<.5&&Math.abs(d)<.5)return;const e=C.current;const l=a>0?a:e.width/e.height;const O=Math.abs(f);const W=Math.abs(d);const P=O>=W;let t;let i;let M=e.x;let m=e.y;switch(b){case"bottomRight":{t=P?e.width+f:(e.height+d)*l;t=Math.max(FREE_MIN_SIZE,Math.min(t,h.width-e.x));i=t/l;break}case"bottomLeft":{t=P?e.width-f:(e.height+d)*l;t=Math.max(FREE_MIN_SIZE,t);i=t/l;M=e.x+e.width-t;M=Math.max(0,M);t=Math.min(t,e.x+e.width);i=t/l;break}case"topRight":{t=P?e.width+f:(e.height-d)*l;t=Math.max(FREE_MIN_SIZE,Math.min(t,h.width-e.x));i=t/l;m=e.y+e.height-i;m=Math.max(0,m);i=Math.min(i,e.y+e.height);t=i*l;break}case"topLeft":{t=P?e.width-f:(e.height-d)*l;t=Math.max(FREE_MIN_SIZE,t);i=t/l;M=e.x+e.width-t;m=e.y+e.height-i;M=Math.max(0,M);m=Math.max(0,m);t=Math.min(t,e.x+e.width);i=t/l;m=e.y+e.height-i;break}}t=Math.max(FREE_MIN_SIZE,Math.round(t));i=Math.max(FREE_MIN_SIZE,Math.round(i));_ImageOverlayController.ImageOverlayController.setFreeDimensions(t,i,Math.round(M),Math.round(m))},onPanResponderRelease:()=>u(false),onPanResponderTerminate:()=>u(false)}),[h.width,h.height,a,n]);const S=(0,_react.useMemo)(()=>({topLeft:R("topLeft"),topRight:R("topRight"),bottomLeft:R("bottomLeft"),bottomRight:R("bottomRight")}),[R]);const H={..._sharedUi.absoluteFill,opacity:c};return(0,_jsxRuntime.jsxs)(_reactNative.View,{testID:"buoy-image-overlay-free-box",style:{position:"absolute",left:v,top:w,width:p,height:r},pointerEvents:n?"none":"auto",children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:_reactNative.StyleSheet.absoluteFill,...n?{}:_.panHandlers,children:(0,_jsxRuntime.jsx)(OverlayImage,{uri:x,style:H,invertX:o,invertY:g})}),(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",style:[styles.freeBorder,y&&styles.freeBorderActive,n&&styles.freeBorderLocked]}),!n&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{...S.topLeft.panHandlers,style:[styles.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.topRight.panHandlers,style:[styles.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.bottomLeft.panHandlers,style:[styles.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.bottomRight.panHandlers,style:[styles.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})})]})]})}function ImageOverlayStandalone(){const[x,v]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.getState());(0,_react.useEffect)(()=>{return _ImageOverlayController.ImageOverlayController.subscribe(v)},[]);const{mode:w,enabled:p,imageUri:r,imageWidth:c,imageHeight:a,targetRect:o,targetLabel:g,showOutline:n,opacity:y,scale:u,offsetX:I,offsetY:C,invertX:h,invertY:_,locked:R,freeX:S,freeY:H,freeWidth:b,freeHeight:s}=x;const j=c&&a&&a>0?c/a:0;if(w==="free"&&p&&r){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:(0,_jsxRuntime.jsx)(FreePlacement,{imageUri:r,x:S,y:H,width:b,height:s,opacity:y,aspectRatio:j,invertX:h,invertY:_,locked:R})})}if(!o)return null;const f=p&&r;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[n&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",testID:"buoy-image-overlay-outline",style:[styles.highlight,{left:o.x-3,top:o.y-3,width:o.width+6,height:o.height+6}]}),g&&(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",style:[styles.label,{left:o.x,top:o.y-20}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.labelText,testID:"buoy-image-overlay-outline-label",children:g})})]}),f&&(()=>{const d=(c??o.width)*u;const e=(a??o.height)*u;const l=o.x+o.width/2;const O=o.y+o.height/2;const W={position:"absolute",left:l-d/2+I,top:O-e/2+C,width:d,height:e,opacity:y};return(0,_jsxRuntime.jsx)(OverlayImage,{uri:r,style:W,invertX:h,invertY:_})})()]})}const styles=_reactNative.StyleSheet.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:_reactNative.Platform.OS==="web"?999:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:_sharedUi.monoFont},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});
@@ -1 +1 @@
1
- "use strict";import{loadImageClipboard as Q,loadTextClipboard as Z}from"../utils/imageClipboard";import{useState as m,useEffect as D,useCallback as f}from"react";import{View as a,Text as l,TextInput as M,TouchableOpacity as d,StyleSheet as ee,Alert as x}from"react-native";import{JsModal as te,ModalHeader as C,macOSColors as W,night as i,Trash2 as oe,SquareDashed as ne,Image as re,PowerToggleButton as ie,windowDragProps as le,ToggleRow as R,monoFont as ae}from"@buoy-gg/shared-ui";import{ImageOverlayController as c}from"../utils/ImageOverlayController";import{scanForImageTargets as P}from"../utils/fiberScanner";import{TargetList as ce}from"./TargetList";import{OverlayControls as H}from"./OverlayControls";import{jsx as t,jsxs as r,Fragment as V}from"react/jsx-runtime";let b="";export function ImageOverlayModal({visible:I,onClose:j,onBack:U,onMinimize:Y,enableSharedModalDimensions:se=false,initialModalState:X,minimizeTargetPosition:E,inline:F=false,initialView:T}){const[s,y]=m(()=>{if(T)return T;const o=c.getState();if(o.mode==="free")return"free";if(o.targetRect)return"controls";return"idle"});const[z,B]=m(()=>T==="targets"?P():[]);const[n,K]=m(()=>c.getState());const[u,p]=m(b);const[S,_]=m(()=>c.isAutoTracking());D(()=>{b=u},[u]);D(()=>{return c.subscribe(K)},[]);D(()=>{c.setAutoTrack(S);return()=>{}},[S]);const O=f(()=>{const o=P();B(o);y("targets")},[]);const $=f(async o=>{await c.setTarget(o.instance,o.label,o.fiber);if(b.trim()){await c.setImageUri(b.trim());c.setEnabled(true)}y("controls")},[]);const v=f(async()=>{const o=b.trim();if(!o)return;if(s==="free"){await c.startFreeMode(o)}else{await c.setImageUri(o);c.setEnabled(true)}},[s]);const L=f(async()=>{let o=null;try{o=Q()}catch{}let h=null;if(!o){try{const g=Z();h=g.default||g}catch{}}if(!o&&!h){x.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(o&&typeof o.hasImageAsync==="function"){const J=await o.hasImageAsync();if(J){const w=await o.getImageAsync({format:"png"});if(w?.data){if(s==="free"){await c.startFreeMode(w.data)}else{await c.setImageUri(w.data);c.setEnabled(true)}return}}}let g=null;if(o&&typeof o.getStringAsync==="function"){g=await o.getStringAsync()}else if(h&&typeof h.getString==="function"){g=await h.getString()}if(g&&(g.startsWith("http")||g.startsWith("data:"))){p(g);b=g;return}if(!o){x.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}else{x.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there.")}}catch{x.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[s]);const q=f(()=>{c.reset();b="";y("idle");p("");B([])},[]);const G=f(()=>{if(s==="controls"){const o=P();B(o);y("targets")}else if(s==="targets"||s==="free"){c.reset();y("idle")}else{y("idle")}},[s]);const N=(()=>{switch(s){case"targets":return`Targets (${z.length})`;case"controls":return n.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})();const k={showToggleButton:false,customContent:r(C,{children:[t(C.Navigation,{onBack:s!=="idle"?G:U}),t(C.Content,{title:N,testID:"buoy-image-overlay-title"}),r(C.Actions,{children:[s==="targets"&&t(d,{style:e.headerTextButton,onPress:O,testID:"buoy-image-overlay-scan",activeOpacity:.7,children:t(l,{style:e.headerTextButtonLabel,children:"Scan"})}),(s==="controls"||s==="free")&&n.imageUri&&t(ie,{isEnabled:n.enabled,onToggle:()=>c.toggle(),accessibilityLabel:"Toggle image overlay",testID:"buoy-image-overlay-power"}),s!=="idle"&&t(d,{style:e.headerActionButton,onPress:q,testID:"buoy-image-overlay-clear",activeOpacity:.7,children:t(oe,{size:14,color:i.color.textSecondary})})]})]})};const A=r(a,{style:e.container,children:[s==="idle"&&r(a,{style:e.homeContainer,children:[t(l,{style:e.homeSubtitle,testID:"buoy-image-overlay-home",children:"Choose a mode"}),r(a,{style:e.modeGrid,children:[r(d,{style:e.modePanel,onPress:O,testID:"buoy-image-overlay-mode-component",activeOpacity:.7,children:[t(a,{style:[e.modeIconCircle,{backgroundColor:i.color.accentSoft}],children:t(ne,{size:24,color:i.color.accent})}),r(l,{style:e.modePanelTitle,children:["Component","\n","Match"]}),t(l,{style:e.modePanelDesc,children:"Overlay on a tagged component"})]}),r(d,{style:e.modePanel,onPress:()=>y("free"),testID:"buoy-image-overlay-mode-free",activeOpacity:.7,children:[t(a,{style:[e.modeIconCircle,{backgroundColor:i.color.accentSoft}],children:t(re,{size:24,color:i.color.accent})}),r(l,{style:e.modePanelTitle,children:["Free","\n","Placement"]}),t(l,{style:e.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),s==="targets"&&t(ce,{targets:z,onSelect:$}),s==="controls"&&r(a,{style:e.controlsContainer,children:[n.targetRect&&r(a,{style:e.infoCard,children:[r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Component"}),t(l,{style:e.infoValue,testID:"buoy-image-overlay-info-component",children:n.targetLabel})]}),r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Size"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(n.targetRect.width)," x ",Math.round(n.targetRect.height)]})]}),r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Position"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(n.targetRect.x),", ",Math.round(n.targetRect.y)]})]}),n.imageWidth!=null&&n.imageHeight!=null&&r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Image"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-image",children:[n.imageWidth," x ",n.imageHeight]})]})]}),r(a,{style:e.inputSection,children:[t(l,{style:e.sectionLabel,children:"Image"}),t(d,{style:e.pasteButton,onPress:L,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:t(l,{style:e.pasteButtonText,children:"Paste from Clipboard"})}),r(a,{style:e.urlRow,children:[t(M,{style:e.urlInput,testID:"buoy-image-overlay-url",value:u,onChangeText:p,placeholder:"or enter URL...",placeholderTextColor:i.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:v}),t(d,{style:[e.loadButton,!u.trim()&&e.loadButtonDisabled],onPress:v,disabled:!u.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:t(l,{style:e.loadButtonText,children:"Load"})})]})]}),r(a,{style:e.toggleSection,children:[t(R,{label:"Show Outline",testID:"buoy-image-overlay-outline-toggle",value:n.showOutline,onValueChange:o=>c.setShowOutline(o)}),t(R,{label:"Auto Track",value:S,onValueChange:_,testID:"buoy-image-overlay-autotrack"}),n.imageUri&&r(V,{children:[r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Opacity"}),t(a,{style:e.blendButtons,children:[0,25,50,75,100].map(o=>t(d,{testID:`buoy-image-overlay-opacity-${o}`,style:[e.blendButton,Math.round(n.opacity*100)===o&&e.blendButtonActive],onPress:()=>c.setOpacity(o/100),activeOpacity:.7,children:r(l,{style:[e.blendButtonText,Math.round(n.opacity*100)===o&&e.blendButtonTextActive],children:[o,"%"]})},o))})]}),r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Flip"}),r(a,{style:e.blendButtons,children:[t(d,{style:[e.blendButton,n.invertX&&e.blendButtonActive],onPress:()=>c.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertX&&e.blendButtonTextActive],testID:n.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),t(d,{style:[e.blendButton,n.invertY&&e.blendButtonActive],onPress:()=>c.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertY&&e.blendButtonTextActive],testID:n.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]})]}),n.imageUri&&t(H,{opacity:n.opacity,scale:n.scale,offsetX:n.offsetX,offsetY:n.offsetY,onOpacityChange:o=>c.setOpacity(o),onScaleChange:o=>c.setScale(o),onOffsetChange:(o,h)=>c.setOffset(o,h)}),r(a,{style:e.actions,children:[t(d,{style:e.actionButton,onPress:()=>c.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-settings",children:t(l,{style:e.actionButtonText,children:"Reset Settings"})}),t(d,{style:e.actionButton,onPress:()=>c.remeasure(),activeOpacity:.7,testID:"buoy-image-overlay-remeasure",children:t(l,{style:e.actionButtonText,children:"Remeasure"})})]})]}),s==="free"&&r(a,{style:e.controlsContainer,children:[r(a,{style:e.inputSection,children:[t(l,{style:e.sectionLabel,children:"Image"}),t(d,{style:e.pasteButton,onPress:L,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:t(l,{style:e.pasteButtonText,children:"Paste from Clipboard"})}),r(a,{style:e.urlRow,children:[t(M,{style:e.urlInput,testID:"buoy-image-overlay-url",value:u,onChangeText:p,placeholder:"or enter URL...",placeholderTextColor:i.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:v}),t(d,{style:[e.loadButton,!u.trim()&&e.loadButtonDisabled],onPress:v,disabled:!u.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:t(l,{style:e.loadButtonText,children:"Load"})})]})]}),n.imageUri&&n.mode==="free"&&r(V,{children:[r(a,{style:e.infoCard,children:[r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Position"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(n.freeX),", ",Math.round(n.freeY)]})]}),r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Size"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(n.freeWidth)," x ",Math.round(n.freeHeight)]})]}),n.imageWidth!=null&&n.imageHeight!=null&&r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Original"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-original",children:[n.imageWidth," x ",n.imageHeight]})]})]}),t(a,{style:e.inputSection,children:t(H,{opacity:n.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:o=>c.setOpacity(o),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),r(a,{style:e.toggleSection,children:[t(R,{label:"Lock Position",testID:"buoy-image-overlay-lock",tone:"warning",value:n.locked,onValueChange:o=>c.setLocked(o)}),r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Opacity"}),t(a,{style:e.blendButtons,children:[0,25,50,75,100].map(o=>t(d,{testID:`buoy-image-overlay-opacity-${o}`,style:[e.blendButton,Math.round(n.opacity*100)===o&&e.blendButtonActive],onPress:()=>c.setOpacity(o/100),activeOpacity:.7,children:r(l,{style:[e.blendButtonText,Math.round(n.opacity*100)===o&&e.blendButtonTextActive],children:[o,"%"]})},o))})]}),r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Flip"}),r(a,{style:e.blendButtons,children:[t(d,{style:[e.blendButton,n.invertX&&e.blendButtonActive],onPress:()=>c.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertX&&e.blendButtonTextActive],testID:n.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),t(d,{style:[e.blendButton,n.invertY&&e.blendButtonActive],onPress:()=>c.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertY&&e.blendButtonTextActive],testID:n.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]}),t(a,{style:e.actions,children:t(d,{style:e.actionButton,onPress:()=>c.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-position",children:t(l,{style:e.actionButtonText,children:"Reset Position"})})})]})]})]});if(F){return r(a,{style:e.inlineRoot,children:[t(a,{style:e.inlineHeader,...le,children:k.customContent}),A]})}return t(te,{visible:I,onClose:j,onMinimize:Y,minimizeTargetPosition:E,initialModalState:X,header:k,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:A})}export function ImageOverlayToolView(I={}){return t(ImageOverlayModal,{...I,inline:true,visible:true,onClose:()=>{}})}const e=ee.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:W.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:W.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:i.color.buttonSurface,borderWidth:1,borderColor:i.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:i.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:i.color.buttonSurface,borderWidth:1,borderColor:i.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:i.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:i.color.surface,borderRadius:12,borderWidth:1,borderColor:i.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:i.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:i.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:i.color.surface,borderRadius:8,borderWidth:1,borderColor:i.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:i.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:i.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:i.color.text,fontFamily:ae},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:i.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:i.color.accentSoft,borderWidth:1,borderColor:i.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:i.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:i.color.surfaceElevated,borderWidth:1,borderColor:i.color.border,paddingHorizontal:12,fontSize:13,color:i.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:i.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:i.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:i.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:i.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:i.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:i.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:i.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:i.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:i.color.textTertiary},blendButtonTextActive:{color:i.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:i.color.surfaceElevated,borderWidth:1,borderColor:i.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:i.color.textSecondary}});
1
+ "use strict";import{loadImageClipboard as Q,loadTextClipboard as Z}from"../utils/imageClipboard";import{useState as m,useEffect as D,useCallback as f}from"react";import{View as a,Text as l,TextInput as M,TouchableOpacity as d,StyleSheet as ee,Alert as x}from"react-native";import{JsModal as te,ModalHeader as C,macOSColors as W,night as i,Trash2 as oe,SquareDashed as ne,Image as re,PowerToggleButton as ie,windowDragProps as le,ToggleRow as R,monoFont as ae}from"@buoy-gg/shared-ui";import{ImageOverlayController as c}from"../utils/ImageOverlayController";import{scanForImageTargets as P}from"../utils/fiberScanner";import{TargetList as ce}from"./TargetList";import{OverlayControls as H}from"./OverlayControls";import{jsx as t,jsxs as r,Fragment as V}from"react/jsx-runtime";let b="";export function ImageOverlayModal({visible:I,onClose:j,onBack:U,onMinimize:Y,enableSharedModalDimensions:se=false,initialModalState:F,minimizeTargetPosition:X,inline:E=false,initialView:T}){const[s,y]=m(()=>{if(T)return T;const o=c.getState();if(o.mode==="free")return"free";if(o.targetRect)return"controls";return"idle"});const[z,B]=m(()=>T==="targets"?P():[]);const[n,K]=m(()=>c.getState());const[u,p]=m(b);const[S,_]=m(()=>c.isAutoTracking());D(()=>{b=u},[u]);D(()=>{return c.subscribe(K)},[]);D(()=>{c.setAutoTrack(S);return()=>{}},[S]);const O=f(()=>{const o=P();B(o);y("targets")},[]);const $=f(async o=>{await c.setTarget(o.instance,o.label,o.fiber);if(b.trim()){await c.setImageUri(b.trim());c.setEnabled(true)}y("controls")},[]);const v=f(async()=>{const o=b.trim();if(!o)return;if(s==="free"){await c.startFreeMode(o)}else{await c.setImageUri(o);c.setEnabled(true)}},[s]);const L=f(async()=>{let o=null;try{o=Q()}catch{}let h=null;if(!o){try{const g=Z();h=g.default||g}catch{}}if(!o&&!h){x.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(o&&typeof o.hasImageAsync==="function"){const J=await o.hasImageAsync();if(J){const w=await o.getImageAsync({format:"png"});if(w?.data){if(s==="free"){await c.startFreeMode(w.data)}else{await c.setImageUri(w.data);c.setEnabled(true)}return}}}let g=null;if(o&&typeof o.getStringAsync==="function"){g=await o.getStringAsync()}else if(h&&typeof h.getString==="function"){g=await h.getString()}if(g&&(g.startsWith("http")||g.startsWith("data:"))){p(g);b=g;return}if(!o){x.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}else{x.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there.")}}catch{x.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[s]);const q=f(()=>{c.reset();b="";y("idle");p("");B([])},[]);const G=f(()=>{if(s==="controls"){const o=P();B(o);y("targets")}else if(s==="targets"||s==="free"){c.reset();y("idle")}else{y("idle")}},[s]);const N=(()=>{switch(s){case"targets":return`Targets (${z.length})`;case"controls":return n.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})();const k={showToggleButton:false,customContent:r(C,{children:[t(C.Navigation,{onBack:s!=="idle"?G:U}),t(C.Content,{title:N,testID:"buoy-image-overlay-title"}),r(C.Actions,{children:[s==="targets"&&t(d,{style:e.headerTextButton,onPress:O,testID:"buoy-image-overlay-scan",activeOpacity:.7,children:t(l,{style:e.headerTextButtonLabel,children:"Scan"})}),(s==="controls"||s==="free")&&n.imageUri&&t(ie,{isEnabled:n.enabled,onToggle:()=>c.toggle(),accessibilityLabel:"Toggle image overlay",testID:"buoy-image-overlay-power"}),s!=="idle"&&t(d,{style:e.headerActionButton,onPress:q,testID:"buoy-image-overlay-clear",activeOpacity:.7,children:t(oe,{size:14,color:i.color.textSecondary})})]})]})};const A=r(a,{style:e.container,children:[s==="idle"&&r(a,{style:e.homeContainer,children:[t(l,{style:e.homeSubtitle,testID:"buoy-image-overlay-home",children:"Choose a mode"}),r(a,{style:e.modeGrid,children:[r(d,{style:e.modePanel,onPress:O,testID:"buoy-image-overlay-mode-component",activeOpacity:.7,accessibilityRole:"button",accessibilityLabel:"Component Match. Overlay on a tagged component",children:[t(a,{style:[e.modeIconCircle,{backgroundColor:i.color.accentSoft}],children:t(ne,{size:24,color:i.color.accent})}),r(l,{style:e.modePanelTitle,children:["Component","\n","Match"]}),t(l,{style:e.modePanelDesc,children:"Overlay on a tagged component"})]}),r(d,{style:e.modePanel,onPress:()=>y("free"),testID:"buoy-image-overlay-mode-free",activeOpacity:.7,accessibilityRole:"button",accessibilityLabel:"Free Placement. Drag and resize anywhere",children:[t(a,{style:[e.modeIconCircle,{backgroundColor:i.color.accentSoft}],children:t(re,{size:24,color:i.color.accent})}),r(l,{style:e.modePanelTitle,children:["Free","\n","Placement"]}),t(l,{style:e.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),s==="targets"&&t(ce,{targets:z,onSelect:$}),s==="controls"&&r(a,{style:e.controlsContainer,children:[n.targetRect&&r(a,{style:e.infoCard,children:[r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Component"}),t(l,{style:e.infoValue,testID:"buoy-image-overlay-info-component",children:n.targetLabel})]}),r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Size"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(n.targetRect.width)," x ",Math.round(n.targetRect.height)]})]}),r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Position"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(n.targetRect.x),", ",Math.round(n.targetRect.y)]})]}),n.imageWidth!=null&&n.imageHeight!=null&&r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Image"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-image",children:[n.imageWidth," x ",n.imageHeight]})]})]}),r(a,{style:e.inputSection,children:[t(l,{style:e.sectionLabel,children:"Image"}),t(d,{style:e.pasteButton,onPress:L,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:t(l,{style:e.pasteButtonText,children:"Paste from Clipboard"})}),r(a,{style:e.urlRow,children:[t(M,{style:e.urlInput,testID:"buoy-image-overlay-url",value:u,onChangeText:p,placeholder:"or enter URL...",placeholderTextColor:i.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:v}),t(d,{style:[e.loadButton,!u.trim()&&e.loadButtonDisabled],onPress:v,disabled:!u.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:t(l,{style:e.loadButtonText,children:"Load"})})]})]}),r(a,{style:e.toggleSection,children:[t(R,{label:"Show Outline",testID:"buoy-image-overlay-outline-toggle",value:n.showOutline,onValueChange:o=>c.setShowOutline(o)}),t(R,{label:"Auto Track",value:S,onValueChange:_,testID:"buoy-image-overlay-autotrack"}),n.imageUri&&r(V,{children:[r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Opacity"}),t(a,{style:e.blendButtons,children:[0,25,50,75,100].map(o=>t(d,{testID:`buoy-image-overlay-opacity-${o}`,style:[e.blendButton,Math.round(n.opacity*100)===o&&e.blendButtonActive],onPress:()=>c.setOpacity(o/100),activeOpacity:.7,children:r(l,{style:[e.blendButtonText,Math.round(n.opacity*100)===o&&e.blendButtonTextActive],children:[o,"%"]})},o))})]}),r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Flip"}),r(a,{style:e.blendButtons,children:[t(d,{style:[e.blendButton,n.invertX&&e.blendButtonActive],onPress:()=>c.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertX&&e.blendButtonTextActive],testID:n.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),t(d,{style:[e.blendButton,n.invertY&&e.blendButtonActive],onPress:()=>c.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertY&&e.blendButtonTextActive],testID:n.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]})]}),n.imageUri&&t(H,{opacity:n.opacity,scale:n.scale,offsetX:n.offsetX,offsetY:n.offsetY,onOpacityChange:o=>c.setOpacity(o),onScaleChange:o=>c.setScale(o),onOffsetChange:(o,h)=>c.setOffset(o,h)}),r(a,{style:e.actions,children:[t(d,{style:e.actionButton,onPress:()=>c.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-settings",children:t(l,{style:e.actionButtonText,children:"Reset Settings"})}),t(d,{style:e.actionButton,onPress:()=>c.remeasure(),activeOpacity:.7,testID:"buoy-image-overlay-remeasure",children:t(l,{style:e.actionButtonText,children:"Remeasure"})})]})]}),s==="free"&&r(a,{style:e.controlsContainer,children:[r(a,{style:e.inputSection,children:[t(l,{style:e.sectionLabel,children:"Image"}),t(d,{style:e.pasteButton,onPress:L,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:t(l,{style:e.pasteButtonText,children:"Paste from Clipboard"})}),r(a,{style:e.urlRow,children:[t(M,{style:e.urlInput,testID:"buoy-image-overlay-url",value:u,onChangeText:p,placeholder:"or enter URL...",placeholderTextColor:i.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:v}),t(d,{style:[e.loadButton,!u.trim()&&e.loadButtonDisabled],onPress:v,disabled:!u.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:t(l,{style:e.loadButtonText,children:"Load"})})]})]}),n.imageUri&&n.mode==="free"&&r(V,{children:[r(a,{style:e.infoCard,children:[r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Position"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(n.freeX),", ",Math.round(n.freeY)]})]}),r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Size"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(n.freeWidth)," x ",Math.round(n.freeHeight)]})]}),n.imageWidth!=null&&n.imageHeight!=null&&r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Original"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-original",children:[n.imageWidth," x ",n.imageHeight]})]})]}),t(a,{style:e.inputSection,children:t(H,{opacity:n.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:o=>c.setOpacity(o),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),r(a,{style:e.toggleSection,children:[t(R,{label:"Lock Position",testID:"buoy-image-overlay-lock",tone:"warning",value:n.locked,onValueChange:o=>c.setLocked(o)}),r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Opacity"}),t(a,{style:e.blendButtons,children:[0,25,50,75,100].map(o=>t(d,{testID:`buoy-image-overlay-opacity-${o}`,style:[e.blendButton,Math.round(n.opacity*100)===o&&e.blendButtonActive],onPress:()=>c.setOpacity(o/100),activeOpacity:.7,children:r(l,{style:[e.blendButtonText,Math.round(n.opacity*100)===o&&e.blendButtonTextActive],children:[o,"%"]})},o))})]}),r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Flip"}),r(a,{style:e.blendButtons,children:[t(d,{style:[e.blendButton,n.invertX&&e.blendButtonActive],onPress:()=>c.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertX&&e.blendButtonTextActive],testID:n.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),t(d,{style:[e.blendButton,n.invertY&&e.blendButtonActive],onPress:()=>c.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertY&&e.blendButtonTextActive],testID:n.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]}),t(a,{style:e.actions,children:t(d,{style:e.actionButton,onPress:()=>c.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-position",children:t(l,{style:e.actionButtonText,children:"Reset Position"})})})]})]})]});if(E){return r(a,{style:e.inlineRoot,children:[t(a,{style:e.inlineHeader,...le,children:k.customContent}),A]})}return t(te,{visible:I,onClose:j,onMinimize:Y,minimizeTargetPosition:X,initialModalState:F,header:k,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:A})}export function ImageOverlayToolView(I={}){return t(ImageOverlayModal,{...I,inline:true,visible:true,onClose:()=>{}})}const e=ee.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:W.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:W.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:i.color.buttonSurface,borderWidth:1,borderColor:i.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:i.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:i.color.buttonSurface,borderWidth:1,borderColor:i.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:i.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:i.color.surface,borderRadius:12,borderWidth:1,borderColor:i.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:i.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:i.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:i.color.surface,borderRadius:8,borderWidth:1,borderColor:i.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:i.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:i.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:i.color.text,fontFamily:ae},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:i.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:i.color.accentSoft,borderWidth:1,borderColor:i.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:i.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:i.color.surfaceElevated,borderWidth:1,borderColor:i.color.border,paddingHorizontal:12,fontSize:13,color:i.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:i.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:i.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:i.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:i.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:i.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:i.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:i.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:i.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:i.color.textTertiary},blendButtonTextActive:{color:i.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:i.color.surfaceElevated,borderWidth:1,borderColor:i.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:i.color.textSecondary}});
@@ -1 +1 @@
1
- "use strict";import oe,{useState as T,useEffect as N,useRef as z,useMemo as B,useCallback as U}from"react";import{View as i,Text as V,Image as Z,StyleSheet as j,PanResponder as k,Dimensions as J,Platform as K}from"react-native";import{absoluteFill as Q,monoFont as $}from"@buoy-gg/shared-ui";import{ImageOverlayController as R}from"../utils/ImageOverlayController";import{jsx as r,Fragment as q,jsxs as L}from"react/jsx-runtime";function G({uri:P,style:C,invertX:W,invertY:M}){const d=[];if(W)d.push({scaleX:-1});if(M)d.push({scaleY:-1});const x=d.length>0?{transform:d}:{};return r(Z,{testID:"buoy-internal-image-overlay",source:{uri:P},style:[C,x],pointerEvents:"none"})}const I=30;function ee({imageUri:P,x:C,y:W,width:M,height:d,opacity:x,aspectRatio:m,invertX:n,invertY:D,locked:l}){const[b,p]=T(false);const _=z({x:0,y:0});const X=z({x:0,y:0,width:0,height:0});const c=J.get("window");const Y=B(()=>k.create({onStartShouldSetPanResponder:()=>!l,onMoveShouldSetPanResponder:(u,s)=>!l&&(Math.abs(s.dx)>2||Math.abs(s.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const u=R.getState();_.current={x:u.freeX,y:u.freeY};p(true)},onPanResponderMove:(u,s)=>{const H=R.getState();const f=Math.max(0,Math.min(_.current.x+s.dx,c.width-H.freeWidth));const g=Math.max(0,Math.min(_.current.y+s.dy,c.height-H.freeHeight));R.setFreePosition(f,g)},onPanResponderRelease:()=>p(false),onPanResponderTerminate:()=>p(false)}),[c.width,c.height,l]);const v=U(u=>k.create({onStartShouldSetPanResponder:()=>!l,onMoveShouldSetPanResponder:()=>!l,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const s=R.getState();X.current={x:s.freeX,y:s.freeY,width:s.freeWidth,height:s.freeHeight};p(true)},onPanResponderMove:(s,H)=>{const{dx:f,dy:g}=H;if(Math.abs(f)<.5&&Math.abs(g)<.5)return;const e=X.current;const h=m>0?m:e.width/e.height;const A=Math.abs(f);const O=Math.abs(g);const E=A>=O;let t;let a;let w=e.x;let y=e.y;switch(u){case"bottomRight":{t=E?e.width+f:(e.height+g)*h;t=Math.max(I,Math.min(t,c.width-e.x));a=t/h;break}case"bottomLeft":{t=E?e.width-f:(e.height+g)*h;t=Math.max(I,t);a=t/h;w=e.x+e.width-t;w=Math.max(0,w);t=Math.min(t,e.x+e.width);a=t/h;break}case"topRight":{t=E?e.width+f:(e.height-g)*h;t=Math.max(I,Math.min(t,c.width-e.x));a=t/h;y=e.y+e.height-a;y=Math.max(0,y);a=Math.min(a,e.y+e.height);t=a*h;break}case"topLeft":{t=E?e.width-f:(e.height-g)*h;t=Math.max(I,t);a=t/h;w=e.x+e.width-t;y=e.y+e.height-a;w=Math.max(0,w);y=Math.max(0,y);t=Math.min(t,e.x+e.width);a=t/h;y=e.y+e.height-a;break}}t=Math.max(I,Math.round(t));a=Math.max(I,Math.round(a));R.setFreeDimensions(t,a,Math.round(w),Math.round(y))},onPanResponderRelease:()=>p(false),onPanResponderTerminate:()=>p(false)}),[c.width,c.height,m,l]);const S=B(()=>({topLeft:v("topLeft"),topRight:v("topRight"),bottomLeft:v("bottomLeft"),bottomRight:v("bottomRight")}),[v]);const F={...Q,opacity:x};return L(i,{testID:"buoy-image-overlay-free-box",style:{position:"absolute",left:C,top:W,width:M,height:d},pointerEvents:l?"none":"auto",children:[r(i,{style:j.absoluteFill,...l?{}:Y.panHandlers,children:r(G,{uri:P,style:F,invertX:n,invertY:D})}),r(i,{pointerEvents:"none",style:[o.freeBorder,b&&o.freeBorderActive,l&&o.freeBorderLocked]}),!l&&L(q,{children:[r(i,{...S.topLeft.panHandlers,style:[o.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.topRight.panHandlers,style:[o.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.bottomLeft.panHandlers,style:[o.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.bottomRight.panHandlers,style:[o.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})})]})]})}export function ImageOverlayStandalone(){const[P,C]=T(()=>R.getState());N(()=>{return R.subscribe(C)},[]);const{mode:W,enabled:M,imageUri:d,imageWidth:x,imageHeight:m,targetRect:n,targetLabel:D,showOutline:l,opacity:b,scale:p,offsetX:_,offsetY:X,invertX:c,invertY:Y,locked:v,freeX:S,freeY:F,freeWidth:u,freeHeight:s}=P;const H=x&&m&&m>0?x/m:0;if(W==="free"&&M&&d){return r(i,{style:o.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:r(ee,{imageUri:d,x:S,y:F,width:u,height:s,opacity:b,aspectRatio:H,invertX:c,invertY:Y,locked:v})})}if(!n)return null;const f=M&&d;return L(i,{style:o.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[l&&L(q,{children:[r(i,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",testID:"buoy-image-overlay-outline",style:[o.highlight,{left:n.x-3,top:n.y-3,width:n.width+6,height:n.height+6}]}),D&&r(i,{pointerEvents:"none",style:[o.label,{left:n.x,top:n.y-20}],children:r(V,{style:o.labelText,testID:"buoy-image-overlay-outline-label",children:D})})]}),f&&(()=>{const g=(x??n.width)*p;const e=(m??n.height)*p;const h=n.x+n.width/2;const A=n.y+n.height/2;const O={position:"absolute",left:h-g/2+_,top:A-e/2+X,width:g,height:e,opacity:b};return r(G,{uri:d,style:O,invertX:c,invertY:Y})})()]})}const o=j.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:K.OS==="web"?999:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:$},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});
1
+ "use strict";import oe,{useState as T,useEffect as N,useRef as z,useMemo as B,useCallback as U}from"react";import{View as i,Text as V,Image as Z,StyleSheet as j,PanResponder as k,Dimensions as J,Platform as K}from"react-native";import{absoluteFill as Q,monoFont as $}from"@buoy-gg/shared-ui";import{ImageOverlayController as R}from"../utils/ImageOverlayController";import{jsx as r,Fragment as q,jsxs as L}from"react/jsx-runtime";function G({uri:P,style:C,invertX:W,invertY:M}){const d=[];if(W)d.push({scaleX:-1});if(M)d.push({scaleY:-1});const x=d.length>0?{transform:d}:{};return r(Z,{testID:"buoy-internal-image-overlay",source:{uri:P},style:[C,x,{pointerEvents:"none"}]})}const I=30;function ee({imageUri:P,x:C,y:W,width:M,height:d,opacity:x,aspectRatio:m,invertX:n,invertY:D,locked:l}){const[b,p]=T(false);const _=z({x:0,y:0});const X=z({x:0,y:0,width:0,height:0});const c=J.get("window");const Y=B(()=>k.create({onStartShouldSetPanResponder:()=>!l,onMoveShouldSetPanResponder:(u,s)=>!l&&(Math.abs(s.dx)>2||Math.abs(s.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const u=R.getState();_.current={x:u.freeX,y:u.freeY};p(true)},onPanResponderMove:(u,s)=>{const H=R.getState();const f=Math.max(0,Math.min(_.current.x+s.dx,c.width-H.freeWidth));const g=Math.max(0,Math.min(_.current.y+s.dy,c.height-H.freeHeight));R.setFreePosition(f,g)},onPanResponderRelease:()=>p(false),onPanResponderTerminate:()=>p(false)}),[c.width,c.height,l]);const v=U(u=>k.create({onStartShouldSetPanResponder:()=>!l,onMoveShouldSetPanResponder:()=>!l,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const s=R.getState();X.current={x:s.freeX,y:s.freeY,width:s.freeWidth,height:s.freeHeight};p(true)},onPanResponderMove:(s,H)=>{const{dx:f,dy:g}=H;if(Math.abs(f)<.5&&Math.abs(g)<.5)return;const e=X.current;const h=m>0?m:e.width/e.height;const A=Math.abs(f);const O=Math.abs(g);const E=A>=O;let t;let a;let w=e.x;let y=e.y;switch(u){case"bottomRight":{t=E?e.width+f:(e.height+g)*h;t=Math.max(I,Math.min(t,c.width-e.x));a=t/h;break}case"bottomLeft":{t=E?e.width-f:(e.height+g)*h;t=Math.max(I,t);a=t/h;w=e.x+e.width-t;w=Math.max(0,w);t=Math.min(t,e.x+e.width);a=t/h;break}case"topRight":{t=E?e.width+f:(e.height-g)*h;t=Math.max(I,Math.min(t,c.width-e.x));a=t/h;y=e.y+e.height-a;y=Math.max(0,y);a=Math.min(a,e.y+e.height);t=a*h;break}case"topLeft":{t=E?e.width-f:(e.height-g)*h;t=Math.max(I,t);a=t/h;w=e.x+e.width-t;y=e.y+e.height-a;w=Math.max(0,w);y=Math.max(0,y);t=Math.min(t,e.x+e.width);a=t/h;y=e.y+e.height-a;break}}t=Math.max(I,Math.round(t));a=Math.max(I,Math.round(a));R.setFreeDimensions(t,a,Math.round(w),Math.round(y))},onPanResponderRelease:()=>p(false),onPanResponderTerminate:()=>p(false)}),[c.width,c.height,m,l]);const S=B(()=>({topLeft:v("topLeft"),topRight:v("topRight"),bottomLeft:v("bottomLeft"),bottomRight:v("bottomRight")}),[v]);const F={...Q,opacity:x};return L(i,{testID:"buoy-image-overlay-free-box",style:{position:"absolute",left:C,top:W,width:M,height:d},pointerEvents:l?"none":"auto",children:[r(i,{style:j.absoluteFill,...l?{}:Y.panHandlers,children:r(G,{uri:P,style:F,invertX:n,invertY:D})}),r(i,{pointerEvents:"none",style:[o.freeBorder,b&&o.freeBorderActive,l&&o.freeBorderLocked]}),!l&&L(q,{children:[r(i,{...S.topLeft.panHandlers,style:[o.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.topRight.panHandlers,style:[o.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.bottomLeft.panHandlers,style:[o.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.bottomRight.panHandlers,style:[o.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})})]})]})}export function ImageOverlayStandalone(){const[P,C]=T(()=>R.getState());N(()=>{return R.subscribe(C)},[]);const{mode:W,enabled:M,imageUri:d,imageWidth:x,imageHeight:m,targetRect:n,targetLabel:D,showOutline:l,opacity:b,scale:p,offsetX:_,offsetY:X,invertX:c,invertY:Y,locked:v,freeX:S,freeY:F,freeWidth:u,freeHeight:s}=P;const H=x&&m&&m>0?x/m:0;if(W==="free"&&M&&d){return r(i,{style:o.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:r(ee,{imageUri:d,x:S,y:F,width:u,height:s,opacity:b,aspectRatio:H,invertX:c,invertY:Y,locked:v})})}if(!n)return null;const f=M&&d;return L(i,{style:o.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[l&&L(q,{children:[r(i,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",testID:"buoy-image-overlay-outline",style:[o.highlight,{left:n.x-3,top:n.y-3,width:n.width+6,height:n.height+6}]}),D&&r(i,{pointerEvents:"none",style:[o.label,{left:n.x,top:n.y-20}],children:r(V,{style:o.labelText,testID:"buoy-image-overlay-outline-label",children:D})})]}),f&&(()=>{const g=(x??n.width)*p;const e=(m??n.height)*p;const h=n.x+n.width/2;const A=n.y+n.height/2;const O={position:"absolute",left:h-g/2+_,top:A-e/2+X,width:g,height:e,opacity:b};return r(G,{uri:d,style:O,invertX:c,invertY:Y})})()]})}const o=j.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:K.OS==="web"?999:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:$},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});
package/lib/web/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- "use client";var Oe=Object.defineProperty;var lt=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var ct=Object.prototype.hasOwnProperty;var dt=(e,t)=>{for(var n in t)Oe(e,n,{get:t[n],enumerable:true})},Ae=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of st(t))!ct.call(e,r)&&r!==n&&Oe(e,r,{get:()=>t[r],enumerable:!(a=lt(t,r))||a.enumerable});return e},ut=(e,t,n)=>(Ae(e,t,"default"),n&&Ae(n,t,"default"));var en=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{ImageOverlayIcon as ht,createToolFactory as gt,defineToolPreset as yt}from"@buoy-gg/shared-ui/web";var ie;function pt(){return typeof navigator>"u"||!navigator.clipboard?null:{async hasImageAsync(){if(ie=void 0,!navigator.clipboard.read)return false;let e=await navigator.clipboard.read();for(let t of e){let n=t.types.find(a=>a.startsWith("image/"));if(n)return ie=await t.getType(n),true}return false},async getImageAsync(){if(!ie)return null;let e=ie;return ie=void 0,{data:await new Promise((t,n)=>{let a=new FileReader;a.onload=()=>t(String(a.result)),a.onerror=n,a.readAsDataURL(e)})}},getStringAsync:()=>navigator.clipboard.readText()}}function ft(){return null}import{useState as le,useEffect as Se,useCallback as oe}from"react";var He={};dt(He,{AccessibilityInfo:()=>xt,ActivityIndicator:()=>fo,Alert:()=>ce,Animated:()=>wt,AppRegistry:()=>St,AppState:()=>Ct,Appearance:()=>It,BackHandler:()=>Tt,Button:()=>mo,CheckBox:()=>Et,Clipboard:()=>Rt,DeviceEventEmitter:()=>Qt,Dimensions:()=>fe,Easing:()=>Bt,FlatList:()=>Wt,I18nManager:()=>Mt,Image:()=>Ce,ImageBackground:()=>Vt,InteractionManager:()=>Pt,Keyboard:()=>Dt,KeyboardAvoidingView:()=>Ft,LayoutAnimation:()=>kt,Linking:()=>Lt,LogBox:()=>Jt,Modal:()=>yo,NativeEventEmitter:()=>Ot,NativeModules:()=>vt,PanResponder:()=>me,Picker:()=>Yt,PixelRatio:()=>At,Platform:()=>ze,Pressable:()=>go,ProgressBar:()=>Xt,RefreshControl:()=>jt,SafeAreaView:()=>Nt,ScrollView:()=>Ye,SectionList:()=>Ut,Share:()=>Ht,StatusBar:()=>_t,StyleSheet:()=>ne,Switch:()=>po,Text:()=>y,TextInput:()=>Re,Touchable:()=>$t,TouchableHighlight:()=>uo,TouchableNativeFeedback:()=>Kt,TouchableOpacity:()=>T,TouchableWithoutFeedback:()=>ho,UIManager:()=>Ee,Vibration:()=>zt,View:()=>s,VirtualizedList:()=>qt,YellowBox:()=>Gt,findNodeHandle:()=>je,unstable_createElement:()=>bt,useColorScheme:()=>Zt,useLocaleContext:()=>eo,useWindowDimensions:()=>to});ut(He,mt);import*as mt from"react-native-web";import{unstable_createElement as bt,NativeModules as vt,AccessibilityInfo as xt,Animated as wt,Appearance as It,AppRegistry as St,AppState as Ct,BackHandler as Tt,Clipboard as Rt,Dimensions as fe,Easing as Bt,I18nManager as Mt,Keyboard as Dt,InteractionManager as Pt,LayoutAnimation as kt,Linking as Lt,NativeEventEmitter as Ot,PanResponder as me,PixelRatio as At,Platform as ze,Share as Ht,StyleSheet as ne,UIManager as Ee,Vibration as zt,CheckBox as Et,FlatList as Wt,Image as Ce,ImageBackground as Vt,KeyboardAvoidingView as Ft,Picker as Yt,ProgressBar as Xt,RefreshControl as jt,SafeAreaView as Nt,SectionList as Ut,StatusBar as _t,Touchable as $t,TouchableNativeFeedback as Kt,VirtualizedList as qt,YellowBox as Gt,LogBox as Jt,DeviceEventEmitter as Qt,useColorScheme as Zt,useLocaleContext as eo,useWindowDimensions as to}from"react-native-web";import*as V from"react-native-web";import{createElement as Te,forwardRef as We,useCallback as oo,useRef as no}from"react";import{useEffect as ro,useState as ao}from"react";import{createPortal as io}from"react-dom";var lo='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as so}from"react/jsx-runtime";var se=Symbol.for("@buoy-gg/portal-host"),Ve=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function Fe(){let e=document;if(e[se])return e[se].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:lo});let n=()=>{let c=document.fullscreenElement,R=c&&c.tagName!=="CANVAS"?c:document.body;t.parentElement!==R&&R.appendChild(t)},a=new Map,r=c=>{(!t.contains(c.target)||!Ve(c.target))&&a.set(c.code||c.key,{key:c.key,code:c.code,location:c.location,keyCode:c.keyCode,which:c.which,altKey:c.altKey,ctrlKey:c.ctrlKey,metaKey:c.metaKey,shiftKey:c.shiftKey})},g=c=>{a.delete(c.code||c.key)},w=()=>a.clear(),p=()=>{let c=[...a.values()];a.clear();for(let R of c)document.dispatchEvent(new KeyboardEvent("keyup",{...R,bubbles:true}))},b=c=>{Ve(c.target)&&c.stopPropagation()},d=c=>c.stopPropagation();return n(),document.addEventListener("fullscreenchange",n),document.addEventListener("keydown",r,true),document.addEventListener("keyup",g,true),window.addEventListener("blur",w),t.addEventListener("focusin",p),t.addEventListener("keydown",b),t.addEventListener("keyup",b),t.addEventListener("keypress",b),t.addEventListener("wheel",d,{passive:true}),e[se]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",n),document.removeEventListener("keydown",r,true),document.removeEventListener("keyup",g,true),window.removeEventListener("blur",w),t.remove(),delete e[se]}},t}function co({children:e}){let[t,n]=ao(null);return ro(()=>{let a=Fe(),r=document[se];return r.users++,n(a),()=>{--r.users===0&&r.dispose()}},[]),t?io(so("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}function N(e){let t=We((a,r)=>{let{accessibilityState:g,accessibilityValue:w,...p}=a;for(let b of["busy","checked","disabled","expanded","selected"])g?.[b]!==void 0&&p[`aria-${b}`]===void 0&&(p[`aria-${b}`]=g[b]);for(let[b,d]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))w?.[b]!==void 0&&p[`aria-${d}`]===void 0&&(p[`aria-${d}`]=w[b]);return Te(e,{...p,ref:r})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var s=N(V.View),y=N(V.Text),Re=N(V.TextInput),T=N(V.TouchableOpacity),uo=N(V.TouchableHighlight),ho=N(V.TouchableWithoutFeedback),go=N(V.Pressable),Ye=N(V.ScrollView),Xe=We((e,t)=>{let n=no(null),a=oo(r=>{if(r){let g=r;for(;g.parentElement&&g.parentElement!==document.body;)g=g.parentElement;g.parentElement===document.body&&(n.current=g,Object.assign(g.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),Fe().appendChild(g))}else n.current&&(document.body.appendChild(n.current),n.current=null);typeof t=="function"?t(r):t&&(t.current=r)},[t]);return Te(co,null,Te(V.Modal,{...e,ref:a}))});Xe.displayName="Modal";var yo=N(Xe),po=N(V.Switch),fo=N(V.ActivityIndicator),mo=N(V.Button),je=V.findNodeHandle,ce={alert(e,t,n,a){if(typeof document>"u")return;let r=document.createElement("dialog");r.dataset.buoyRoot="",r.setAttribute("aria-label",e),r.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let g=document.createElement("h2");if(g.textContent=e,g.style.cssText="font-size:18px;margin:0 0 12px",r.appendChild(g),t){let d=document.createElement("p");d.textContent=t,d.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",r.appendChild(d)}let w=document.createElement("div");w.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let p=n?.length?n:[{text:"OK"}],b=()=>{r.close?.(),r.remove()};for(let d of p){let c=document.createElement("button");c.type="button",c.textContent=d.text??"OK",c.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${d.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,c.onclick=()=>{b(),d.onPress?.()},w.appendChild(c)}r.addEventListener("cancel",d=>{d.preventDefault(),a?.cancelable!==false&&(b(),a?.onDismiss?.())}),r.appendChild(w),document.body.appendChild(r),r.showModal?r.showModal():r.setAttribute("open","")}};import{JsModal as bo,ModalHeader as be,macOSColors as Ne,night as m,Trash2 as vo,SquareDashed as xo,Image as wo,PowerToggleButton as Io,windowDragProps as So,ToggleRow as Be,monoFont as Co}from"@buoy-gg/shared-ui/web";function Me(e){return new Promise(t=>{try{let n=[];e&&n.push(e),e?.canonical?.publicInstance&&n.push(e.canonical.publicInstance),e?.canonical&&e.canonical!==e&&n.push(e.canonical);for(let a of n)if(typeof a.getBoundingClientRect=="function")try{let r=a.getBoundingClientRect();if(r&&typeof r.x=="number"&&typeof r.y=="number"&&typeof r.width=="number"&&typeof r.height=="number"&&r.width>0&&r.height>0){t({x:r.x,y:r.y,width:r.width,height:r.height});return}}catch{}for(let a of n)if(typeof a.measure=="function"){let r=setTimeout(()=>t(null),200);a.measure((g,w,p,b,d,c)=>{clearTimeout(r),d!=null&&c!=null&&p!=null&&b!=null&&p>0&&b>0?t({x:d,y:c,width:p,height:b}):t(null)});return}try{let a=je(e);if(a!=null){let r=setTimeout(()=>t(null),200);Ee.measure(a,(g,w,p,b,d,c)=>{clearTimeout(r),d!=null&&c!=null&&p!=null&&b!=null&&p>0&&b>0?t({x:d,y:c,width:p,height:b}):t(null)});return}}catch{}t(null)}catch{t(null)}})}var Ue=null;function To(e){Ue=e??null}function _e(){return Ue||(typeof globalThis>"u"?null:globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__??null)}var $e="image-target:",Ro=5,Bo=22;function Mo(){let e=_e();if(!e?.getFiberRoots)return[];let t=new Set,n=e.renderers?.keys?Array.from(e.renderers.keys()):[1];for(let a of n)try{e.getFiberRoots(a)?.forEach(r=>t.add(r))}catch{}return[...t]}function Do(e){return e.tag===Bo&&e.memoizedState!==null}function Po(e){return e.memoizedProps?.activityState===0}function de(e,t,n=0,a=new Set){if(!(!e||a.has(e)||n>500)){if(a.add(e),Do(e)){e.sibling&&de(e.sibling,t,n,a);return}if(Po(e)){e.sibling&&de(e.sibling,t,n,a);return}t(e,n),e.child&&de(e.child,t,n+1,a),e.sibling&&de(e.sibling,t,n,a)}}function ko(e){let t=new Set(["View","RCTView","Text","RCTText","Image","RCTImageView","ScrollView","RCTScrollView","TextInput","RCTTextInput","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","Pressable","FlatList","SectionList","SafeAreaView"]),n=e._debugOwner||e.return,a=0;for(;n&&a<30;){a++;let r=n.type;if(r){let g=typeof r=="string"?r:r.displayName||r.name;if(g&&!t.has(g))return g}n=n.return}return null}function ue(){let e=Mo();if(e.length===0)return[];let t=[];for(let n of e)de(n.current,a=>{if(a.tag!==Ro)return;let r=a.memoizedProps?.testID??a.pendingProps?.testID??a.memoizedProps?.["data-testid"]??a.pendingProps?.["data-testid"];if(!r||!r.startsWith($e))return;let g=r.slice($e.length);g&&t.push({label:g,testID:r,fiber:a,instance:a.stateNode,componentName:ko(a)})});return t}var Ke={mode:null,enabled:false,imageUri:null,imageWidth:null,imageHeight:null,targetTag:null,targetLabel:null,targetRect:null,showOutline:true,opacity:.5,scale:1,offsetX:0,offsetY:0,invertX:false,invertY:false,locked:false,freeX:0,freeY:0,freeWidth:200,freeHeight:200},i={...Ke},De=new Set,K=null,ve=null,he=false,ge=null,Lo=null;function B(){for(let e of De)e(i)}function Oo(e){return e?typeof e._nativeTag=="number"?e._nativeTag:typeof e.canonical?._nativeTag=="number"?e.canonical._nativeTag:typeof e.__nativeTag=="number"?e.__nativeTag:null:null}async function qe(e,t){let n=await Me(e);if(n)return{rect:n,freshInstance:e};let a=ue().find(r=>r.label===t);return a&&(n=await Me(a.instance),n)?{rect:n,freshInstance:a.instance}:{rect:null,freshInstance:e}}function Ao(){if(ge)return;let e=_e();if(e){if(e.rendererInterfaces)for(let[,t]of e.rendererInterfaces)typeof t.setTraceUpdatesEnabled=="function"&&t.setTraceUpdatesEnabled(true);typeof e.sub=="function"&&(ge=e.sub("traceUpdates",Eo))}}var re=null,Pe=false;function Ho(){if(re!==null||typeof requestAnimationFrame!="function")return;let e=()=>{re=requestAnimationFrame(e),!(Pe||!he||!K)&&(Pe=true,Je().finally(()=>{Pe=false}))};re=requestAnimationFrame(e)}function zo(){re!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(re),re=null}function Ge(){zo(),ge&&(ge(),ge=null)}function Eo(e){!he||!K||Je()}function Je(){return Me(K).then(e=>{if(e&&i.targetRect){let t=i.targetRect;(Math.abs(e.x-t.x)>.5||Math.abs(e.y-t.y)>.5||Math.abs(e.width-t.width)>.5||Math.abs(e.height-t.height)>.5)&&(i={...i,targetRect:e},B())}}).catch(()=>{})}function Qe(e){return new Promise(t=>{Ce.getSize(e,(n,a)=>t({width:n,height:a}),()=>t(null))})}var v={subscribe(e){return De.add(e),e(i),()=>De.delete(e)},getState(){return i},async setTarget(e,t,n){K=e,ve=t;let a=n?.stateNode??e,{rect:r,freshInstance:g}=await qe(a,t);K=g;let w=Oo(K);i={...i,mode:"component",targetTag:w,targetLabel:t,targetRect:r},B()},async setImageUri(e){let t=await Qe(e),n=1;t&&i.targetRect&&t.width>0&&(n=i.targetRect.width/t.width),i={...i,imageUri:e,imageWidth:t?.width??null,imageHeight:t?.height??null,scale:n,showOutline:false},B()},setOpacity(e){i={...i,opacity:Math.max(0,Math.min(1,e))},B()},setScale(e){i={...i,scale:Math.max(.01,Math.min(5,e))},B()},setOffset(e,t){i={...i,offsetX:e,offsetY:t},B()},toggleInvertX(){i={...i,invertX:!i.invertX},B()},toggleInvertY(){i={...i,invertY:!i.invertY},B()},setLocked(e){i={...i,locked:e},B()},setAutoTrack(e){he=e,e?(Ao(),Ho()):Ge()},isAutoTracking(){return he},setShowOutline(e){i={...i,showOutline:e},B()},setEnabled(e){i={...i,enabled:e},B()},toggle(){i={...i,enabled:!i.enabled},B()},fitWidth(){i.imageWidth&&i.targetRect&&i.imageWidth>0&&(i={...i,scale:i.targetRect.width/i.imageWidth},B())},fitHeight(){i.imageHeight&&i.targetRect&&i.imageHeight>0&&(i={...i,scale:i.targetRect.height/i.imageHeight},B())},resetSettings(){if(i={...i,invertX:false,invertY:false},i.mode==="free"){let e=fe.get("window"),t=i.imageWidth??200,n=i.imageHeight??200;i={...i,opacity:.5,freeX:(e.width-t)/2,freeY:(e.height-n)/2,freeWidth:t,freeHeight:n}}else{let e=1;i.imageWidth&&i.targetRect&&i.imageWidth>0&&(e=i.targetRect.width/i.imageWidth),i={...i,opacity:.5,scale:e,offsetX:0,offsetY:0}}B()},async remeasure(){if(!ve)return;let{rect:e,freshInstance:t}=await qe(K,ve);K=t,e&&(i={...i,targetRect:e},B())},async startFreeMode(e){let t=await Qe(e),n=fe.get("window"),a=t?.width??200,r=t?.height??200,g=a,w=r,p=n.width*.8,b=n.height*.6;if(g>p||w>b){let d=Math.min(p/g,b/w);g=Math.round(g*d),w=Math.round(w*d)}i={...i,mode:"free",enabled:true,imageUri:e,imageWidth:t?.width??null,imageHeight:t?.height??null,opacity:.5,freeX:Math.round((n.width-g)/2),freeY:Math.round((n.height-w)/2),freeWidth:Math.round(g),freeHeight:Math.round(w)},B()},setFreePosition(e,t){i={...i,freeX:e,freeY:t},B()},setFreeDimensions(e,t,n,a){i={...i,freeWidth:e,freeHeight:t,freeX:n,freeY:a},B()},reset(){Ge(),he=false,Lo=null,K=null,ve=null,i={...Ke},B()}};import{ChevronRight as Wo,night as _,Hash as Vo,ToolEmptyState as Fo,monoFont as ke}from"@buoy-gg/shared-ui/web";import{jsx as $,jsxs as ye}from"react/jsx-runtime";function Yo({target:e,onSelect:t}){return ye(T,{style:F.card,onPress:t,activeOpacity:.7,testID:`buoy-image-overlay-target-${e.label}`,children:[$(s,{style:F.colorIndicator}),ye(s,{style:F.content,children:[$(s,{style:F.topRow,children:$(y,{style:F.label,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-label`,children:e.label})}),ye(s,{style:F.bottomRow,children:[ye(s,{style:F.badgeRow,children:[ye(s,{style:F.testIdBadge,children:[$(Vo,{size:8,color:_.color.accent}),$(y,{style:F.testIdBadgeText,children:"testID"})]}),$(y,{style:F.testIdValue,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-testid`,children:e.testID})]}),e.componentName&&$(y,{style:F.componentName,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-component`,children:e.componentName})]})]}),$(Wo,{size:16,color:_.color.textTertiary})]})}function Xo({targets:e,onSelect:t}){return e.length===0?$(Fo,{testID:"buoy-image-overlay-empty",otto:"scanning",title:"No targets found",message:`Tag components with
2
- testID="image-target:YourLabel"`}):$(Ye,{style:F.list,contentContainerStyle:F.listContent,children:e.map(n=>$(Yo,{target:n,onSelect:()=>t(n)},n.testID))})}var F=ne.create({list:{flex:1},listContent:{paddingTop:8,paddingBottom:20},card:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,marginHorizontal:12,marginBottom:6,backgroundColor:_.color.surface,borderRadius:8,borderWidth:1,borderColor:_.color.border},colorIndicator:{width:4,height:36,borderRadius:2,marginRight:10,backgroundColor:_.color.accent},content:{flex:1,marginRight:8},topRow:{flexDirection:"row",alignItems:"center",marginBottom:4},label:{fontSize:13,fontWeight:"600",color:_.color.text,flex:1},bottomRow:{gap:2},badgeRow:{flexDirection:"row",alignItems:"center",gap:4},testIdBadge:{flexDirection:"row",alignItems:"center",paddingVertical:2,paddingHorizontal:5,borderRadius:4,backgroundColor:_.color.accentSoft,gap:3},testIdBadgeText:{fontSize:9,fontWeight:"700",color:_.color.accent},testIdValue:{fontSize:11,color:_.color.text,fontFamily:ke,flex:1},componentName:{fontSize:10,color:"#a855f7",fontFamily:ke,marginTop:1},emptyState:{alignItems:"center",paddingVertical:40,paddingHorizontal:32},emptyTitle:{color:_.color.text,fontSize:14,fontWeight:"600",marginBottom:6},emptyText:{color:_.color.textTertiary,fontSize:12,textAlign:"center",lineHeight:18,fontFamily:ke}});import{useRef as J,useCallback as xe}from"react";import{night as q,monoFont as jo}from"@buoy-gg/shared-ui/web";import{jsx as W,jsxs as we}from"react/jsx-runtime";function pe({label:e,testID:t,value:n,min:a,max:r,step:g,displayValue:w,onChange:p}){let b=J(0),d=J(0),c=xe(C=>Math.max(a,Math.min(r,C)),[a,r]),R=r>a?(n-a)/(r-a):0,X=J(p),h=J(c),P=J(a),O=J(r);X.current=p,h.current=c,P.current=a,O.current=r;let z=xe(C=>{let A=C-d.current,H=Math.max(0,Math.min(1,A/b.current)),x=P.current+H*(O.current-P.current);X.current(h.current(x))},[]),j=J(me.create({onStartShouldSetPanResponder:()=>true,onMoveShouldSetPanResponder:()=>true,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:C=>{z(C.nativeEvent.pageX)},onPanResponderMove:C=>{z(C.nativeEvent.pageX)}})).current,Q=xe(C=>{b.current=C.nativeEvent.layout.width},[]),E=J(null),k=xe(()=>{E.current?.measure?.((C,A,H,x,L)=>{d.current=L})},[]);return we(s,{style:Y.controlRow,children:[W(y,{style:Y.label,children:e}),we(s,{style:Y.controlRight,children:[W(T,{style:Y.stepperButton,onPress:()=>p(c(n-g)),testID:`${t}-minus`,activeOpacity:.6,children:W(y,{style:Y.stepperButtonText,children:"-"})}),W(s,{style:Y.sliderHitArea,...j.panHandlers,testID:t,children:we(s,{ref:E,style:Y.sliderTrack,onLayout:C=>{Q(C),k()},pointerEvents:"none",children:[W(s,{style:[Y.sliderFill,{width:`${R*100}%`}]}),W(s,{style:[Y.sliderThumb,{left:`${R*100}%`}]})]})}),W(T,{style:Y.stepperButton,onPress:()=>p(c(n+g)),testID:`${t}-plus`,activeOpacity:.6,children:W(y,{style:Y.stepperButtonText,children:"+"})}),W(y,{style:Y.valueText,testID:`${t}-value`,children:w})]})]})}function Ze({opacity:e,scale:t,offsetX:n,offsetY:a,onOpacityChange:r,onScaleChange:g,onOffsetChange:w,opacityOnly:p}){return p?W(pe,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:r}):we(s,{style:Y.container,children:[W(pe,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:r}),W(pe,{label:"Scale",testID:"buoy-image-overlay-slider-scale",value:t,min:.05,max:3,step:.05,displayValue:`${Math.round(t*100)}%`,onChange:g}),W(pe,{label:"Offset X",testID:"buoy-image-overlay-slider-offset-x",value:n,min:-200,max:200,step:2,displayValue:`${Math.round(n)}px`,onChange:b=>w(Math.round(b),a)}),W(pe,{label:"Offset Y",testID:"buoy-image-overlay-slider-offset-y",value:a,min:-200,max:200,step:2,displayValue:`${Math.round(a)}px`,onChange:b=>w(n,Math.round(b))})]})}var Y=ne.create({container:{gap:8},controlRow:{paddingHorizontal:12,gap:4},label:{fontSize:11,fontWeight:"600",color:q.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},controlRight:{flexDirection:"row",alignItems:"center",gap:6},stepperButton:{zIndex:1,width:28,height:28,borderRadius:6,backgroundColor:q.color.surfaceElevated,borderWidth:1,borderColor:q.color.border,justifyContent:"center",alignItems:"center"},stepperButtonText:{fontSize:16,fontWeight:"700",color:q.color.text,lineHeight:18},sliderHitArea:{flex:1,paddingVertical:20,paddingHorizontal:40,marginVertical:-20,marginHorizontal:-40},sliderTrack:{height:28,justifyContent:"center",borderRadius:6,backgroundColor:q.color.bg,borderWidth:1,borderColor:q.color.border,overflow:"hidden"},sliderFill:{position:"absolute",left:0,top:0,bottom:0,backgroundColor:q.color.accentFill,borderRadius:5},sliderThumb:{position:"absolute",width:4,top:4,bottom:4,marginLeft:-2,borderRadius:2,backgroundColor:q.color.accent},valueText:{fontSize:11,fontWeight:"600",color:q.color.text,width:45,textAlign:"right",fontFamily:jo}});import{Fragment as et,jsx as l,jsxs as f}from"react/jsx-runtime";var Z="";function Le({visible:e,onClose:t,onBack:n,onMinimize:a,enableSharedModalDimensions:r=false,initialModalState:g,minimizeTargetPosition:w,inline:p=false,initialView:b}){let[d,c]=le(()=>{if(b)return b;let u=v.getState();return u.mode==="free"?"free":u.targetRect?"controls":"idle"}),[R,X]=le(()=>b==="targets"?ue():[]),[h,P]=le(()=>v.getState()),[O,z]=le(Z),[j,Q]=le(()=>v.isAutoTracking());Se(()=>{Z=O},[O]),Se(()=>v.subscribe(P),[]),Se(()=>(v.setAutoTrack(j),()=>{}),[j]);let E=oe(()=>{let u=ue();X(u),c("targets")},[]),k=oe(async u=>{await v.setTarget(u.instance,u.label,u.fiber),Z.trim()&&(await v.setImageUri(Z.trim()),v.setEnabled(true)),c("controls")},[]),C=oe(async()=>{let u=Z.trim();u&&(d==="free"?await v.startFreeMode(u):(await v.setImageUri(u),v.setEnabled(true)))},[d]),A=oe(async()=>{let u=null;try{u=pt()}catch{}let I=null;if(!u)try{let S=ft();I=S.default||S}catch{}if(!u&&!I){ce.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(u&&typeof u.hasImageAsync=="function"&&await u.hasImageAsync()){let U=await u.getImageAsync({format:"png"});if(U?.data){d==="free"?await v.startFreeMode(U.data):(await v.setImageUri(U.data),v.setEnabled(true));return}}let S=null;if(u&&typeof u.getStringAsync=="function"?S=await u.getStringAsync():I&&typeof I.getString=="function"&&(S=await I.getString()),S&&(S.startsWith("http")||S.startsWith("data:"))){z(S),Z=S;return}u?ce.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there."):ce.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}catch{ce.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[d]),H=oe(()=>{v.reset(),Z="",c("idle"),z(""),X([])},[]),x=oe(()=>{if(d==="controls"){let u=ue();X(u),c("targets")}else(d==="targets"||d==="free")&&v.reset(),c("idle")},[d]),L=(()=>{switch(d){case"targets":return`Targets (${R.length})`;case"controls":return h.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})(),ee={showToggleButton:false,customContent:f(be,{children:[l(be.Navigation,{onBack:d!=="idle"?x:n}),l(be.Content,{title:L,testID:"buoy-image-overlay-title"}),f(be.Actions,{children:[d==="targets"&&l(T,{style:o.headerTextButton,onPress:E,testID:"buoy-image-overlay-scan",activeOpacity:.7,children:l(y,{style:o.headerTextButtonLabel,children:"Scan"})}),(d==="controls"||d==="free")&&h.imageUri&&l(Io,{isEnabled:h.enabled,onToggle:()=>v.toggle(),accessibilityLabel:"Toggle image overlay",testID:"buoy-image-overlay-power"}),d!=="idle"&&l(T,{style:o.headerActionButton,onPress:H,testID:"buoy-image-overlay-clear",activeOpacity:.7,children:l(vo,{size:14,color:m.color.textSecondary})})]})]})},te=f(s,{style:o.container,children:[d==="idle"&&f(s,{style:o.homeContainer,children:[l(y,{style:o.homeSubtitle,testID:"buoy-image-overlay-home",children:"Choose a mode"}),f(s,{style:o.modeGrid,children:[f(T,{style:o.modePanel,onPress:E,testID:"buoy-image-overlay-mode-component",activeOpacity:.7,children:[l(s,{style:[o.modeIconCircle,{backgroundColor:m.color.accentSoft}],children:l(xo,{size:24,color:m.color.accent})}),f(y,{style:o.modePanelTitle,children:["Component",`
3
- `,"Match"]}),l(y,{style:o.modePanelDesc,children:"Overlay on a tagged component"})]}),f(T,{style:o.modePanel,onPress:()=>c("free"),testID:"buoy-image-overlay-mode-free",activeOpacity:.7,children:[l(s,{style:[o.modeIconCircle,{backgroundColor:m.color.accentSoft}],children:l(wo,{size:24,color:m.color.accent})}),f(y,{style:o.modePanelTitle,children:["Free",`
4
- `,"Placement"]}),l(y,{style:o.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),d==="targets"&&l(Xo,{targets:R,onSelect:k}),d==="controls"&&f(s,{style:o.controlsContainer,children:[h.targetRect&&f(s,{style:o.infoCard,children:[f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Component"}),l(y,{style:o.infoValue,testID:"buoy-image-overlay-info-component",children:h.targetLabel})]}),f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Size"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(h.targetRect.width)," x ",Math.round(h.targetRect.height)]})]}),f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Position"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(h.targetRect.x),", ",Math.round(h.targetRect.y)]})]}),h.imageWidth!=null&&h.imageHeight!=null&&f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Image"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-image",children:[h.imageWidth," x ",h.imageHeight]})]})]}),f(s,{style:o.inputSection,children:[l(y,{style:o.sectionLabel,children:"Image"}),l(T,{style:o.pasteButton,onPress:A,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:l(y,{style:o.pasteButtonText,children:"Paste from Clipboard"})}),f(s,{style:o.urlRow,children:[l(Re,{style:o.urlInput,testID:"buoy-image-overlay-url",value:O,onChangeText:z,placeholder:"or enter URL...",placeholderTextColor:m.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:C}),l(T,{style:[o.loadButton,!O.trim()&&o.loadButtonDisabled],onPress:C,disabled:!O.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:l(y,{style:o.loadButtonText,children:"Load"})})]})]}),f(s,{style:o.toggleSection,children:[l(Be,{label:"Show Outline",testID:"buoy-image-overlay-outline-toggle",value:h.showOutline,onValueChange:u=>v.setShowOutline(u)}),l(Be,{label:"Auto Track",value:j,onValueChange:Q,testID:"buoy-image-overlay-autotrack"}),h.imageUri&&f(et,{children:[f(s,{style:o.blendRow,children:[l(y,{style:o.toggleLabel,children:"Opacity"}),l(s,{style:o.blendButtons,children:[0,25,50,75,100].map(u=>l(T,{testID:`buoy-image-overlay-opacity-${u}`,style:[o.blendButton,Math.round(h.opacity*100)===u&&o.blendButtonActive],onPress:()=>v.setOpacity(u/100),activeOpacity:.7,children:f(y,{style:[o.blendButtonText,Math.round(h.opacity*100)===u&&o.blendButtonTextActive],children:[u,"%"]})},u))})]}),f(s,{style:o.blendRow,children:[l(y,{style:o.toggleLabel,children:"Flip"}),f(s,{style:o.blendButtons,children:[l(T,{style:[o.blendButton,h.invertX&&o.blendButtonActive],onPress:()=>v.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:l(y,{style:[o.blendButtonText,h.invertX&&o.blendButtonTextActive],testID:h.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),l(T,{style:[o.blendButton,h.invertY&&o.blendButtonActive],onPress:()=>v.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:l(y,{style:[o.blendButtonText,h.invertY&&o.blendButtonTextActive],testID:h.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]})]}),h.imageUri&&l(Ze,{opacity:h.opacity,scale:h.scale,offsetX:h.offsetX,offsetY:h.offsetY,onOpacityChange:u=>v.setOpacity(u),onScaleChange:u=>v.setScale(u),onOffsetChange:(u,I)=>v.setOffset(u,I)}),f(s,{style:o.actions,children:[l(T,{style:o.actionButton,onPress:()=>v.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-settings",children:l(y,{style:o.actionButtonText,children:"Reset Settings"})}),l(T,{style:o.actionButton,onPress:()=>v.remeasure(),activeOpacity:.7,testID:"buoy-image-overlay-remeasure",children:l(y,{style:o.actionButtonText,children:"Remeasure"})})]})]}),d==="free"&&f(s,{style:o.controlsContainer,children:[f(s,{style:o.inputSection,children:[l(y,{style:o.sectionLabel,children:"Image"}),l(T,{style:o.pasteButton,onPress:A,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:l(y,{style:o.pasteButtonText,children:"Paste from Clipboard"})}),f(s,{style:o.urlRow,children:[l(Re,{style:o.urlInput,testID:"buoy-image-overlay-url",value:O,onChangeText:z,placeholder:"or enter URL...",placeholderTextColor:m.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:C}),l(T,{style:[o.loadButton,!O.trim()&&o.loadButtonDisabled],onPress:C,disabled:!O.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:l(y,{style:o.loadButtonText,children:"Load"})})]})]}),h.imageUri&&h.mode==="free"&&f(et,{children:[f(s,{style:o.infoCard,children:[f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Position"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(h.freeX),", ",Math.round(h.freeY)]})]}),f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Size"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(h.freeWidth)," x ",Math.round(h.freeHeight)]})]}),h.imageWidth!=null&&h.imageHeight!=null&&f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Original"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-original",children:[h.imageWidth," x ",h.imageHeight]})]})]}),l(s,{style:o.inputSection,children:l(Ze,{opacity:h.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:u=>v.setOpacity(u),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),f(s,{style:o.toggleSection,children:[l(Be,{label:"Lock Position",testID:"buoy-image-overlay-lock",tone:"warning",value:h.locked,onValueChange:u=>v.setLocked(u)}),f(s,{style:o.blendRow,children:[l(y,{style:o.toggleLabel,children:"Opacity"}),l(s,{style:o.blendButtons,children:[0,25,50,75,100].map(u=>l(T,{testID:`buoy-image-overlay-opacity-${u}`,style:[o.blendButton,Math.round(h.opacity*100)===u&&o.blendButtonActive],onPress:()=>v.setOpacity(u/100),activeOpacity:.7,children:f(y,{style:[o.blendButtonText,Math.round(h.opacity*100)===u&&o.blendButtonTextActive],children:[u,"%"]})},u))})]}),f(s,{style:o.blendRow,children:[l(y,{style:o.toggleLabel,children:"Flip"}),f(s,{style:o.blendButtons,children:[l(T,{style:[o.blendButton,h.invertX&&o.blendButtonActive],onPress:()=>v.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:l(y,{style:[o.blendButtonText,h.invertX&&o.blendButtonTextActive],testID:h.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),l(T,{style:[o.blendButton,h.invertY&&o.blendButtonActive],onPress:()=>v.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:l(y,{style:[o.blendButtonText,h.invertY&&o.blendButtonTextActive],testID:h.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]}),l(s,{style:o.actions,children:l(T,{style:o.actionButton,onPress:()=>v.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-position",children:l(y,{style:o.actionButtonText,children:"Reset Position"})})})]})]})]});return p?f(s,{style:o.inlineRoot,children:[l(s,{style:o.inlineHeader,...So,children:ee.customContent}),te]}):l(bo,{visible:e,onClose:t,onMinimize:a,minimizeTargetPosition:w,initialModalState:g,header:ee,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:te})}function No(e={}){return l(Le,{...e,inline:true,visible:true,onClose:()=>{}})}var o=ne.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:Ne.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:Ne.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:m.color.buttonSurface,borderWidth:1,borderColor:m.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:m.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:m.color.buttonSurface,borderWidth:1,borderColor:m.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:m.color.surface,borderRadius:12,borderWidth:1,borderColor:m.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:m.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:m.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:m.color.surface,borderRadius:8,borderWidth:1,borderColor:m.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:m.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:m.color.text,fontFamily:Co},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:m.color.accentSoft,borderWidth:1,borderColor:m.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:m.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:m.color.surfaceElevated,borderWidth:1,borderColor:m.color.border,paddingHorizontal:12,fontSize:13,color:m.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:m.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:m.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:m.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:m.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:m.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:m.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:m.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:m.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:m.color.textTertiary},blendButtonTextActive:{color:m.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:m.color.surfaceElevated,borderWidth:1,borderColor:m.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:m.color.textSecondary}});import{jsx as Uo}from"react/jsx-runtime";var _o="#A855F7",tt=yt({id:"image-overlay",name:"IMG",description:"Design mockup overlay",slot:"both",icon:({size:e})=>Uo(ht,{size:e,color:_o}),component:Le,props:{enableSharedModalDimensions:false}}),$o=gt(tt,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));import{useState as ot,useEffect as Ko,useRef as nt,useMemo as rt,useCallback as qo}from"react";import{absoluteFill as Go,monoFont as Jo}from"@buoy-gg/shared-ui/web";import{Fragment as at,jsx as D,jsxs as Ie}from"react/jsx-runtime";function it({uri:e,style:t,invertX:n,invertY:a}){let r=[];n&&r.push({scaleX:-1}),a&&r.push({scaleY:-1});let g=r.length>0?{transform:r}:{};return D(Ce,{testID:"buoy-internal-image-overlay",source:{uri:e},style:[t,g],pointerEvents:"none"})}var ae=30;function Qo({imageUri:e,x:t,y:n,width:a,height:r,opacity:g,aspectRatio:w,invertX:p,invertY:b,locked:d}){let[c,R]=ot(false),X=nt({x:0,y:0}),h=nt({x:0,y:0,width:0,height:0}),P=fe.get("window"),O=rt(()=>me.create({onStartShouldSetPanResponder:()=>!d,onMoveShouldSetPanResponder:(E,k)=>!d&&(Math.abs(k.dx)>2||Math.abs(k.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let E=v.getState();X.current={x:E.freeX,y:E.freeY},R(true)},onPanResponderMove:(E,k)=>{let C=v.getState(),A=Math.max(0,Math.min(X.current.x+k.dx,P.width-C.freeWidth)),H=Math.max(0,Math.min(X.current.y+k.dy,P.height-C.freeHeight));v.setFreePosition(A,H)},onPanResponderRelease:()=>R(false),onPanResponderTerminate:()=>R(false)}),[P.width,P.height,d]),z=qo(E=>me.create({onStartShouldSetPanResponder:()=>!d,onMoveShouldSetPanResponder:()=>!d,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let k=v.getState();h.current={x:k.freeX,y:k.freeY,width:k.freeWidth,height:k.freeHeight},R(true)},onPanResponderMove:(k,C)=>{let{dx:A,dy:H}=C;if(Math.abs(A)<.5&&Math.abs(H)<.5)return;let x=h.current,L=w>0?w:x.width/x.height,ee=Math.abs(A),te=Math.abs(H),u=ee>=te,I,S,U=x.x,G=x.y;switch(E){case"bottomRight":{I=u?x.width+A:(x.height+H)*L,I=Math.max(ae,Math.min(I,P.width-x.x)),S=I/L;break}case"bottomLeft":{I=u?x.width-A:(x.height+H)*L,I=Math.max(ae,I),S=I/L,U=x.x+x.width-I,U=Math.max(0,U),I=Math.min(I,x.x+x.width),S=I/L;break}case"topRight":{I=u?x.width+A:(x.height-H)*L,I=Math.max(ae,Math.min(I,P.width-x.x)),S=I/L,G=x.y+x.height-S,G=Math.max(0,G),S=Math.min(S,x.y+x.height),I=S*L;break}case"topLeft":{I=u?x.width-A:(x.height-H)*L,I=Math.max(ae,I),S=I/L,U=x.x+x.width-I,G=x.y+x.height-S,U=Math.max(0,U),G=Math.max(0,G),I=Math.min(I,x.x+x.width),S=I/L,G=x.y+x.height-S;break}}I=Math.max(ae,Math.round(I)),S=Math.max(ae,Math.round(S)),v.setFreeDimensions(I,S,Math.round(U),Math.round(G))},onPanResponderRelease:()=>R(false),onPanResponderTerminate:()=>R(false)}),[P.width,P.height,w,d]),j=rt(()=>({topLeft:z("topLeft"),topRight:z("topRight"),bottomLeft:z("bottomLeft"),bottomRight:z("bottomRight")}),[z]),Q={...Go,opacity:g};return Ie(s,{testID:"buoy-image-overlay-free-box",style:{position:"absolute",left:t,top:n,width:a,height:r},pointerEvents:d?"none":"auto",children:[D(s,{style:ne.absoluteFill,...d?{}:O.panHandlers,children:D(it,{uri:e,style:Q,invertX:p,invertY:b})}),D(s,{pointerEvents:"none",style:[M.freeBorder,c&&M.freeBorderActive,d&&M.freeBorderLocked]}),!d&&Ie(at,{children:[D(s,{...j.topLeft.panHandlers,style:[M.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(s,{style:[M.cornerHandle,c&&M.cornerHandleActive]})}),D(s,{...j.topRight.panHandlers,style:[M.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(s,{style:[M.cornerHandle,c&&M.cornerHandleActive]})}),D(s,{...j.bottomLeft.panHandlers,style:[M.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(s,{style:[M.cornerHandle,c&&M.cornerHandleActive]})}),D(s,{...j.bottomRight.panHandlers,style:[M.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(s,{style:[M.cornerHandle,c&&M.cornerHandleActive]})})]})]})}function Zo(){let[e,t]=ot(()=>v.getState());Ko(()=>v.subscribe(t),[]);let{mode:n,enabled:a,imageUri:r,imageWidth:g,imageHeight:w,targetRect:p,targetLabel:b,showOutline:d,opacity:c,scale:R,offsetX:X,offsetY:h,invertX:P,invertY:O,locked:z,freeX:j,freeY:Q,freeWidth:E,freeHeight:k}=e,C=g&&w&&w>0?g/w:0;if(n==="free"&&a&&r)return D(s,{style:M.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:D(Qo,{imageUri:r,x:j,y:Q,width:E,height:k,opacity:c,aspectRatio:C,invertX:P,invertY:O,locked:z})});if(!p)return null;let A=a&&r;return Ie(s,{style:M.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[d&&Ie(at,{children:[D(s,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",testID:"buoy-image-overlay-outline",style:[M.highlight,{left:p.x-3,top:p.y-3,width:p.width+6,height:p.height+6}]}),b&&D(s,{pointerEvents:"none",style:[M.label,{left:p.x,top:p.y-20}],children:D(y,{style:M.labelText,testID:"buoy-image-overlay-outline-label",children:b})})]}),A&&(()=>{let H=(g??p.width)*R,x=(w??p.height)*R,L=p.x+p.width/2,ee=p.y+p.height/2,te={position:"absolute",left:L-H/2+X,top:ee-x/2+h,width:H,height:x,opacity:c};return D(it,{uri:r,style:te,invertX:P,invertY:O})})()]})}var M=ne.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:ze.OS==="web"?999:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:Jo},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});export{v as ImageOverlayController,Le as ImageOverlayModal,Zo as ImageOverlayStandalone,No as ImageOverlayToolView,$o as createImageOverlayTool,tt as imageOverlayToolPreset,ue as scanForImageTargets,To as setDevToolsHookOverride};
1
+ "use client";var ze=Object.defineProperty;var ut=Object.getOwnPropertyDescriptor;var ht=Object.getOwnPropertyNames;var gt=Object.prototype.hasOwnProperty;var yt=(e,t)=>{for(var n in t)ze(e,n,{get:t[n],enumerable:true})},He=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ht(t))!gt.call(e,a)&&a!==n&&ze(e,a,{get:()=>t[a],enumerable:!(r=ut(t,a))||r.enumerable});return e},ft=(e,t,n)=>(He(e,t,"default"),n&&He(n,t,"default"));var ln=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{ImageOverlayIcon as pt,createToolFactory as mt,defineToolPreset as bt}from"@buoy-gg/shared-ui/web";var se;function vt(){return typeof navigator>"u"||!navigator.clipboard?null:{async hasImageAsync(){if(se=void 0,!navigator.clipboard.read)return false;let e=await navigator.clipboard.read();for(let t of e){let n=t.types.find(r=>r.startsWith("image/"));if(n)return se=await t.getType(n),true}return false},async getImageAsync(){if(!se)return null;let e=se;return se=void 0,{data:await new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result)),r.onerror=n,r.readAsDataURL(e)})}},getStringAsync:()=>navigator.clipboard.readText()}}function xt(){return null}import{useState as ce,useEffect as Te,useCallback as oe}from"react";var We={};yt(We,{AccessibilityInfo:()=>Ct,ActivityIndicator:()=>So,Alert:()=>ue,Animated:()=>po,AppRegistry:()=>Rt,AppState:()=>Mt,Appearance:()=>Tt,BackHandler:()=>Bt,Button:()=>Io,CheckBox:()=>Ft,Clipboard:()=>Dt,DeviceEventEmitter:()=>to,Dimensions:()=>be,Easing:()=>Pt,FlatList:()=>Yt,I18nManager:()=>Ot,Image:()=>Re,ImageBackground:()=>Xt,InteractionManager:()=>At,Keyboard:()=>kt,KeyboardAvoidingView:()=>$t,LayoutAnimation:()=>Lt,Linking:()=>Et,LogBox:()=>eo,Modal:()=>xo,NativeEventEmitter:()=>zt,NativeModules:()=>It,PanResponder:()=>ve,Picker:()=>jt,PixelRatio:()=>Ht,Platform:()=>Ve,Pressable:()=>vo,ProgressBar:()=>Nt,RefreshControl:()=>_t,SafeAreaView:()=>Ut,ScrollView:()=>Ne,SectionList:()=>Kt,Share:()=>Wt,StatusBar:()=>qt,StyleSheet:()=>re,Switch:()=>wo,Text:()=>f,TextInput:()=>De,Touchable:()=>Gt,TouchableHighlight:()=>mo,TouchableNativeFeedback:()=>Jt,TouchableOpacity:()=>R,TouchableWithoutFeedback:()=>bo,UIManager:()=>Fe,Vibration:()=>Vt,View:()=>c,VirtualizedList:()=>Qt,YellowBox:()=>Zt,findNodeHandle:()=>Ue,unstable_createElement:()=>St,useColorScheme:()=>oo,useLocaleContext:()=>no,useWindowDimensions:()=>ao});ft(We,wt);import*as wt from"react-native-web";import{unstable_createElement as St,NativeModules as It,AccessibilityInfo as Ct,Appearance as Tt,AppRegistry as Rt,AppState as Mt,BackHandler as Bt,Clipboard as Dt,Dimensions as be,Easing as Pt,I18nManager as Ot,Keyboard as kt,InteractionManager as At,LayoutAnimation as Lt,Linking as Et,NativeEventEmitter as zt,PanResponder as ve,PixelRatio as Ht,Platform as Ve,Share as Wt,UIManager as Fe,Vibration as Vt,CheckBox as Ft,FlatList as Yt,Image as Re,ImageBackground as Xt,KeyboardAvoidingView as $t,Picker as jt,ProgressBar as Nt,RefreshControl as _t,SafeAreaView as Ut,SectionList as Kt,StatusBar as qt,Touchable as Gt,TouchableNativeFeedback as Jt,VirtualizedList as Qt,YellowBox as Zt,LogBox as eo,DeviceEventEmitter as to,useColorScheme as oo,useLocaleContext as no,useWindowDimensions as ao}from"react-native-web";import*as V from"react-native-web";import{createElement as Me,forwardRef as Ye,useCallback as ro,useRef as io}from"react";import{useEffect as lo,useState as so}from"react";import{createPortal as co}from"react-dom";var uo='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as ho}from"react/jsx-runtime";var de=Symbol.for("@buoy-gg/portal-host"),Xe=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function $e(){let e=document;if(e[de])return e[de].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:uo});let n=()=>{let i=document.fullscreenElement,I=i&&i.tagName!=="CANVAS"?i:document.body;t.parentElement!==I&&I.appendChild(t)},r=new Map,a=i=>{(!t.contains(i.target)||!Xe(i.target))&&r.set(i.code||i.key,{key:i.key,code:i.code,location:i.location,keyCode:i.keyCode,which:i.which,altKey:i.altKey,ctrlKey:i.ctrlKey,metaKey:i.metaKey,shiftKey:i.shiftKey})},g=i=>{r.delete(i.code||i.key)},x=()=>r.clear(),p=()=>{let i=[...r.values()];r.clear();for(let I of i)document.dispatchEvent(new KeyboardEvent("keyup",{...I,bubbles:true}))},y=i=>{Xe(i.target)&&i.stopPropagation()},d=i=>i.stopPropagation();return n(),document.addEventListener("fullscreenchange",n),document.addEventListener("keydown",a,true),document.addEventListener("keyup",g,true),window.addEventListener("blur",x),t.addEventListener("focusin",p),t.addEventListener("keydown",y),t.addEventListener("keyup",y),t.addEventListener("keypress",y),t.addEventListener("wheel",d,{passive:true}),e[de]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",n),document.removeEventListener("keydown",a,true),document.removeEventListener("keyup",g,true),window.removeEventListener("blur",x),t.remove(),delete e[de]}},t}function go({children:e}){let[t,n]=so(null);return lo(()=>{let r=$e(),a=document[de];return a.users++,n(r),()=>{--a.users===0&&a.dispose()}},[]),t?co(ho("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}var ne=V,yo=["shadowColor","shadowOffset","shadowOpacity","shadowRadius","textShadowColor","textShadowOffset","textShadowRadius"],ae=e=>typeof e=="number"?`${e}px`:e;function Be(e){if(Array.isArray(e)){let I=e.map(Be);return I.some((A,u)=>A!==e[u])?I:e}if(!e||typeof e!="object"||!yo.some(I=>e[I]!=null))return e;let{shadowColor:t,shadowOffset:n,shadowOpacity:r,shadowRadius:a,textShadowColor:g,textShadowOffset:x,textShadowRadius:p,...y}=e;if(t!=null||n!=null||r!=null||a!=null){let I=t??"black",A=r==null?I:`color-mix(in srgb, ${I} ${Math.min(r,1)*100}%, transparent)`,u=`${ae(n?.width??0)} ${ae(n?.height??0)} ${ae(a??0)} ${A}`;y.boxShadow=typeof y.boxShadow=="string"?`${y.boxShadow}, ${u}`:y.boxShadow??u}let{width:d=0,height:i=0}=x??{};if(g&&(d||i||p)){let I=`${ae(d)} ${ae(i)} ${ae(p??0)} ${g}`;y.textShadow=y.textShadow?`${y.textShadow}, ${I}`:I}return y}var fo=ne.StyleSheet.create({auto:{pointerEvents:"auto"},none:{pointerEvents:"none"},"box-none":{pointerEvents:"box-none"},"box-only":{pointerEvents:"box-only"}});function je(e,t){if(typeof e=="function")return r=>je(e(r),t);let n=Be(e);return t?[n,fo[t]]:n}var re={...ne.StyleSheet,create:e=>ne.StyleSheet.create(Object.fromEntries(Object.entries(e).map(([t,n])=>[t,Be(n)])))};function j(e){let t=Ye((r,a)=>{let{accessibilityState:g,accessibilityValue:x,pointerEvents:p,...y}=r;for(let i of["busy","checked","disabled","expanded","selected"])g?.[i]!==void 0&&y[`aria-${i}`]===void 0&&(y[`aria-${i}`]=g[i]);for(let[i,I]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))x?.[i]!==void 0&&y[`aria-${I}`]===void 0&&(y[`aria-${I}`]=x[i]);let d=je(y.style,p);return d!==y.style&&(y.style=d),Me(e,{...y,ref:a})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var c=j(V.View),f=j(V.Text),po={...ne.Animated,View:ne.Animated.createAnimatedComponent(c),Text:ne.Animated.createAnimatedComponent(f)},De=j(V.TextInput),R=j(V.TouchableOpacity),mo=j(V.TouchableHighlight),bo=j(V.TouchableWithoutFeedback),vo=j(V.Pressable),Ne=j(V.ScrollView),_e=Ye((e,t)=>{let n=io(null),r=ro(a=>{if(a){let g=a;for(;g.parentElement&&g.parentElement!==document.body;)g=g.parentElement;g.parentElement===document.body&&(n.current=g,Object.assign(g.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),$e().appendChild(g))}else n.current&&(document.body.appendChild(n.current),n.current=null);typeof t=="function"?t(a):t&&(t.current=a)},[t]);return Me(go,null,Me(V.Modal,{...e,ref:r}))});_e.displayName="Modal";var xo=j(_e),wo=j(V.Switch),So=j(V.ActivityIndicator),Io=j(V.Button),Ue=V.findNodeHandle,ue={alert(e,t,n,r){if(typeof document>"u")return;let a=document.createElement("dialog");a.dataset.buoyRoot="",a.setAttribute("aria-label",e),a.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let g=document.createElement("h2");if(g.textContent=e,g.style.cssText="font-size:18px;margin:0 0 12px",a.appendChild(g),t){let d=document.createElement("p");d.textContent=t,d.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",a.appendChild(d)}let x=document.createElement("div");x.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let p=n?.length?n:[{text:"OK"}],y=()=>{a.close?.(),a.remove()};for(let d of p){let i=document.createElement("button");i.type="button",i.textContent=d.text??"OK",i.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${d.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,i.onclick=()=>{y(),d.onPress?.()},x.appendChild(i)}a.addEventListener("cancel",d=>{d.preventDefault(),r?.cancelable!==false&&(y(),r?.onDismiss?.())}),a.appendChild(x),document.body.appendChild(a),a.showModal?a.showModal():a.setAttribute("open","")}};import{JsModal as Co,ModalHeader as xe,macOSColors as Ke,night as b,Trash2 as To,SquareDashed as Ro,Image as Mo,PowerToggleButton as Bo,windowDragProps as Do,ToggleRow as Pe,monoFont as Po}from"@buoy-gg/shared-ui/web";function Oe(e){return new Promise(t=>{try{let n=[];e&&n.push(e),e?.canonical?.publicInstance&&n.push(e.canonical.publicInstance),e?.canonical&&e.canonical!==e&&n.push(e.canonical);for(let r of n)if(typeof r.getBoundingClientRect=="function")try{let a=r.getBoundingClientRect();if(a&&typeof a.x=="number"&&typeof a.y=="number"&&typeof a.width=="number"&&typeof a.height=="number"&&a.width>0&&a.height>0){t({x:a.x,y:a.y,width:a.width,height:a.height});return}}catch{}for(let r of n)if(typeof r.measure=="function"){let a=setTimeout(()=>t(null),200);r.measure((g,x,p,y,d,i)=>{clearTimeout(a),d!=null&&i!=null&&p!=null&&y!=null&&p>0&&y>0?t({x:d,y:i,width:p,height:y}):t(null)});return}try{let r=Ue(e);if(r!=null){let a=setTimeout(()=>t(null),200);Fe.measure(r,(g,x,p,y,d,i)=>{clearTimeout(a),d!=null&&i!=null&&p!=null&&y!=null&&p>0&&y>0?t({x:d,y:i,width:p,height:y}):t(null)});return}}catch{}t(null)}catch{t(null)}})}var qe=null;function Oo(e){qe=e??null}function Ge(){return qe||(typeof globalThis>"u"?null:globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__??null)}var Je="image-target:",ko=5,Ao=22;function Lo(){let e=Ge();if(!e?.getFiberRoots)return[];let t=new Set,n=e.renderers?.keys?Array.from(e.renderers.keys()):[1];for(let r of n)try{e.getFiberRoots(r)?.forEach(a=>t.add(a))}catch{}return[...t]}function Eo(e){return e.tag===Ao&&e.memoizedState!==null}function zo(e){return e.memoizedProps?.activityState===0}function he(e,t,n=0,r=new Set){if(!(!e||r.has(e)||n>500)){if(r.add(e),Eo(e)){e.sibling&&he(e.sibling,t,n,r);return}if(zo(e)){e.sibling&&he(e.sibling,t,n,r);return}t(e,n),e.child&&he(e.child,t,n+1,r),e.sibling&&he(e.sibling,t,n,r)}}function Ho(e){let t=new Set(["View","RCTView","Text","RCTText","Image","RCTImageView","ScrollView","RCTScrollView","TextInput","RCTTextInput","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","Pressable","FlatList","SectionList","SafeAreaView"]),n=e._debugOwner||e.return,r=0;for(;n&&r<30;){r++;let a=n.type;if(a){let g=typeof a=="string"?a:a.displayName||a.name;if(g&&!t.has(g))return g}n=n.return}return null}function ge(){let e=Lo();if(e.length===0)return[];let t=[];for(let n of e)he(n.current,r=>{if(r.tag!==ko)return;let a=r.memoizedProps?.testID??r.pendingProps?.testID??r.memoizedProps?.["data-testid"]??r.pendingProps?.["data-testid"];if(!a||!a.startsWith(Je))return;let g=a.slice(Je.length);g&&t.push({label:g,testID:a,fiber:r,instance:r.stateNode,componentName:Ho(r)})});return t}var Qe={mode:null,enabled:false,imageUri:null,imageWidth:null,imageHeight:null,targetTag:null,targetLabel:null,targetRect:null,showOutline:true,opacity:.5,scale:1,offsetX:0,offsetY:0,invertX:false,invertY:false,locked:false,freeX:0,freeY:0,freeWidth:200,freeHeight:200},l={...Qe},ke=new Set,K=null,we=null,ye=false,fe=null,Wo=null;function M(){for(let e of ke)e(l)}function Vo(e){return e?typeof e._nativeTag=="number"?e._nativeTag:typeof e.canonical?._nativeTag=="number"?e.canonical._nativeTag:typeof e.__nativeTag=="number"?e.__nativeTag:null:null}async function Ze(e,t){let n=await Oe(e);if(n)return{rect:n,freshInstance:e};let r=ge().find(a=>a.label===t);return r&&(n=await Oe(r.instance),n)?{rect:n,freshInstance:r.instance}:{rect:null,freshInstance:e}}function Fo(){if(fe)return;let e=Ge();if(e){if(e.rendererInterfaces)for(let[,t]of e.rendererInterfaces)typeof t.setTraceUpdatesEnabled=="function"&&t.setTraceUpdatesEnabled(true);typeof e.sub=="function"&&(fe=e.sub("traceUpdates",$o))}}var ie=null,Ae=false;function Yo(){if(ie!==null||typeof requestAnimationFrame!="function")return;let e=()=>{ie=requestAnimationFrame(e),!(Ae||!ye||!K)&&(Ae=true,tt().finally(()=>{Ae=false}))};ie=requestAnimationFrame(e)}function Xo(){ie!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(ie),ie=null}function et(){Xo(),fe&&(fe(),fe=null)}function $o(e){!ye||!K||tt()}function tt(){return Oe(K).then(e=>{if(e&&l.targetRect){let t=l.targetRect;(Math.abs(e.x-t.x)>.5||Math.abs(e.y-t.y)>.5||Math.abs(e.width-t.width)>.5||Math.abs(e.height-t.height)>.5)&&(l={...l,targetRect:e},M())}}).catch(()=>{})}function ot(e){return new Promise(t=>{Re.getSize(e,(n,r)=>t({width:n,height:r}),()=>t(null))})}var v={subscribe(e){return ke.add(e),e(l),()=>ke.delete(e)},getState(){return l},async setTarget(e,t,n){K=e,we=t;let r=n?.stateNode??e,{rect:a,freshInstance:g}=await Ze(r,t);K=g;let x=Vo(K);l={...l,mode:"component",targetTag:x,targetLabel:t,targetRect:a},M()},async setImageUri(e){let t=await ot(e),n=1;t&&l.targetRect&&t.width>0&&(n=l.targetRect.width/t.width),l={...l,imageUri:e,imageWidth:t?.width??null,imageHeight:t?.height??null,scale:n,showOutline:false},M()},setOpacity(e){l={...l,opacity:Math.max(0,Math.min(1,e))},M()},setScale(e){l={...l,scale:Math.max(.01,Math.min(5,e))},M()},setOffset(e,t){l={...l,offsetX:e,offsetY:t},M()},toggleInvertX(){l={...l,invertX:!l.invertX},M()},toggleInvertY(){l={...l,invertY:!l.invertY},M()},setLocked(e){l={...l,locked:e},M()},setAutoTrack(e){ye=e,e?(Fo(),Yo()):et()},isAutoTracking(){return ye},setShowOutline(e){l={...l,showOutline:e},M()},setEnabled(e){l={...l,enabled:e},M()},toggle(){l={...l,enabled:!l.enabled},M()},fitWidth(){l.imageWidth&&l.targetRect&&l.imageWidth>0&&(l={...l,scale:l.targetRect.width/l.imageWidth},M())},fitHeight(){l.imageHeight&&l.targetRect&&l.imageHeight>0&&(l={...l,scale:l.targetRect.height/l.imageHeight},M())},resetSettings(){if(l={...l,invertX:false,invertY:false},l.mode==="free"){let e=be.get("window"),t=l.imageWidth??200,n=l.imageHeight??200;l={...l,opacity:.5,freeX:(e.width-t)/2,freeY:(e.height-n)/2,freeWidth:t,freeHeight:n}}else{let e=1;l.imageWidth&&l.targetRect&&l.imageWidth>0&&(e=l.targetRect.width/l.imageWidth),l={...l,opacity:.5,scale:e,offsetX:0,offsetY:0}}M()},async remeasure(){if(!we)return;let{rect:e,freshInstance:t}=await Ze(K,we);K=t,e&&(l={...l,targetRect:e},M())},async startFreeMode(e){let t=await ot(e),n=be.get("window"),r=t?.width??200,a=t?.height??200,g=r,x=a,p=n.width*.8,y=n.height*.6;if(g>p||x>y){let d=Math.min(p/g,y/x);g=Math.round(g*d),x=Math.round(x*d)}l={...l,mode:"free",enabled:true,imageUri:e,imageWidth:t?.width??null,imageHeight:t?.height??null,opacity:.5,freeX:Math.round((n.width-g)/2),freeY:Math.round((n.height-x)/2),freeWidth:Math.round(g),freeHeight:Math.round(x)},M()},setFreePosition(e,t){l={...l,freeX:e,freeY:t},M()},setFreeDimensions(e,t,n,r){l={...l,freeWidth:e,freeHeight:t,freeX:n,freeY:r},M()},reset(){et(),ye=false,Wo=null,K=null,we=null,l={...Qe},M()}};import{ChevronRight as jo,night as _,Hash as No,ToolEmptyState as _o,monoFont as Le}from"@buoy-gg/shared-ui/web";import{jsx as U,jsxs as pe}from"react/jsx-runtime";function Uo({target:e,onSelect:t}){return pe(R,{style:Y.card,onPress:t,activeOpacity:.7,testID:`buoy-image-overlay-target-${e.label}`,children:[U(c,{style:Y.colorIndicator}),pe(c,{style:Y.content,children:[U(c,{style:Y.topRow,children:U(f,{style:Y.label,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-label`,children:e.label})}),pe(c,{style:Y.bottomRow,children:[pe(c,{style:Y.badgeRow,children:[pe(c,{style:Y.testIdBadge,children:[U(No,{size:8,color:_.color.accent}),U(f,{style:Y.testIdBadgeText,children:"testID"})]}),U(f,{style:Y.testIdValue,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-testid`,children:e.testID})]}),e.componentName&&U(f,{style:Y.componentName,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-component`,children:e.componentName})]})]}),U(jo,{size:16,color:_.color.textTertiary})]})}function Ko({targets:e,onSelect:t}){return e.length===0?U(_o,{testID:"buoy-image-overlay-empty",otto:"scanning",title:"No targets found",message:`Tag components with
2
+ testID="image-target:YourLabel"`}):U(Ne,{style:Y.list,contentContainerStyle:Y.listContent,children:e.map(n=>U(Uo,{target:n,onSelect:()=>t(n)},n.testID))})}var Y=re.create({list:{flex:1},listContent:{paddingTop:8,paddingBottom:20},card:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,marginHorizontal:12,marginBottom:6,backgroundColor:_.color.surface,borderRadius:8,borderWidth:1,borderColor:_.color.border},colorIndicator:{width:4,height:36,borderRadius:2,marginRight:10,backgroundColor:_.color.accent},content:{flex:1,marginRight:8},topRow:{flexDirection:"row",alignItems:"center",marginBottom:4},label:{fontSize:13,fontWeight:"600",color:_.color.text,flex:1},bottomRow:{gap:2},badgeRow:{flexDirection:"row",alignItems:"center",gap:4},testIdBadge:{flexDirection:"row",alignItems:"center",paddingVertical:2,paddingHorizontal:5,borderRadius:4,backgroundColor:_.color.accentSoft,gap:3},testIdBadgeText:{fontSize:9,fontWeight:"700",color:_.color.accent},testIdValue:{fontSize:11,color:_.color.text,fontFamily:Le,flex:1},componentName:{fontSize:10,color:"#a855f7",fontFamily:Le,marginTop:1},emptyState:{alignItems:"center",paddingVertical:40,paddingHorizontal:32},emptyTitle:{color:_.color.text,fontSize:14,fontWeight:"600",marginBottom:6},emptyText:{color:_.color.textTertiary,fontSize:12,textAlign:"center",lineHeight:18,fontFamily:Le}});import{useRef as J,useCallback as Se}from"react";import{night as q,monoFont as qo}from"@buoy-gg/shared-ui/web";import{jsx as F,jsxs as Ie}from"react/jsx-runtime";function me({label:e,testID:t,value:n,min:r,max:a,step:g,displayValue:x,onChange:p}){let y=J(0),d=J(0),i=Se(T=>Math.max(r,Math.min(a,T)),[r,a]),I=a>r?(n-r)/(a-r):0,A=J(p),u=J(i),P=J(r),L=J(a);A.current=p,u.current=i,P.current=r,L.current=a;let H=Se(T=>{let E=T-d.current,z=Math.max(0,Math.min(1,E/y.current)),w=P.current+z*(L.current-P.current);A.current(u.current(w))},[]),$=J(ve.create({onStartShouldSetPanResponder:()=>true,onMoveShouldSetPanResponder:()=>true,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:T=>{H(T.nativeEvent.pageX)},onPanResponderMove:T=>{H(T.nativeEvent.pageX)}})).current,Q=Se(T=>{y.current=T.nativeEvent.layout.width},[]),W=J(null),O=Se(()=>{W.current?.measure?.((T,E,z,w,k)=>{d.current=k})},[]);return Ie(c,{style:X.controlRow,children:[F(f,{style:X.label,children:e}),Ie(c,{style:X.controlRight,children:[F(R,{style:X.stepperButton,onPress:()=>p(i(n-g)),testID:`${t}-minus`,activeOpacity:.6,children:F(f,{style:X.stepperButtonText,children:"-"})}),F(c,{style:X.sliderHitArea,...$.panHandlers,testID:t,children:Ie(c,{ref:W,style:X.sliderTrack,onLayout:T=>{Q(T),O()},pointerEvents:"none",children:[F(c,{style:[X.sliderFill,{width:`${I*100}%`}]}),F(c,{style:[X.sliderThumb,{left:`${I*100}%`}]})]})}),F(R,{style:X.stepperButton,onPress:()=>p(i(n+g)),testID:`${t}-plus`,activeOpacity:.6,children:F(f,{style:X.stepperButtonText,children:"+"})}),F(f,{style:X.valueText,testID:`${t}-value`,children:x})]})]})}function nt({opacity:e,scale:t,offsetX:n,offsetY:r,onOpacityChange:a,onScaleChange:g,onOffsetChange:x,opacityOnly:p}){return p?F(me,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:a}):Ie(c,{style:X.container,children:[F(me,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:a}),F(me,{label:"Scale",testID:"buoy-image-overlay-slider-scale",value:t,min:.05,max:3,step:.05,displayValue:`${Math.round(t*100)}%`,onChange:g}),F(me,{label:"Offset X",testID:"buoy-image-overlay-slider-offset-x",value:n,min:-200,max:200,step:2,displayValue:`${Math.round(n)}px`,onChange:y=>x(Math.round(y),r)}),F(me,{label:"Offset Y",testID:"buoy-image-overlay-slider-offset-y",value:r,min:-200,max:200,step:2,displayValue:`${Math.round(r)}px`,onChange:y=>x(n,Math.round(y))})]})}var X=re.create({container:{gap:8},controlRow:{paddingHorizontal:12,gap:4},label:{fontSize:11,fontWeight:"600",color:q.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},controlRight:{flexDirection:"row",alignItems:"center",gap:6},stepperButton:{zIndex:1,width:28,height:28,borderRadius:6,backgroundColor:q.color.surfaceElevated,borderWidth:1,borderColor:q.color.border,justifyContent:"center",alignItems:"center"},stepperButtonText:{fontSize:16,fontWeight:"700",color:q.color.text,lineHeight:18},sliderHitArea:{flex:1,paddingVertical:20,paddingHorizontal:40,marginVertical:-20,marginHorizontal:-40},sliderTrack:{height:28,justifyContent:"center",borderRadius:6,backgroundColor:q.color.bg,borderWidth:1,borderColor:q.color.border,overflow:"hidden"},sliderFill:{position:"absolute",left:0,top:0,bottom:0,backgroundColor:q.color.accentFill,borderRadius:5},sliderThumb:{position:"absolute",width:4,top:4,bottom:4,marginLeft:-2,borderRadius:2,backgroundColor:q.color.accent},valueText:{fontSize:11,fontWeight:"600",color:q.color.text,width:45,textAlign:"right",fontFamily:qo}});import{Fragment as at,jsx as s,jsxs as m}from"react/jsx-runtime";var Z="";function Ee({visible:e,onClose:t,onBack:n,onMinimize:r,enableSharedModalDimensions:a=false,initialModalState:g,minimizeTargetPosition:x,inline:p=false,initialView:y}){let[d,i]=ce(()=>{if(y)return y;let h=v.getState();return h.mode==="free"?"free":h.targetRect?"controls":"idle"}),[I,A]=ce(()=>y==="targets"?ge():[]),[u,P]=ce(()=>v.getState()),[L,H]=ce(Z),[$,Q]=ce(()=>v.isAutoTracking());Te(()=>{Z=L},[L]),Te(()=>v.subscribe(P),[]),Te(()=>(v.setAutoTrack($),()=>{}),[$]);let W=oe(()=>{let h=ge();A(h),i("targets")},[]),O=oe(async h=>{await v.setTarget(h.instance,h.label,h.fiber),Z.trim()&&(await v.setImageUri(Z.trim()),v.setEnabled(true)),i("controls")},[]),T=oe(async()=>{let h=Z.trim();h&&(d==="free"?await v.startFreeMode(h):(await v.setImageUri(h),v.setEnabled(true)))},[d]),E=oe(async()=>{let h=null;try{h=vt()}catch{}let S=null;if(!h)try{let C=xt();S=C.default||C}catch{}if(!h&&!S){ue.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(h&&typeof h.hasImageAsync=="function"&&await h.hasImageAsync()){let N=await h.getImageAsync({format:"png"});if(N?.data){d==="free"?await v.startFreeMode(N.data):(await v.setImageUri(N.data),v.setEnabled(true));return}}let C=null;if(h&&typeof h.getStringAsync=="function"?C=await h.getStringAsync():S&&typeof S.getString=="function"&&(C=await S.getString()),C&&(C.startsWith("http")||C.startsWith("data:"))){H(C),Z=C;return}h?ue.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there."):ue.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}catch{ue.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[d]),z=oe(()=>{v.reset(),Z="",i("idle"),H(""),A([])},[]),w=oe(()=>{if(d==="controls"){let h=ge();A(h),i("targets")}else(d==="targets"||d==="free")&&v.reset(),i("idle")},[d]),k=(()=>{switch(d){case"targets":return`Targets (${I.length})`;case"controls":return u.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})(),ee={showToggleButton:false,customContent:m(xe,{children:[s(xe.Navigation,{onBack:d!=="idle"?w:n}),s(xe.Content,{title:k,testID:"buoy-image-overlay-title"}),m(xe.Actions,{children:[d==="targets"&&s(R,{style:o.headerTextButton,onPress:W,testID:"buoy-image-overlay-scan",activeOpacity:.7,children:s(f,{style:o.headerTextButtonLabel,children:"Scan"})}),(d==="controls"||d==="free")&&u.imageUri&&s(Bo,{isEnabled:u.enabled,onToggle:()=>v.toggle(),accessibilityLabel:"Toggle image overlay",testID:"buoy-image-overlay-power"}),d!=="idle"&&s(R,{style:o.headerActionButton,onPress:z,testID:"buoy-image-overlay-clear",activeOpacity:.7,children:s(To,{size:14,color:b.color.textSecondary})})]})]})},te=m(c,{style:o.container,children:[d==="idle"&&m(c,{style:o.homeContainer,children:[s(f,{style:o.homeSubtitle,testID:"buoy-image-overlay-home",children:"Choose a mode"}),m(c,{style:o.modeGrid,children:[m(R,{style:o.modePanel,onPress:W,testID:"buoy-image-overlay-mode-component",activeOpacity:.7,accessibilityRole:"button",accessibilityLabel:"Component Match. Overlay on a tagged component",children:[s(c,{style:[o.modeIconCircle,{backgroundColor:b.color.accentSoft}],children:s(Ro,{size:24,color:b.color.accent})}),m(f,{style:o.modePanelTitle,children:["Component",`
3
+ `,"Match"]}),s(f,{style:o.modePanelDesc,children:"Overlay on a tagged component"})]}),m(R,{style:o.modePanel,onPress:()=>i("free"),testID:"buoy-image-overlay-mode-free",activeOpacity:.7,accessibilityRole:"button",accessibilityLabel:"Free Placement. Drag and resize anywhere",children:[s(c,{style:[o.modeIconCircle,{backgroundColor:b.color.accentSoft}],children:s(Mo,{size:24,color:b.color.accent})}),m(f,{style:o.modePanelTitle,children:["Free",`
4
+ `,"Placement"]}),s(f,{style:o.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),d==="targets"&&s(Ko,{targets:I,onSelect:O}),d==="controls"&&m(c,{style:o.controlsContainer,children:[u.targetRect&&m(c,{style:o.infoCard,children:[m(c,{style:o.infoRow,children:[s(f,{style:o.infoLabel,children:"Component"}),s(f,{style:o.infoValue,testID:"buoy-image-overlay-info-component",children:u.targetLabel})]}),m(c,{style:o.infoRow,children:[s(f,{style:o.infoLabel,children:"Size"}),m(f,{style:o.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(u.targetRect.width)," x ",Math.round(u.targetRect.height)]})]}),m(c,{style:o.infoRow,children:[s(f,{style:o.infoLabel,children:"Position"}),m(f,{style:o.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(u.targetRect.x),", ",Math.round(u.targetRect.y)]})]}),u.imageWidth!=null&&u.imageHeight!=null&&m(c,{style:o.infoRow,children:[s(f,{style:o.infoLabel,children:"Image"}),m(f,{style:o.infoValueMono,testID:"buoy-image-overlay-info-image",children:[u.imageWidth," x ",u.imageHeight]})]})]}),m(c,{style:o.inputSection,children:[s(f,{style:o.sectionLabel,children:"Image"}),s(R,{style:o.pasteButton,onPress:E,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:s(f,{style:o.pasteButtonText,children:"Paste from Clipboard"})}),m(c,{style:o.urlRow,children:[s(De,{style:o.urlInput,testID:"buoy-image-overlay-url",value:L,onChangeText:H,placeholder:"or enter URL...",placeholderTextColor:b.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:T}),s(R,{style:[o.loadButton,!L.trim()&&o.loadButtonDisabled],onPress:T,disabled:!L.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:s(f,{style:o.loadButtonText,children:"Load"})})]})]}),m(c,{style:o.toggleSection,children:[s(Pe,{label:"Show Outline",testID:"buoy-image-overlay-outline-toggle",value:u.showOutline,onValueChange:h=>v.setShowOutline(h)}),s(Pe,{label:"Auto Track",value:$,onValueChange:Q,testID:"buoy-image-overlay-autotrack"}),u.imageUri&&m(at,{children:[m(c,{style:o.blendRow,children:[s(f,{style:o.toggleLabel,children:"Opacity"}),s(c,{style:o.blendButtons,children:[0,25,50,75,100].map(h=>s(R,{testID:`buoy-image-overlay-opacity-${h}`,style:[o.blendButton,Math.round(u.opacity*100)===h&&o.blendButtonActive],onPress:()=>v.setOpacity(h/100),activeOpacity:.7,children:m(f,{style:[o.blendButtonText,Math.round(u.opacity*100)===h&&o.blendButtonTextActive],children:[h,"%"]})},h))})]}),m(c,{style:o.blendRow,children:[s(f,{style:o.toggleLabel,children:"Flip"}),m(c,{style:o.blendButtons,children:[s(R,{style:[o.blendButton,u.invertX&&o.blendButtonActive],onPress:()=>v.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:s(f,{style:[o.blendButtonText,u.invertX&&o.blendButtonTextActive],testID:u.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),s(R,{style:[o.blendButton,u.invertY&&o.blendButtonActive],onPress:()=>v.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:s(f,{style:[o.blendButtonText,u.invertY&&o.blendButtonTextActive],testID:u.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]})]}),u.imageUri&&s(nt,{opacity:u.opacity,scale:u.scale,offsetX:u.offsetX,offsetY:u.offsetY,onOpacityChange:h=>v.setOpacity(h),onScaleChange:h=>v.setScale(h),onOffsetChange:(h,S)=>v.setOffset(h,S)}),m(c,{style:o.actions,children:[s(R,{style:o.actionButton,onPress:()=>v.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-settings",children:s(f,{style:o.actionButtonText,children:"Reset Settings"})}),s(R,{style:o.actionButton,onPress:()=>v.remeasure(),activeOpacity:.7,testID:"buoy-image-overlay-remeasure",children:s(f,{style:o.actionButtonText,children:"Remeasure"})})]})]}),d==="free"&&m(c,{style:o.controlsContainer,children:[m(c,{style:o.inputSection,children:[s(f,{style:o.sectionLabel,children:"Image"}),s(R,{style:o.pasteButton,onPress:E,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:s(f,{style:o.pasteButtonText,children:"Paste from Clipboard"})}),m(c,{style:o.urlRow,children:[s(De,{style:o.urlInput,testID:"buoy-image-overlay-url",value:L,onChangeText:H,placeholder:"or enter URL...",placeholderTextColor:b.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:T}),s(R,{style:[o.loadButton,!L.trim()&&o.loadButtonDisabled],onPress:T,disabled:!L.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:s(f,{style:o.loadButtonText,children:"Load"})})]})]}),u.imageUri&&u.mode==="free"&&m(at,{children:[m(c,{style:o.infoCard,children:[m(c,{style:o.infoRow,children:[s(f,{style:o.infoLabel,children:"Position"}),m(f,{style:o.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(u.freeX),", ",Math.round(u.freeY)]})]}),m(c,{style:o.infoRow,children:[s(f,{style:o.infoLabel,children:"Size"}),m(f,{style:o.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(u.freeWidth)," x ",Math.round(u.freeHeight)]})]}),u.imageWidth!=null&&u.imageHeight!=null&&m(c,{style:o.infoRow,children:[s(f,{style:o.infoLabel,children:"Original"}),m(f,{style:o.infoValueMono,testID:"buoy-image-overlay-info-original",children:[u.imageWidth," x ",u.imageHeight]})]})]}),s(c,{style:o.inputSection,children:s(nt,{opacity:u.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:h=>v.setOpacity(h),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),m(c,{style:o.toggleSection,children:[s(Pe,{label:"Lock Position",testID:"buoy-image-overlay-lock",tone:"warning",value:u.locked,onValueChange:h=>v.setLocked(h)}),m(c,{style:o.blendRow,children:[s(f,{style:o.toggleLabel,children:"Opacity"}),s(c,{style:o.blendButtons,children:[0,25,50,75,100].map(h=>s(R,{testID:`buoy-image-overlay-opacity-${h}`,style:[o.blendButton,Math.round(u.opacity*100)===h&&o.blendButtonActive],onPress:()=>v.setOpacity(h/100),activeOpacity:.7,children:m(f,{style:[o.blendButtonText,Math.round(u.opacity*100)===h&&o.blendButtonTextActive],children:[h,"%"]})},h))})]}),m(c,{style:o.blendRow,children:[s(f,{style:o.toggleLabel,children:"Flip"}),m(c,{style:o.blendButtons,children:[s(R,{style:[o.blendButton,u.invertX&&o.blendButtonActive],onPress:()=>v.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:s(f,{style:[o.blendButtonText,u.invertX&&o.blendButtonTextActive],testID:u.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),s(R,{style:[o.blendButton,u.invertY&&o.blendButtonActive],onPress:()=>v.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:s(f,{style:[o.blendButtonText,u.invertY&&o.blendButtonTextActive],testID:u.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]}),s(c,{style:o.actions,children:s(R,{style:o.actionButton,onPress:()=>v.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-position",children:s(f,{style:o.actionButtonText,children:"Reset Position"})})})]})]})]});return p?m(c,{style:o.inlineRoot,children:[s(c,{style:o.inlineHeader,...Do,children:ee.customContent}),te]}):s(Co,{visible:e,onClose:t,onMinimize:r,minimizeTargetPosition:x,initialModalState:g,header:ee,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:te})}function Go(e={}){return s(Ee,{...e,inline:true,visible:true,onClose:()=>{}})}var o=re.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:Ke.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:Ke.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:b.color.buttonSurface,borderWidth:1,borderColor:b.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:b.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:b.color.buttonSurface,borderWidth:1,borderColor:b.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:b.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:b.color.surface,borderRadius:12,borderWidth:1,borderColor:b.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:b.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:b.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:b.color.surface,borderRadius:8,borderWidth:1,borderColor:b.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:b.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:b.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:b.color.text,fontFamily:Po},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:b.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:b.color.accentSoft,borderWidth:1,borderColor:b.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:b.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:b.color.surfaceElevated,borderWidth:1,borderColor:b.color.border,paddingHorizontal:12,fontSize:13,color:b.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:b.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:b.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:b.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:b.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:b.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:b.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:b.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:b.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:b.color.textTertiary},blendButtonTextActive:{color:b.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:b.color.surfaceElevated,borderWidth:1,borderColor:b.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:b.color.textSecondary}});import{jsx as Jo}from"react/jsx-runtime";var Qo="#A855F7",rt=bt({id:"image-overlay",name:"IMG",description:"Design mockup overlay",slot:"both",icon:({size:e})=>Jo(pt,{size:e,color:Qo}),component:Ee,props:{enableSharedModalDimensions:false}}),Zo=mt(rt,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));import{useState as it,useEffect as en,useRef as lt,useMemo as st,useCallback as tn}from"react";import{absoluteFill as on,monoFont as nn}from"@buoy-gg/shared-ui/web";import{Fragment as ct,jsx as D,jsxs as Ce}from"react/jsx-runtime";function dt({uri:e,style:t,invertX:n,invertY:r}){let a=[];n&&a.push({scaleX:-1}),r&&a.push({scaleY:-1});let g=a.length>0?{transform:a}:{};return D(Re,{testID:"buoy-internal-image-overlay",source:{uri:e},style:[t,g,{pointerEvents:"none"}]})}var le=30;function an({imageUri:e,x:t,y:n,width:r,height:a,opacity:g,aspectRatio:x,invertX:p,invertY:y,locked:d}){let[i,I]=it(false),A=lt({x:0,y:0}),u=lt({x:0,y:0,width:0,height:0}),P=be.get("window"),L=st(()=>ve.create({onStartShouldSetPanResponder:()=>!d,onMoveShouldSetPanResponder:(W,O)=>!d&&(Math.abs(O.dx)>2||Math.abs(O.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let W=v.getState();A.current={x:W.freeX,y:W.freeY},I(true)},onPanResponderMove:(W,O)=>{let T=v.getState(),E=Math.max(0,Math.min(A.current.x+O.dx,P.width-T.freeWidth)),z=Math.max(0,Math.min(A.current.y+O.dy,P.height-T.freeHeight));v.setFreePosition(E,z)},onPanResponderRelease:()=>I(false),onPanResponderTerminate:()=>I(false)}),[P.width,P.height,d]),H=tn(W=>ve.create({onStartShouldSetPanResponder:()=>!d,onMoveShouldSetPanResponder:()=>!d,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let O=v.getState();u.current={x:O.freeX,y:O.freeY,width:O.freeWidth,height:O.freeHeight},I(true)},onPanResponderMove:(O,T)=>{let{dx:E,dy:z}=T;if(Math.abs(E)<.5&&Math.abs(z)<.5)return;let w=u.current,k=x>0?x:w.width/w.height,ee=Math.abs(E),te=Math.abs(z),h=ee>=te,S,C,N=w.x,G=w.y;switch(W){case"bottomRight":{S=h?w.width+E:(w.height+z)*k,S=Math.max(le,Math.min(S,P.width-w.x)),C=S/k;break}case"bottomLeft":{S=h?w.width-E:(w.height+z)*k,S=Math.max(le,S),C=S/k,N=w.x+w.width-S,N=Math.max(0,N),S=Math.min(S,w.x+w.width),C=S/k;break}case"topRight":{S=h?w.width+E:(w.height-z)*k,S=Math.max(le,Math.min(S,P.width-w.x)),C=S/k,G=w.y+w.height-C,G=Math.max(0,G),C=Math.min(C,w.y+w.height),S=C*k;break}case"topLeft":{S=h?w.width-E:(w.height-z)*k,S=Math.max(le,S),C=S/k,N=w.x+w.width-S,G=w.y+w.height-C,N=Math.max(0,N),G=Math.max(0,G),S=Math.min(S,w.x+w.width),C=S/k,G=w.y+w.height-C;break}}S=Math.max(le,Math.round(S)),C=Math.max(le,Math.round(C)),v.setFreeDimensions(S,C,Math.round(N),Math.round(G))},onPanResponderRelease:()=>I(false),onPanResponderTerminate:()=>I(false)}),[P.width,P.height,x,d]),$=st(()=>({topLeft:H("topLeft"),topRight:H("topRight"),bottomLeft:H("bottomLeft"),bottomRight:H("bottomRight")}),[H]),Q={...on,opacity:g};return Ce(c,{testID:"buoy-image-overlay-free-box",style:{position:"absolute",left:t,top:n,width:r,height:a},pointerEvents:d?"none":"auto",children:[D(c,{style:re.absoluteFill,...d?{}:L.panHandlers,children:D(dt,{uri:e,style:Q,invertX:p,invertY:y})}),D(c,{pointerEvents:"none",style:[B.freeBorder,i&&B.freeBorderActive,d&&B.freeBorderLocked]}),!d&&Ce(ct,{children:[D(c,{...$.topLeft.panHandlers,style:[B.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(c,{style:[B.cornerHandle,i&&B.cornerHandleActive]})}),D(c,{...$.topRight.panHandlers,style:[B.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(c,{style:[B.cornerHandle,i&&B.cornerHandleActive]})}),D(c,{...$.bottomLeft.panHandlers,style:[B.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(c,{style:[B.cornerHandle,i&&B.cornerHandleActive]})}),D(c,{...$.bottomRight.panHandlers,style:[B.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(c,{style:[B.cornerHandle,i&&B.cornerHandleActive]})})]})]})}function rn(){let[e,t]=it(()=>v.getState());en(()=>v.subscribe(t),[]);let{mode:n,enabled:r,imageUri:a,imageWidth:g,imageHeight:x,targetRect:p,targetLabel:y,showOutline:d,opacity:i,scale:I,offsetX:A,offsetY:u,invertX:P,invertY:L,locked:H,freeX:$,freeY:Q,freeWidth:W,freeHeight:O}=e,T=g&&x&&x>0?g/x:0;if(n==="free"&&r&&a)return D(c,{style:B.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:D(an,{imageUri:a,x:$,y:Q,width:W,height:O,opacity:i,aspectRatio:T,invertX:P,invertY:L,locked:H})});if(!p)return null;let E=r&&a;return Ce(c,{style:B.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[d&&Ce(ct,{children:[D(c,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",testID:"buoy-image-overlay-outline",style:[B.highlight,{left:p.x-3,top:p.y-3,width:p.width+6,height:p.height+6}]}),y&&D(c,{pointerEvents:"none",style:[B.label,{left:p.x,top:p.y-20}],children:D(f,{style:B.labelText,testID:"buoy-image-overlay-outline-label",children:y})})]}),E&&(()=>{let z=(g??p.width)*I,w=(x??p.height)*I,k=p.x+p.width/2,ee=p.y+p.height/2,te={position:"absolute",left:k-z/2+A,top:ee-w/2+u,width:z,height:w,opacity:i};return D(dt,{uri:a,style:te,invertX:P,invertY:L})})()]})}var B=re.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:Ve.OS==="web"?999:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:nn},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});export{v as ImageOverlayController,Ee as ImageOverlayModal,rn as ImageOverlayStandalone,Go as ImageOverlayToolView,Zo as createImageOverlayTool,rt as imageOverlayToolPreset,ge as scanForImageTargets,Oo as setDevToolsHookOverride};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/image-overlay",
3
- "version": "7.0.73",
3
+ "version": "7.0.75",
4
4
  "description": "Overlay a design mockup on a running React Native app and adjust opacity to compare spacing and alignment.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -34,7 +34,7 @@
34
34
  ],
35
35
  "sideEffects": false,
36
36
  "dependencies": {
37
- "@buoy-gg/shared-ui": "^7.0.73"
37
+ "@buoy-gg/shared-ui": "^7.0.75"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "react": "*"