@buoy-gg/permissions 7.0.63 → 7.0.64

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.PermissionsBody=PermissionsBody;var _react=require("react");var _sharedUi=require("@buoy-gg/shared-ui");var _expo=require("../engine/adapters/expo");var _install=require("../engine/install");var _store=require("../engine/store");var _permissionsSyncAdapter=require("../sync/permissionsSyncAdapter");var _PermissionsToolView=require("./PermissionsToolView");var _jsxRuntime=require("react/jsx-runtime");const actions=_permissionsSyncAdapter.permissionsSyncAdapter.actions;async function runAction(e,r){const s=actions[e];if(!s)throw new Error(`Unknown permissions action: ${e}`);return s(r)}function reload(){void(0,_sharedUi.reloadApp)("auto","buoy permissions").catch(()=>{})}function PermissionsBody(){(0,_react.useEffect)(()=>{(0,_install.installPermissions)();void(0,_expo.refreshExpoRealStates)()},[]);const e=(0,_react.useSyncExternalStore)(_store.subscribePermissions,_store.getPermissionsSnapshot,_store.getPermissionsSnapshot);return(0,_jsxRuntime.jsx)(_PermissionsToolView.PermissionsToolView,{snapshot:e,onAction:runAction,onReload:reload})}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.PermissionsBody=PermissionsBody;var _react=require("react");var _reactNative=require("react-native");var _license=require("@buoy-gg/license");var _sharedUi=require("@buoy-gg/shared-ui");var _expo=require("../engine/adapters/expo");var _install=require("../engine/install");var _store=require("../engine/store");var _permissionsSyncAdapter=require("../sync/permissionsSyncAdapter");var _PermissionsToolView=require("./PermissionsToolView");var _jsxRuntime=require("react/jsx-runtime");const actions=_permissionsSyncAdapter.permissionsSyncAdapter.actions;async function runAction(e,r){const s=actions[e];if(!s)throw new Error(`Unknown permissions action: ${e}`);return s(r)}function reload(){void(0,_sharedUi.reloadApp)("auto","buoy permissions").catch(()=>{})}function PermissionsBody(){const[e]=(0,_react.useState)(()=>_reactNative.Platform.OS==="web"&&!(0,_license.capacitorPlatform)());(0,_react.useEffect)(()=>{(0,_install.installPermissions)();void(0,_expo.refreshExpoRealStates)()},[]);const r=(0,_react.useSyncExternalStore)(_store.subscribePermissions,_store.getPermissionsSnapshot,_store.getPermissionsSnapshot);return(0,_jsxRuntime.jsx)(_PermissionsToolView.PermissionsToolView,{snapshot:r,onAction:runAction,onReload:reload,browserOnly:e})}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.PermissionsToolView=PermissionsToolView;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _model=require("../engine/model");var _jsxRuntime=require("react/jsx-runtime");const STALE_AFTER_MS=1500;const realNow=()=>{const e=globalThis.__buoyRealNow;return typeof e==="function"?e():Date.now()};function valueLabel(e,i){if(!e.effective)return"Not Checked";if(e.once&&e.effective==="granted")return"Allowed Once";return(0,_model.stateLabel)(e.id,i,e.effective)}function PermissionsToolView({snapshot:e,onAction:i,onReload:l}){const o=(0,_sharedUi.useSafeAreaInsets)({minBottom:16});const[a,c]=(0,_react.useState)(null);const[s,h]=(0,_react.useState)({name:"list"});const t=(r,m)=>{c(null);i(r,m).catch(f=>{c(f instanceof Error?f.message:String(f))})};const n=s.name==="detail"?e?.permissions.find(r=>r.id===s.id):void 0;const x=()=>h(s.name==="detail"&&s.from==="other"?{name:"other"}:{name:"list"});const d=s.name==="other"?"Other Permissions":n?n.label:null;const T=(0,_sharedUi.useToolScreenHeader)(d?{title:d,onBack:x,searchable:false}:null,[d,s.name,s.name==="detail"?s.from:null]);if(!e){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.waiting,testID:"permissions-waiting",children:(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{centered:true,children:"Waiting for the app\u2026"})})}const{platform:p,permissions:y}=e;const j=y.filter(r=>r.calls>0||r.override!==null);const g=y.filter(r=>!(r.calls>0||r.override!==null));const b=(r,m)=>h({name:"detail",id:r,from:m});let u;if(s.name==="detail"&&n){u=(0,_jsxRuntime.jsx)(DetailScreen,{row:n,platform:p,log:e.log,run:t,onPicked:x})}else if(s.name==="other"){u=(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(PermissionList,{rows:g,platform:p,onOpen:r=>b(r,"other")}),(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{children:"Your app can ask for these but hasn't yet."})]})}else{u=(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[j.length>0?(0,_jsxRuntime.jsx)(PermissionList,{rows:j,platform:p,onOpen:r=>b(r,"list"),onReload:l}):(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{padded:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.empty,testID:"permissions-empty",children:"Your app hasn't checked any permissions yet. Open a screen that uses location, the camera or notifications and it will show up here."})}),g.length>0?(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${g.length}`,activeOpacity:.6,onPress:()=>h({name:"other"}),style:styles.row,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:"Other Permissions"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowRight,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowValue,children:g.length}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})]})}):null,e.overriddenCount>0?(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>t("resetAll"),style:styles.row,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.destructive,children:"Use Real Permissions"})})}):null]})}return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:styles.fill,contentContainerStyle:[styles.content,{paddingBottom:o.bottom}],testID:"permissions-scroll",children:[!T&&s.name!=="list"?(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:x,style:styles.inlineBack,children:[(0,_jsxRuntime.jsx)(_sharedUi.ChevronLeft,{size:18,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.inlineBackText,children:s.name==="detail"&&s.from==="other"?"Other Permissions":"Permissions"}),d?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.inlineTitle,children:d}):null]}):null,a?(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{tone:"danger",centered:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"permissions-error",children:a})}):null,u]})}function PermissionList({rows:e,platform:i,onOpen:l,onReload:o}){const[,a]=(0,_react.useReducer)(t=>t+1,0);const c=realNow();const s=e.filter(t=>t.stale&&t.changedAt!==null&&c-t.changedAt<STALE_AFTER_MS).map(t=>STALE_AFTER_MS-(c-t.changedAt));const h=s.length>0?Math.min(...s):null;(0,_react.useEffect)(()=>{if(h===null)return;const t=setTimeout(a,h+50);return()=>clearTimeout(t)},[h]);return(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_sharedUi.NightRows,{children:e.map(t=>{const n=t.stale&&t.changedAt!==null&&c-t.changedAt>=STALE_AFTER_MS;return(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(PermissionRowView,{row:t,platform:i,onPress:()=>l(t.id)}),n?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.stale,testID:`permissions-stale-${t.id}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.staleText,children:"The app hasn't checked again since this changed."}),o?(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`permissions-reload-${t.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:o,hitSlop:{top:8,bottom:8,left:8,right:8},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.staleAction,children:"Reload App"})}):null]}):null]},t.id)})})})}function PermissionRowView({row:e,platform:i,onPress:l}){const o=e.override!==null;const a=valueLabel(e,i);const c=e.real?(0,_model.stateLabel)(e.id,i,e.real):"Not Checked";return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${a}${o?`, simulated. Phone: ${c}`:""}`,activeOpacity:.6,onPress:l,style:styles.row,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowLeft,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:e.label}),o?(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",c]}):null]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowRight,children:[o?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.dot}):null,(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.rowValue,o?styles.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:a}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})]})}function OptionRow({title:e,detail:i,selected:l,testID:o,onPress:a}){return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:o,accessibilityRole:"button",accessibilityLabel:`${e}. ${i}`,accessibilityState:{selected:l},activeOpacity:.6,onPress:a,style:styles.option,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.optionText,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:e}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.optionDetail,children:i})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.check,children:l?(0,_jsxRuntime.jsx)(_sharedUi.Check,{size:18,color:_sharedUi.night.color.accent}):null})]})}const VERBS={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function DetailScreen({row:e,platform:i,log:l,run:o,onPicked:a}){const c=e.real?(0,_model.stateLabel)(e.id,i,e.real):null;const s=n=>{if(n===null)o("clearOverride",{permission:e.id});else o("setOverride",{permission:e.id,state:n});a()};const h=l.filter(n=>n.permission===e.id).slice(0,8);const t=e.canRequestReal&&e.real==="undetermined";return(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightSectionLabel,{children:"What the app sees"}),(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsxs)(_sharedUi.NightRows,{children:[(0,_jsxRuntime.jsx)(OptionRow,{title:"Phone's Setting",detail:c?`Use what the phone says: ${c}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>s(null)},"real"),e.states.map(n=>(0,_jsxRuntime.jsx)(OptionRow,{title:(0,_model.stateLabel)(e.id,i,n),detail:(0,_model.stateDescription)(e.id,i,n),selected:e.override===n,testID:`permissions-state-${e.id}-${n}`,onPress:()=>s(n)},n))]})})]}),t?(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>o("requestReal",{permission:e.id}),style:styles.row,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.action,children:"Show Real Prompt"})})}),(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{tone:"warning",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,h.length>0?(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightSectionLabel,{children:"Recent"}),(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_sharedUi.NightRows,{children:h.map(n=>(0,_jsxRuntime.jsx)(RecentRow,{entry:n,platform:i},n.id))})}),e.sources.length>0?(0,_jsxRuntime.jsxs)(_sharedUi.NightFootnote,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function clockTime(e){const i=new Date(e);const l=o=>String(o).padStart(2,"0");return`${l(i.getHours())}:${l(i.getMinutes())}:${l(i.getSeconds())}`}function RecentRow({entry:e,platform:i}){const l=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":(0,_model.stateLabel)(e.permission,i,e.returned):"";return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.recentRow,testID:`permissions-log-${e.id}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.recentTime,children:clockTime(e.at)}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.recentVerb,numberOfLines:1,children:VERBS[e.kind]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.recentResult,e.error?styles.recentFailed:null],numberOfLines:1,children:l})]})}const styles=_reactNative.StyleSheet.create({fill:{flex:1},content:{paddingHorizontal:_sharedUi.night.gutter,paddingTop:12,gap:_sharedUi.night.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.row},rowSub:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.row},rowValueSimulated:{color:_sharedUi.night.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:_sharedUi.night.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:_sharedUi.night.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.caption,flexShrink:1},staleAction:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.caption,fontWeight:"600"},destructive:{color:_sharedUi.night.color.danger,fontSize:_sharedUi.night.font.row},action:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.row},inlineTitle:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:10},recentTime:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.body,flex:1},recentResult:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.body},recentFailed:{color:_sharedUi.night.color.danger}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.PermissionsToolView=PermissionsToolView;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _model=require("../engine/model");var _jsxRuntime=require("react/jsx-runtime");const STALE_AFTER_MS=1500;const realNow=()=>{const e=globalThis.__buoyRealNow;return typeof e==="function"?e():Date.now()};function valueLabel(e,i){if(!e.effective)return"Not Checked";if(e.once&&e.effective==="granted")return"Allowed Once";return(0,_model.stateLabel)(e.id,i,e.effective)}function PermissionsToolView({snapshot:e,onAction:i,onReload:l,browserOnly:o}){const a=(0,_sharedUi.useSafeAreaInsets)({minBottom:16});const[c,h]=(0,_react.useState)(null);const[n,t]=(0,_react.useState)({name:"list"});const s=(r,f)=>{h(null);i(r,f).catch(y=>{h(y instanceof Error?y.message:String(y))})};const u=n.name==="detail"?e?.permissions.find(r=>r.id===n.id):void 0;const x=()=>t(n.name==="detail"&&n.from==="other"?{name:"other"}:{name:"list"});const d=n.name==="other"?"Other Permissions":u?u.label:null;const T=(0,_sharedUi.useToolScreenHeader)(d?{title:d,onBack:x,searchable:false}:null,[d,n.name,n.name==="detail"?n.from:null]);if(!e){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.waiting,testID:"permissions-waiting",children:(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{centered:true,children:"Waiting for the app\u2026"})})}const{platform:m,permissions:j}=e;const b=j.filter(r=>r.calls>0||r.override!==null);const p=j.filter(r=>!(r.calls>0||r.override!==null));const w=(r,f)=>t({name:"detail",id:r,from:f});let g;if(o){g=(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{padded:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.empty,testID:"permissions-browser-only",children:"This app runs in a plain browser. The browser keeps its own permissions. Buoy can't change them here. This tool works when the app runs on a phone with Capacitor."})})}else if(n.name==="detail"&&u){g=(0,_jsxRuntime.jsx)(DetailScreen,{row:u,platform:m,log:e.log,run:s,onPicked:x})}else if(n.name==="other"){g=(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(PermissionList,{rows:p,platform:m,onOpen:r=>w(r,"other")}),(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{children:"Your app can ask for these but hasn't yet."})]})}else{g=(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[b.length>0?(0,_jsxRuntime.jsx)(PermissionList,{rows:b,platform:m,onOpen:r=>w(r,"list"),onReload:l}):(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{padded:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.empty,testID:"permissions-empty",children:"Your app hasn't checked any permissions yet. Open a screen that uses location, the camera or notifications and it will show up here."})}),p.length>0?(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${p.length}`,activeOpacity:.6,onPress:()=>t({name:"other"}),style:styles.row,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:"Other Permissions"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowRight,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowValue,children:p.length}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})]})}):null,e.overriddenCount>0?(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>s("resetAll"),style:styles.row,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.destructive,children:"Use Real Permissions"})})}):null]})}return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:styles.fill,contentContainerStyle:[styles.content,{paddingBottom:a.bottom}],testID:"permissions-scroll",children:[!T&&n.name!=="list"?(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:x,style:styles.inlineBack,children:[(0,_jsxRuntime.jsx)(_sharedUi.ChevronLeft,{size:18,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.inlineBackText,children:n.name==="detail"&&n.from==="other"?"Other Permissions":"Permissions"}),d?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.inlineTitle,children:d}):null]}):null,c?(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{tone:"danger",centered:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"permissions-error",children:c})}):null,g]})}function PermissionList({rows:e,platform:i,onOpen:l,onReload:o}){const[,a]=(0,_react.useReducer)(t=>t+1,0);const c=realNow();const h=e.filter(t=>t.stale&&t.changedAt!==null&&c-t.changedAt<STALE_AFTER_MS).map(t=>STALE_AFTER_MS-(c-t.changedAt));const n=h.length>0?Math.min(...h):null;(0,_react.useEffect)(()=>{if(n===null)return;const t=setTimeout(a,n+50);return()=>clearTimeout(t)},[n]);return(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_sharedUi.NightRows,{children:e.map(t=>{const s=t.stale&&t.changedAt!==null&&c-t.changedAt>=STALE_AFTER_MS;return(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(PermissionRowView,{row:t,platform:i,onPress:()=>l(t.id)}),s?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.stale,testID:`permissions-stale-${t.id}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.staleText,children:"The app hasn't checked again since this changed."}),o?(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`permissions-reload-${t.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:o,hitSlop:{top:8,bottom:8,left:8,right:8},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.staleAction,children:"Reload App"})}):null]}):null]},t.id)})})})}function PermissionRowView({row:e,platform:i,onPress:l}){const o=e.override!==null;const a=valueLabel(e,i);const c=e.real?(0,_model.stateLabel)(e.id,i,e.real):"Not Checked";return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${a}${o?`, simulated. Phone: ${c}`:""}`,activeOpacity:.6,onPress:l,style:styles.row,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowLeft,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:e.label}),o?(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",c]}):null]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowRight,children:[o?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.dot}):null,(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.rowValue,o?styles.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:a}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})]})}function OptionRow({title:e,detail:i,selected:l,testID:o,onPress:a}){return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:o,accessibilityRole:"button",accessibilityLabel:`${e}. ${i}`,accessibilityState:{selected:l},activeOpacity:.6,onPress:a,style:styles.option,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.optionText,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:e}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.optionDetail,children:i})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.check,children:l?(0,_jsxRuntime.jsx)(_sharedUi.Check,{size:18,color:_sharedUi.night.color.accent}):null})]})}const VERBS={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function DetailScreen({row:e,platform:i,log:l,run:o,onPicked:a}){const c=e.real?(0,_model.stateLabel)(e.id,i,e.real):null;const h=s=>{if(s===null)o("clearOverride",{permission:e.id});else o("setOverride",{permission:e.id,state:s});a()};const n=l.filter(s=>s.permission===e.id).slice(0,8);const t=e.canRequestReal&&e.real==="undetermined";return(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightSectionLabel,{children:"What the app sees"}),(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsxs)(_sharedUi.NightRows,{children:[(0,_jsxRuntime.jsx)(OptionRow,{title:"Phone's Setting",detail:c?`Use what the phone says: ${c}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>h(null)},"real"),e.states.map(s=>(0,_jsxRuntime.jsx)(OptionRow,{title:(0,_model.stateLabel)(e.id,i,s),detail:(0,_model.stateDescription)(e.id,i,s),selected:e.override===s,testID:`permissions-state-${e.id}-${s}`,onPress:()=>h(s)},s))]})})]}),t?(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>o("requestReal",{permission:e.id}),style:styles.row,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.action,children:"Show Real Prompt"})})}),(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{tone:"warning",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,n.length>0?(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightSectionLabel,{children:"Recent"}),(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_sharedUi.NightRows,{children:n.map(s=>(0,_jsxRuntime.jsx)(RecentRow,{entry:s,platform:i},s.id))})}),e.sources.length>0?(0,_jsxRuntime.jsxs)(_sharedUi.NightFootnote,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function clockTime(e){const i=new Date(e);const l=o=>String(o).padStart(2,"0");return`${l(i.getHours())}:${l(i.getMinutes())}:${l(i.getSeconds())}`}function RecentRow({entry:e,platform:i}){const l=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":(0,_model.stateLabel)(e.permission,i,e.returned):"";return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.recentRow,testID:`permissions-log-${e.id}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.recentTime,children:clockTime(e.at)}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.recentVerb,numberOfLines:1,children:VERBS[e.kind]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.recentResult,e.error?styles.recentFailed:null],numberOfLines:1,children:l})]})}const styles=_reactNative.StyleSheet.create({fill:{flex:1},content:{paddingHorizontal:_sharedUi.night.gutter,paddingTop:12,gap:_sharedUi.night.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.row},rowSub:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.row},rowValueSimulated:{color:_sharedUi.night.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:_sharedUi.night.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:_sharedUi.night.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.caption,flexShrink:1},staleAction:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.caption,fontWeight:"600"},destructive:{color:_sharedUi.night.color.danger,fontSize:_sharedUi.night.font.row},action:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.row},inlineTitle:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:10},recentTime:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.body,flex:1},recentResult:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.body},recentFailed:{color:_sharedUi.night.color.danger}});
@@ -1 +1 @@
1
- "use strict";import{useEffect as i,useSyncExternalStore as t}from"react";import{reloadApp as e}from"@buoy-gg/shared-ui";import{refreshExpoRealStates as m}from"../engine/adapters/expo";import{installPermissions as p}from"../engine/install";import{getPermissionsSnapshot as r,subscribePermissions as c}from"../engine/store";import{permissionsSyncAdapter as a}from"../sync/permissionsSyncAdapter";import{PermissionsToolView as f}from"./PermissionsToolView";import{jsx as u}from"react/jsx-runtime";const l=a.actions;async function d(o,n){const s=l[o];if(!s)throw new Error(`Unknown permissions action: ${o}`);return s(n)}function h(){void e("auto","buoy permissions").catch(()=>{})}export function PermissionsBody(){i(()=>{p();void m()},[]);const o=t(c,r,r);return u(f,{snapshot:o,onAction:d,onReload:h})}
1
+ "use strict";import{useEffect as n,useState as i,useSyncExternalStore as e}from"react";import{Platform as m}from"react-native";import{capacitorPlatform as a}from"@buoy-gg/license";import{reloadApp as p}from"@buoy-gg/shared-ui";import{refreshExpoRealStates as c}from"../engine/adapters/expo";import{installPermissions as f}from"../engine/install";import{getPermissionsSnapshot as t,subscribePermissions as u}from"../engine/store";import{permissionsSyncAdapter as l}from"../sync/permissionsSyncAdapter";import{PermissionsToolView as d}from"./PermissionsToolView";import{jsx as w}from"react/jsx-runtime";const y=l.actions;async function P(o,r){const s=y[o];if(!s)throw new Error(`Unknown permissions action: ${o}`);return s(r)}function S(){void p("auto","buoy permissions").catch(()=>{})}export function PermissionsBody(){const[o]=i(()=>m.OS==="web"&&!a());n(()=>{f();void c()},[]);const r=e(u,t,t);return w(d,{snapshot:r,onAction:P,onReload:S,browserOnly:o})}
@@ -1 +1 @@
1
- "use strict";import{useEffect as F,useReducer as _,useState as A}from"react";import{ScrollView as E,StyleSheet as W,Text as a,TouchableOpacity as y,View as p}from"react-native";import{Check as q,ChevronLeft as U,ChevronRight as V,NightCard as b,NightFootnote as S,NightRows as v,NightSectionLabel as H,night as n,useSafeAreaInsets as G,useToolScreenHeader as M}from"@buoy-gg/shared-ui";import{stateDescription as Y,stateLabel as x}from"../engine/model";import{jsx as t,jsxs as s,Fragment as C}from"react/jsx-runtime";const z=1500;const J=()=>{const e=globalThis.__buoyRealNow;return typeof e==="function"?e():Date.now()};function K(e,l){if(!e.effective)return"Not Checked";if(e.once&&e.effective==="granted")return"Allowed Once";return x(e.id,l,e.effective)}export function PermissionsToolView({snapshot:e,onAction:l,onReload:h}){const d=G({minBottom:16});const[f,m]=A(null);const[c,g]=A({name:"list"});const o=(u,P)=>{m(null);l(u,P).catch(I=>{m(I instanceof Error?I.message:String(I))})};const r=c.name==="detail"?e?.permissions.find(u=>u.id===c.id):void 0;const k=()=>g(c.name==="detail"&&c.from==="other"?{name:"other"}:{name:"list"});const w=c.name==="other"?"Other Permissions":r?r.label:null;const j=M(w?{title:w,onBack:k,searchable:false}:null,[w,c.name,c.name==="detail"?c.from:null]);if(!e){return t(p,{style:i.waiting,testID:"permissions-waiting",children:t(S,{centered:true,children:"Waiting for the app\u2026"})})}const{platform:D,permissions:$}=e;const O=$.filter(u=>u.calls>0||u.override!==null);const R=$.filter(u=>!(u.calls>0||u.override!==null));const L=(u,P)=>g({name:"detail",id:u,from:P});let T;if(c.name==="detail"&&r){T=t(Z,{row:r,platform:D,log:e.log,run:o,onPicked:k})}else if(c.name==="other"){T=s(p,{children:[t(B,{rows:R,platform:D,onOpen:u=>L(u,"other")}),t(S,{children:"Your app can ask for these but hasn't yet."})]})}else{T=s(C,{children:[O.length>0?t(B,{rows:O,platform:D,onOpen:u=>L(u,"list"),onReload:h}):t(b,{padded:true,children:t(a,{style:i.empty,testID:"permissions-empty",children:"Your app hasn't checked any permissions yet. Open a screen that uses location, the camera or notifications and it will show up here."})}),R.length>0?t(b,{children:s(y,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${R.length}`,activeOpacity:.6,onPress:()=>g({name:"other"}),style:i.row,children:[t(a,{style:i.rowTitle,children:"Other Permissions"}),s(p,{style:i.rowRight,children:[t(a,{style:i.rowValue,children:R.length}),t(V,{size:16,color:n.color.textTertiary})]})]})}):null,e.overriddenCount>0?t(b,{children:t(y,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>o("resetAll"),style:i.row,children:t(a,{style:i.destructive,children:"Use Real Permissions"})})}):null]})}return s(E,{style:i.fill,contentContainerStyle:[i.content,{paddingBottom:d.bottom}],testID:"permissions-scroll",children:[!j&&c.name!=="list"?s(y,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:k,style:i.inlineBack,children:[t(U,{size:18,color:n.color.accent}),t(a,{style:i.inlineBackText,children:c.name==="detail"&&c.from==="other"?"Other Permissions":"Permissions"}),w?t(a,{style:i.inlineTitle,children:w}):null]}):null,f?t(S,{tone:"danger",centered:true,children:t(a,{testID:"permissions-error",children:f})}):null,T]})}function B({rows:e,platform:l,onOpen:h,onReload:d}){const[,f]=_(o=>o+1,0);const m=J();const c=e.filter(o=>o.stale&&o.changedAt!==null&&m-o.changedAt<z).map(o=>z-(m-o.changedAt));const g=c.length>0?Math.min(...c):null;F(()=>{if(g===null)return;const o=setTimeout(f,g+50);return()=>clearTimeout(o)},[g]);return t(b,{children:t(v,{children:e.map(o=>{const r=o.stale&&o.changedAt!==null&&m-o.changedAt>=z;return s(p,{children:[t(Q,{row:o,platform:l,onPress:()=>h(o.id)}),r?s(p,{style:i.stale,testID:`permissions-stale-${o.id}`,children:[t(a,{style:i.staleText,children:"The app hasn't checked again since this changed."}),d?t(y,{testID:`permissions-reload-${o.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:d,hitSlop:{top:8,bottom:8,left:8,right:8},children:t(a,{style:i.staleAction,children:"Reload App"})}):null]}):null]},o.id)})})})}function Q({row:e,platform:l,onPress:h}){const d=e.override!==null;const f=K(e,l);const m=e.real?x(e.id,l,e.real):"Not Checked";return s(y,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${f}${d?`, simulated. Phone: ${m}`:""}`,activeOpacity:.6,onPress:h,style:i.row,children:[s(p,{style:i.rowLeft,children:[t(a,{style:i.rowTitle,children:e.label}),d?s(a,{style:i.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",m]}):null]}),s(p,{style:i.rowRight,children:[d?t(p,{style:i.dot}):null,t(a,{style:[i.rowValue,d?i.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:f}),t(V,{size:16,color:n.color.textTertiary})]})]})}function N({title:e,detail:l,selected:h,testID:d,onPress:f}){return s(y,{testID:d,accessibilityRole:"button",accessibilityLabel:`${e}. ${l}`,accessibilityState:{selected:h},activeOpacity:.6,onPress:f,style:i.option,children:[s(p,{style:i.optionText,children:[t(a,{style:i.rowTitle,children:e}),t(a,{style:i.optionDetail,children:l})]}),t(p,{style:i.check,children:h?t(q,{size:18,color:n.color.accent}):null})]})}const X={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function Z({row:e,platform:l,log:h,run:d,onPicked:f}){const m=e.real?x(e.id,l,e.real):null;const c=r=>{if(r===null)d("clearOverride",{permission:e.id});else d("setOverride",{permission:e.id,state:r});f()};const g=h.filter(r=>r.permission===e.id).slice(0,8);const o=e.canRequestReal&&e.real==="undetermined";return s(C,{children:[s(p,{children:[t(H,{children:"What the app sees"}),t(b,{children:s(v,{children:[t(N,{title:"Phone's Setting",detail:m?`Use what the phone says: ${m}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>c(null)},"real"),e.states.map(r=>t(N,{title:x(e.id,l,r),detail:Y(e.id,l,r),selected:e.override===r,testID:`permissions-state-${e.id}-${r}`,onPress:()=>c(r)},r))]})})]}),o?s(p,{children:[t(b,{children:t(y,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>d("requestReal",{permission:e.id}),style:i.row,children:t(a,{style:i.action,children:"Show Real Prompt"})})}),t(S,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?t(S,{tone:"warning",children:t(a,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,g.length>0?s(p,{children:[t(H,{children:"Recent"}),t(b,{children:t(v,{children:g.map(r=>t(te,{entry:r,platform:l},r.id))})}),e.sources.length>0?s(S,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function ee(e){const l=new Date(e);const h=d=>String(d).padStart(2,"0");return`${h(l.getHours())}:${h(l.getMinutes())}:${h(l.getSeconds())}`}function te({entry:e,platform:l}){const h=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":x(e.permission,l,e.returned):"";return s(p,{style:i.recentRow,testID:`permissions-log-${e.id}`,children:[t(a,{style:i.recentTime,children:ee(e.at)}),t(a,{style:i.recentVerb,numberOfLines:1,children:X[e.kind]}),t(a,{style:[i.recentResult,e.error?i.recentFailed:null],numberOfLines:1,children:h})]})}const i=W.create({fill:{flex:1},content:{paddingHorizontal:n.gutter,paddingTop:12,gap:n.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:n.color.textSecondary,fontSize:n.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:n.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:n.color.text,fontSize:n.font.row},rowSub:{color:n.color.textTertiary,fontSize:n.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:n.color.textSecondary,fontSize:n.font.row},rowValueSimulated:{color:n.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:n.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:n.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:n.color.textSecondary,fontSize:n.font.caption,flexShrink:1},staleAction:{color:n.color.accent,fontSize:n.font.caption,fontWeight:"600"},destructive:{color:n.color.danger,fontSize:n.font.row},action:{color:n.color.accent,fontSize:n.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:n.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:n.color.textTertiary,fontSize:n.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:n.color.accent,fontSize:n.font.row},inlineTitle:{color:n.color.text,fontSize:n.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:n.rowPadH,paddingVertical:10},recentTime:{color:n.color.textTertiary,fontSize:n.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:n.color.text,fontSize:n.font.body,flex:1},recentResult:{color:n.color.textSecondary,fontSize:n.font.body},recentFailed:{color:n.color.danger}});
1
+ "use strict";import{useEffect as _,useReducer as E,useState as V}from"react";import{ScrollView as W,StyleSheet as q,Text as c,TouchableOpacity as b,View as u}from"react-native";import{Check as U,ChevronLeft as G,ChevronRight as H,NightCard as y,NightFootnote as S,NightRows as z,NightSectionLabel as C,night as n,useSafeAreaInsets as M,useToolScreenHeader as Y}from"@buoy-gg/shared-ui";import{stateDescription as J,stateLabel as R}from"../engine/model";import{jsx as t,jsxs as r,Fragment as B}from"react/jsx-runtime";const $=1500;const K=()=>{const e=globalThis.__buoyRealNow;return typeof e==="function"?e():Date.now()};function Q(e,l){if(!e.effective)return"Not Checked";if(e.once&&e.effective==="granted")return"Allowed Once";return R(e.id,l,e.effective)}export function PermissionsToolView({snapshot:e,onAction:l,onReload:h,browserOnly:d}){const f=M({minBottom:16});const[m,g]=V(null);const[s,o]=V({name:"list"});const a=(p,I)=>{g(null);l(p,I).catch(v=>{g(v instanceof Error?v.message:String(v))})};const T=s.name==="detail"?e?.permissions.find(p=>p.id===s.id):void 0;const D=()=>o(s.name==="detail"&&s.from==="other"?{name:"other"}:{name:"list"});const w=s.name==="other"?"Other Permissions":T?T.label:null;const F=Y(w?{title:w,onBack:D,searchable:false}:null,[w,s.name,s.name==="detail"?s.from:null]);if(!e){return t(u,{style:i.waiting,testID:"permissions-waiting",children:t(S,{centered:true,children:"Waiting for the app\u2026"})})}const{platform:P,permissions:O}=e;const L=O.filter(p=>p.calls>0||p.override!==null);const k=O.filter(p=>!(p.calls>0||p.override!==null));const A=(p,I)=>o({name:"detail",id:p,from:I});let x;if(d){x=t(y,{padded:true,children:t(c,{style:i.empty,testID:"permissions-browser-only",children:"This app runs in a plain browser. The browser keeps its own permissions. Buoy can't change them here. This tool works when the app runs on a phone with Capacitor."})})}else if(s.name==="detail"&&T){x=t(ee,{row:T,platform:P,log:e.log,run:a,onPicked:D})}else if(s.name==="other"){x=r(u,{children:[t(N,{rows:k,platform:P,onOpen:p=>A(p,"other")}),t(S,{children:"Your app can ask for these but hasn't yet."})]})}else{x=r(B,{children:[L.length>0?t(N,{rows:L,platform:P,onOpen:p=>A(p,"list"),onReload:h}):t(y,{padded:true,children:t(c,{style:i.empty,testID:"permissions-empty",children:"Your app hasn't checked any permissions yet. Open a screen that uses location, the camera or notifications and it will show up here."})}),k.length>0?t(y,{children:r(b,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${k.length}`,activeOpacity:.6,onPress:()=>o({name:"other"}),style:i.row,children:[t(c,{style:i.rowTitle,children:"Other Permissions"}),r(u,{style:i.rowRight,children:[t(c,{style:i.rowValue,children:k.length}),t(H,{size:16,color:n.color.textTertiary})]})]})}):null,e.overriddenCount>0?t(y,{children:t(b,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>a("resetAll"),style:i.row,children:t(c,{style:i.destructive,children:"Use Real Permissions"})})}):null]})}return r(W,{style:i.fill,contentContainerStyle:[i.content,{paddingBottom:f.bottom}],testID:"permissions-scroll",children:[!F&&s.name!=="list"?r(b,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:D,style:i.inlineBack,children:[t(G,{size:18,color:n.color.accent}),t(c,{style:i.inlineBackText,children:s.name==="detail"&&s.from==="other"?"Other Permissions":"Permissions"}),w?t(c,{style:i.inlineTitle,children:w}):null]}):null,m?t(S,{tone:"danger",centered:true,children:t(c,{testID:"permissions-error",children:m})}):null,x]})}function N({rows:e,platform:l,onOpen:h,onReload:d}){const[,f]=E(o=>o+1,0);const m=K();const g=e.filter(o=>o.stale&&o.changedAt!==null&&m-o.changedAt<$).map(o=>$-(m-o.changedAt));const s=g.length>0?Math.min(...g):null;_(()=>{if(s===null)return;const o=setTimeout(f,s+50);return()=>clearTimeout(o)},[s]);return t(y,{children:t(z,{children:e.map(o=>{const a=o.stale&&o.changedAt!==null&&m-o.changedAt>=$;return r(u,{children:[t(X,{row:o,platform:l,onPress:()=>h(o.id)}),a?r(u,{style:i.stale,testID:`permissions-stale-${o.id}`,children:[t(c,{style:i.staleText,children:"The app hasn't checked again since this changed."}),d?t(b,{testID:`permissions-reload-${o.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:d,hitSlop:{top:8,bottom:8,left:8,right:8},children:t(c,{style:i.staleAction,children:"Reload App"})}):null]}):null]},o.id)})})})}function X({row:e,platform:l,onPress:h}){const d=e.override!==null;const f=Q(e,l);const m=e.real?R(e.id,l,e.real):"Not Checked";return r(b,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${f}${d?`, simulated. Phone: ${m}`:""}`,activeOpacity:.6,onPress:h,style:i.row,children:[r(u,{style:i.rowLeft,children:[t(c,{style:i.rowTitle,children:e.label}),d?r(c,{style:i.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",m]}):null]}),r(u,{style:i.rowRight,children:[d?t(u,{style:i.dot}):null,t(c,{style:[i.rowValue,d?i.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:f}),t(H,{size:16,color:n.color.textTertiary})]})]})}function j({title:e,detail:l,selected:h,testID:d,onPress:f}){return r(b,{testID:d,accessibilityRole:"button",accessibilityLabel:`${e}. ${l}`,accessibilityState:{selected:h},activeOpacity:.6,onPress:f,style:i.option,children:[r(u,{style:i.optionText,children:[t(c,{style:i.rowTitle,children:e}),t(c,{style:i.optionDetail,children:l})]}),t(u,{style:i.check,children:h?t(U,{size:18,color:n.color.accent}):null})]})}const Z={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function ee({row:e,platform:l,log:h,run:d,onPicked:f}){const m=e.real?R(e.id,l,e.real):null;const g=a=>{if(a===null)d("clearOverride",{permission:e.id});else d("setOverride",{permission:e.id,state:a});f()};const s=h.filter(a=>a.permission===e.id).slice(0,8);const o=e.canRequestReal&&e.real==="undetermined";return r(B,{children:[r(u,{children:[t(C,{children:"What the app sees"}),t(y,{children:r(z,{children:[t(j,{title:"Phone's Setting",detail:m?`Use what the phone says: ${m}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>g(null)},"real"),e.states.map(a=>t(j,{title:R(e.id,l,a),detail:J(e.id,l,a),selected:e.override===a,testID:`permissions-state-${e.id}-${a}`,onPress:()=>g(a)},a))]})})]}),o?r(u,{children:[t(y,{children:t(b,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>d("requestReal",{permission:e.id}),style:i.row,children:t(c,{style:i.action,children:"Show Real Prompt"})})}),t(S,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?t(S,{tone:"warning",children:t(c,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,s.length>0?r(u,{children:[t(C,{children:"Recent"}),t(y,{children:t(z,{children:s.map(a=>t(ne,{entry:a,platform:l},a.id))})}),e.sources.length>0?r(S,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function te(e){const l=new Date(e);const h=d=>String(d).padStart(2,"0");return`${h(l.getHours())}:${h(l.getMinutes())}:${h(l.getSeconds())}`}function ne({entry:e,platform:l}){const h=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":R(e.permission,l,e.returned):"";return r(u,{style:i.recentRow,testID:`permissions-log-${e.id}`,children:[t(c,{style:i.recentTime,children:te(e.at)}),t(c,{style:i.recentVerb,numberOfLines:1,children:Z[e.kind]}),t(c,{style:[i.recentResult,e.error?i.recentFailed:null],numberOfLines:1,children:h})]})}const i=q.create({fill:{flex:1},content:{paddingHorizontal:n.gutter,paddingTop:12,gap:n.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:n.color.textSecondary,fontSize:n.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:n.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:n.color.text,fontSize:n.font.row},rowSub:{color:n.color.textTertiary,fontSize:n.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:n.color.textSecondary,fontSize:n.font.row},rowValueSimulated:{color:n.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:n.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:n.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:n.color.textSecondary,fontSize:n.font.caption,flexShrink:1},staleAction:{color:n.color.accent,fontSize:n.font.caption,fontWeight:"600"},destructive:{color:n.color.danger,fontSize:n.font.row},action:{color:n.color.accent,fontSize:n.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:n.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:n.color.textTertiary,fontSize:n.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:n.color.accent,fontSize:n.font.row},inlineTitle:{color:n.color.text,fontSize:n.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:n.rowPadH,paddingVertical:10},recentTime:{color:n.color.textTertiary,fontSize:n.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:n.color.text,fontSize:n.font.body,flex:1},recentResult:{color:n.color.textSecondary,fontSize:n.font.body},recentFailed:{color:n.color.danger}});
@@ -5,6 +5,8 @@ export interface PermissionsToolViewProps {
5
5
  onAction: PermissionsActionHandler;
6
6
  /** Reload the app's JS so every screen asks again. Hidden when absent. */
7
7
  onReload?: () => void;
8
+ /** A plain browser: nothing is patched, so say so instead of the list. */
9
+ browserOnly?: boolean;
8
10
  }
9
- export declare function PermissionsToolView({ snapshot, onAction, onReload }: PermissionsToolViewProps): import("react").JSX.Element;
11
+ export declare function PermissionsToolView({ snapshot, onAction, onReload, browserOnly }: PermissionsToolViewProps): import("react").JSX.Element;
10
12
  //# sourceMappingURL=PermissionsToolView.d.ts.map
package/lib/web/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- "use client";var Be=Object.defineProperty;var _t=Object.getOwnPropertyDescriptor;var Ut=Object.getOwnPropertyNames;var jt=Object.prototype.hasOwnProperty;var zt=(e,t)=>{for(var i in t)Be(e,i,{get:t[i],enumerable:true})},_e=(e,t,i,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ut(t))!jt.call(e,n)&&n!==i&&Be(e,n,{get:()=>t[n],enumerable:!(o=_t(t,n))||o.enumerable});return e},Ht=(e,t,i)=>(_e(e,t,"default"),i&&_e(i,t,"default"));var Ue=(()=>{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{callCapacitorNative as Ft,capacitorPlatform as Vt,emitCapacitorEvent as ie,hasCapacitorPlugin as Wt,loadCapacitorAppHost as Gt}from"@buoy-gg/license/web";function je(e){let t=e;if(!t?.coords||typeof t.coords.latitude!="number"||typeof t.coords.longitude!="number")return e;let i=o=>Math.round(o/.02)*.02;return{...t,coords:{...t.coords,latitude:Number(i(t.coords.latitude).toFixed(4)),longitude:Number(i(t.coords.longitude).toFixed(4)),accuracy:Math.max(t.coords.accuracy??0,3e3),altitude:null,altitudeAccuracy:null,heading:null,speed:null}}}import{callCapacitorNative as H,hasCapacitorPlugin as ze,installCapacitorBridge as Kt,interceptCapacitor as oe,makeCapacitorCallbackId as Yt}from"@buoy-gg/license/web";var ne=["undetermined","granted","limited","denied","blocked","restricted"],Jt=["ask","allow","limited","deny"],ye={location:{id:"location",label:"Location",limited:{ios:"Approximate",android:"Approximate"},purpose:"use your location"},locationBackground:{id:"locationBackground",label:"Background Location",purpose:"use your location in the background"},camera:{id:"camera",label:"Camera",purpose:"access your camera"},microphone:{id:"microphone",label:"Microphone",purpose:"access your microphone"},notifications:{id:"notifications",label:"Notifications",limited:{ios:"Provisional"},purpose:"send you notifications"},photos:{id:"photos",label:"Photos",limited:{ios:"Selected Photos",android:"Selected Photos"},purpose:"access your photos"},contacts:{id:"contacts",label:"Contacts",limited:{ios:"Selected Contacts"},purpose:"access your contacts"},calendar:{id:"calendar",label:"Calendar",purpose:"access your calendar"},reminders:{id:"reminders",label:"Reminders",only:"ios",purpose:"access your reminders"},tracking:{id:"tracking",label:"Tracking",only:"ios",purpose:"track your activity across other companies' apps and websites"},motion:{id:"motion",label:"Motion & Fitness",purpose:"access your motion and fitness activity"},bluetooth:{id:"bluetooth",label:"Bluetooth",purpose:"use Bluetooth"}},be=Object.keys(ye);function we(e){return typeof e=="string"&&(e in ye||e.startsWith("android:")&&e.length>8)}function R(e){let t=ye[e];if(t)return t;let i=e.slice(8).replace(/^android\.permission\./,"");return{id:e,label:i.toLowerCase().split("_").map(o=>o.charAt(0).toUpperCase()+o.slice(1)).join(" "),only:"android",purpose:`use ${i.toLowerCase().replace(/_/g," ")}`}}function re(e,t){let i=R(e),o=["undetermined","granted"];return i.limited?.[t]&&o.push("limited"),o.push("denied"),t==="android"&&o.push("blocked"),t==="ios"&&e!=="notifications"&&o.push("restricted"),o}function He(e,t,i){return re(e,t).includes(i)}function Fe(e,t,i){return He(e,t,i)?i:i==="blocked"?"denied":i==="restricted"?t==="android"?"blocked":"denied":i==="limited"?"granted":i}function Ve(e,t){return t==="undetermined"?true:e==="android"&&t==="denied"}function Zt(e,t,i,o){return Ve(t,i)?o==="allow"||o==="once"?"granted":o==="limited"?He(e,t,"limited")?"limited":"granted":t==="android"&&i==="denied"?"blocked":"denied":i}function We(e,t){return t==="ios"?e==="location":e==="camera"||e==="microphone"}function Xt(e,t){let i=R(e).limited?.[t],o=t==="ios",n=[];if(o&&We(e,t)&&n.push({answer:"once",label:"Allow Once"}),e==="location"||e==="locationBackground"?n.push({answer:"allow",label:o?"Allow While Using App":"While using the app"}):n.push({answer:"allow",label:"Allow"}),!o&&We(e,t)&&n.push({answer:"once",label:"Only this time"}),i){let r=e==="location"?o?"Allow With Approximate Location":"Approximate location":e==="photos"?o?"Limit Access\u2026":"Select photos":e==="contacts"?"Select Contacts\u2026":`Allow ${i}`;n.push({answer:"limited",label:r})}return n.push({answer:"deny",label:o?"Don\u2019t Allow":"Don\u2019t allow"}),n}function Qt(e,t,i){switch(i){case"undetermined":return"Never asked. The next request shows a prompt.";case"granted":return"Full access.";case"limited":return e==="location"?"Allowed, with an approximate position.":e==="photos"?"Allowed for the photos the person picked.":e==="contacts"?"Allowed for the contacts the person picked.":e==="notifications"?"Delivered quietly to Notification Center, without asking.":"Partial access.";case"denied":return t==="ios"?"The person said no. The app can't ask again, only send them to Settings.":"The person said no once. The app can ask one more time.";case"blocked":return"The person said no for good. Only Settings can change it.";case"restricted":return"Turned off by Screen Time or device management. The person can't change it."}}function ei(e,t){if(!e||typeof e!="object")return null;let i=e,o=typeof i.ios?.status=="number"?i.ios.status:void 0;return o===3||o===4?"limited":i.status==="granted"?i.accessPrivileges==="limited"||i.ios?.accuracy==="reduced"||i.android?.accuracy==="coarse"?"limited":"granted":i.status==="denied"?t==="android"&&i.canAskAgain===false?"blocked":"denied":i.status==="undetermined"?"undetermined":null}function N(e,t,i){switch(i){case"undetermined":return"Not Asked";case"granted":return"Allowed";case"limited":return R(e).limited?.[t]??"Limited";case"denied":return"Denied";case"blocked":return"Blocked";case"restricted":return"Restricted"}}var ti={location:"location",coarseLocation:"location",camera:"camera",photos:"photos",receive:"notifications",display:"notifications",notifications:"notifications",microphone:"microphone",contacts:"contacts",calendar:"calendar",reminders:"reminders",bluetooth:"bluetooth",motion:"motion",tracking:"tracking"};function F(e){return ti[e]??null}function ve(e,t){switch(e){case"granted":return"granted";case"limited":return"limited";case"prompt":return"undetermined";case"prompt-with-rationale":return t==="android"?"denied":"undetermined";case"denied":return t==="android"?"blocked":"denied";default:return null}}function ii(e,t){switch(e){case"granted":return"granted";case"limited":return"limited";case"undetermined":return"prompt";case"denied":return t==="android"?"prompt-with-rationale":"denied";case"blocked":case"restricted":return"denied"}}function V(e,t,i){if(e==="location"&&"location"in t){let o=ve(t.location,i),n=ve(t.coarseLocation,i);return o!=="granted"&&n==="granted"?"limited":o}for(let[o,n]of Object.entries(t))if(F(o)===e)return ve(n,i);return null}function Ge(e,t,i){let o={...e};for(let n of Object.keys(e)){let r=F(n);if(!r)continue;let a=t(r);a!==null&&(r==="location"&&a==="limited"?o[n]=n==="coarseLocation"||i==="ios"?"granted":"denied":a==="limited"&&r!=="photos"&&r!=="contacts"?o[n]="granted":o[n]=ii(a,i))}return o}import{devToolsStorageKeys as oi,persistentStorage as Ke}from"@buoy-gg/shared-ui/web";function ni(){try{let e=globalThis.localStorage;return e?Je(e.getItem(Ae)):void 0}catch{return}}var D={requestAnswer:"ask",persist:true,showChip:true,notifyApp:true,enforce:true,interceptSettings:true},Ae=oi.permissions.state();function W(e,t){return typeof e=="boolean"?e:t}function Ye(e){let t=e&&typeof e=="object"?e:{};return{requestAnswer:Jt.includes(t.requestAnswer)?t.requestAnswer:D.requestAnswer,persist:W(t.persist,D.persist),showChip:W(t.showChip,D.showChip),notifyApp:W(t.notifyApp,D.notifyApp),enforce:W(t.enforce,D.enforce),interceptSettings:W(t.interceptSettings,D.interceptSettings)}}function Je(e){if(!e)return null;try{let t=JSON.parse(e);if(!t||t.v!==1)return null;let i={};for(let[o,n]of Object.entries(t.overrides??{}))we(o)&&ne.includes(n)&&(i[o]=n);return{v:1,overrides:i,settings:Ye(t.settings)}}catch{return null}}async function ri(){try{return Je(await Ke.getItem(Ae))}catch{return null}}var Pe=Promise.resolve();function Ze(e){let t=JSON.stringify(e);return Pe=Pe.then(()=>Ke.setItem(Ae,t)).catch(()=>{}),Pe.then(()=>{})}var Xe=200,si=50,Qe="__buoyPermissionsStore",et=globalThis,s=et[Qe]??(et[Qe]={platform:"ios",booted:false,overrides:new Map,settings:{...D},seen:new Map,libraries:new Set,log:[],nextLogId:1,listeners:new Set,snapshot:null,prompter:null,changeHooks:new Set,realRequesters:new Map,host:{isSimulator:null,deviceName:null,bundleId:null},once:new Set});s.once??(s.once=new Set);var G=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function A(){s.snapshot=null;for(let e of Array.from(s.listeners))try{e()}catch{}}function B(){if(!s.settings.persist){Ze({v:1,overrides:{},settings:s.settings});return}Ze(ai())}function ai(){return{v:1,overrides:Object.fromEntries(Array.from(s.overrides,([e,t])=>[e,s.once.has(e)?"undetermined":t])),settings:s.settings}}function O(e){let t=s.seen.get(e);return t||(t={sources:new Set,real:null,calls:0,lastCallAt:null,lastReadAt:null,changedAt:null},s.seen.set(e,t)),t}function tt(e){if(e&&(s.settings=e.settings,s.overrides.clear(),!!e.settings.persist))for(let[t,i]of Object.entries(e.overrides)){let o=t;s.overrides.set(o,Fe(o,s.platform,i))}}function it(e){s.platform=e.platform,e.host&&(s.host=e.host),A()}function li(){if(s.booted)return;s.booted=true;let e=ni();if(e!==void 0){tt(e),A();return}ri().then(t=>{s.overrides.size>0||(tt(t),A())})}function ci(e,t){s.realRequesters.has(e)||s.realRequesters.set(e,t)}async function di(e){let t=Se(e),i=s.realRequesters.get(t);if(!i)throw new Error(`No installed library can ask the system for ${R(t).label}.`);let o=await i();return o!==null&&U(t,o),w()}function ui(e){s.prompter=e}function pi(e){return s.changeHooks.add(e),()=>s.changeHooks.delete(e)}function K(e,t){for(let i of Array.from(s.changeHooks))try{i({id:e,from:t})}catch{}}function mi(e,t){let i=!s.libraries.has(e);s.libraries.add(e);for(let o of t){let n=O(o);n.sources.has(e)||(n.sources.add(e),i=true)}i&&A()}function Y(){return s.platform}function _(){return s.settings}function E(e){return s.overrides.get(e)??null}function fi(e){return s.overrides.has(e)}function hi(){return s.overrides.size>0}function U(e,t,i){if(t===null)return;let o=O(e);i&&o.sources.add(i),o.real!==t&&(o.real=t,A())}function L(e){let t={...e,id:s.nextLogId++,at:G()};if(s.log.unshift(t),s.log.length>Xe&&(s.log.length=Xe),e.permission){let i=O(e.permission);(e.kind==="check"||e.kind==="request")&&i.sources.add(e.source),i.calls+=1,i.lastCallAt=t.at,(e.kind==="check"||e.kind==="request")&&(i.lastReadAt=t.at),e.real!==null&&e.kind!=="gated"&&(i.real=e.real)}return A(),t}async function gi(e){let t=s.overrides.get(e);if(t===void 0)throw new Error(`${e} is not overridden`);if(!Ve(s.platform,t))return{state:t};let i,o=s.settings.requestAnswer;o==="ask"&&s.prompter?i=await s.prompter(e):i=o==="ask"?"allow":o;let n=s.overrides.get(e);if(n===void 0)return{state:t,answer:i};let r=Zt(e,s.platform,n,i);return i==="once"&&r==="granted"&&s.once.add(e),r!==n&&(s.overrides.set(e,r),B(),A(),K(e,"request")),{state:r,answer:i}}function Se(e){if(!we(e))throw new Error(`Unknown permission "${String(e)}". Use one of: ${be.join(", ")}, or android:<android.permission.NAME>.`);return e}function ot(e,t){let i=Se(e);if(!ne.includes(t))throw new Error(`Unknown state "${String(t)}". Use one of: ${ne.join(", ")}.`);let o=t,n=re(i,s.platform),r=s.platform==="ios"&&o==="blocked"?"denied":o;if(!n.includes(r))throw new Error(`${R(i).label} can't be "${o}" on ${s.platform}. It can be: ${n.join(", ")}.`);return(s.overrides.get(i)!==r||s.once.has(i))&&(s.overrides.set(i,r),s.once.delete(i),O(i).changedAt=G(),B(),A(),K(i,"tool")),w()}function nt(e){let t=Se(e);return s.overrides.delete(t)&&(s.once.delete(t),O(t).changedAt=G(),B(),A(),K(t,"tool")),w()}function xe(){if(s.overrides.size>0){let e=G();for(let t of s.overrides.keys())O(t).changedAt=e;s.overrides.clear(),s.once.clear(),B(),A(),K(null,"tool")}return w()}function yi(){return Object.fromEntries(s.overrides)}function bi(e){let t=G();for(let i of s.overrides.keys())O(i).changedAt=t;s.overrides.clear(),s.once.clear();for(let[i,o]of Object.entries(e)){let n=i;!o||!we(n)||(s.overrides.set(n,Fe(n,s.platform,o)),O(n).changedAt=t)}return B(),A(),K(null,"tool"),w()}function rt(e){let t={};for(let[o,n]of Object.entries(e))n!==void 0&&(t[o]=n);if(t.requestAnswer!==void 0&&!["ask","allow","limited","deny"].includes(t.requestAnswer))throw new Error('requestAnswer must be "ask", "allow", "limited" or "deny".');let i=Ye({...s.settings,...t});return s.settings=i,B(),A(),w()}function wi(){s.log=[];for(let e of s.seen.values())e.calls=0,e.lastCallAt=null;return A(),w()}function vi(e,t){if(!e||!t)return null;let i=o=>o==="granted"||o==="limited";return i(e)&&!i(t)?"The phone hasn't allowed this, so calls that need it, like getting a position or a photo, still fail.":null}function w(){if(s.snapshot)return s.snapshot;let e=new Set([...s.seen.keys(),...s.overrides.keys()]),t=o=>{let n=be.indexOf(o);return n===-1?1e3:n},i=Array.from(e).filter(o=>{let n=R(o).only;return!n||n===s.platform}).sort((o,n)=>t(o)-t(n)||o.localeCompare(n)).map(o=>{let n=s.seen.get(o),r=s.overrides.get(o)??null,a=n?.real??null;return{id:o,label:R(o).label,states:re(o,s.platform),override:r,real:a,effective:r??a,sources:n?Array.from(n.sources).sort():[],calls:n?.calls??0,lastCallAt:n?.lastCallAt??null,lastReadAt:n?.lastReadAt??null,changedAt:n?.changedAt??null,stale:n?.changedAt!=null&&n.lastReadAt!=null&&n.lastReadAt<n.changedAt,once:s.once.has(o),warning:vi(r,a),canRequestReal:s.realRequesters.has(o)}});return s.snapshot={platform:s.platform,host:s.host,libraries:Array.from(s.libraries).sort(),permissions:i,overriddenCount:s.overrides.size,settings:s.settings,log:s.log.slice(0,si)},s.snapshot}function J(e){return s.listeners.add(e),()=>s.listeners.delete(e)}var se=10,ke=[{plugin:"Geolocation",library:"@capacitor/geolocation",aliases:{location:"location"}},{plugin:"Camera",library:"@capacitor/camera",aliases:{camera:"camera",photos:"photos"}},{plugin:"PushNotifications",library:"@capacitor/push-notifications",aliases:{notifications:"receive"}},{plugin:"LocalNotifications",library:"@capacitor/local-notifications",aliases:{notifications:"display"}}],Ai=[{plugin:"Geolocation",methods:["getCurrentPosition"],permission:()=>"location",message:()=>"Location permission was denied"},{plugin:"Camera",methods:["getPhoto","pickImages","pickLimitedLibraryPhotos"],permission:e=>e.source==="CAMERA"?"camera":"photos",message:e=>e==="camera"?"User denied access to camera":"User denied access to photos"}];function T(e){return ke.find(t=>t.plugin===e)?.library??`Capacitor ${e}`}var st=e=>e==="denied"||e==="blocked"||e==="restricted";function ae(e){let t=new Set;for(let i of Object.keys(e)){let o=F(i);o&&t.add(o)}return Array.from(t)}function q(e){return e&&typeof e=="object"?e:{}}var at=false;function Pi(){if(at)return true;if(!Kt())return false;at=true;let e=Y();oe({plugin:"*",methods:["checkPermissions"],order:se,promise:async(t,i)=>{let o=q(await i()),n=ae(o);if(n.length===0)return o;for(let r of n){let a=V(r,o,e);U(r,a,T(t.plugin));let c=E(r);L({source:T(t.plugin),method:`${t.plugin}.checkPermissions`,permission:r,kind:"check",real:a,returned:c??a,overridden:c!==null})}return Ge(o,E,e)}}),oe({plugin:"*",methods:["requestPermissions"],order:se,promise:async(t,i)=>{let o=Array.isArray(t.options.permissions)?t.options.permissions.map(String):null,n=l=>{let m=F(l);return m!==null&&E(m)!==null},r=o??Object.keys(q(await H(t.plugin,"checkPermissions").catch(()=>({}))));if(!r.some(n)){let l=q(await i());for(let m of ae(l)){let b=V(m,l,e);U(m,b,T(t.plugin)),L({source:T(t.plugin),method:`${t.plugin}.requestPermissions`,permission:m,kind:"request",real:b,returned:b,overridden:false})}return l}let a=r.filter(l=>!n(l)),c=a.length?q(await H(t.plugin,"requestPermissions",{...t.options,permissions:a})):q(await H(t.plugin,"checkPermissions").catch(()=>({})));for(let l of ae(c)){if(E(l)!==null)continue;let m=V(l,c,e);U(l,m,T(t.plugin)),L({source:T(t.plugin),method:`${t.plugin}.requestPermissions`,permission:l,kind:"request",real:m,returned:m,overridden:false})}let u=new Set;for(let l of r.filter(n)){let m=F(l);if(u.has(m))continue;u.add(m);let{state:b,answer:M}=await gi(m);L({source:T(t.plugin),method:`${t.plugin}.requestPermissions`,permission:m,kind:"request",real:null,returned:b,overridden:true,answer:M})}for(let l of r)l in c||(c={...c,[l]:"prompt"});return Ge(c,E,e)}});for(let t of Ai)oe({plugin:t.plugin,methods:t.methods,order:se,promise:(i,o)=>{let n=t.permission(i.options),r=E(n);if(_().enforce&&r==="limited"&&t.plugin==="Geolocation")return o().then(c=>je(c));if(!_().enforce||!st(r))return o();let a=t.message(n);return L({source:T(t.plugin),method:`${t.plugin}.${i.method}`,permission:n,kind:"gated",real:null,returned:r,overridden:true,error:a}),Promise.reject(new Error(a))}});oe({plugin:"Geolocation",methods:["watchPosition"],order:se,callback:(t,i,o)=>{let n=E("location");if(_().enforce&&n==="limited")return o((a,c)=>i(c?a:je(a),c));if(!_().enforce||!st(n))return o(i);let r="Location permission was denied";return L({source:T("Geolocation"),method:"Geolocation.watchPosition",permission:"location",kind:"gated",real:null,returned:n,overridden:true,error:r}),setTimeout(()=>i(null,new Error(r)),0),Yt()}});for(let t of ke){if(!ze(t.plugin))continue;let i=Object.keys(t.aliases);mi(t.library,i);for(let o of i){let n=t.aliases[o];ci(o,async()=>{let r=q(await H(t.plugin,"requestPermissions",{permissions:[n]})),a=V(o,r,e);return L({source:t.library,method:`${t.plugin}.requestPermissions (system)`,permission:o,kind:"request",real:a,returned:a,overridden:false}),a})}}return true}async function Si(){let e=Y();for(let t of ke)if(ze(t.plugin))try{let i=q(await H(t.plugin,"checkPermissions"));for(let o of ae(i))U(o,V(o,i,e),t.library)}catch{}}function Z(e,t,i,o){let n=e.createElement(t);return Object.assign(n.style,i),o!==void 0&&(n.textContent=o),n}var xi={alert(e,t,i,o){let n=globalThis.document;if(!n?.body){o?.onDismiss?.();return}let r=Z(n,"div",{position:"fixed",inset:"0",zIndex:"2147483000",background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",padding:"24px",fontFamily:"-apple-system, system-ui, Roboto, sans-serif"});r.setAttribute("role","alertdialog"),r.setAttribute("data-testid","buoy-permission-prompt");let a=Z(n,"div",{width:"100%",maxWidth:"290px",background:"#f2f2f7",color:"#000",borderRadius:"14px",overflow:"hidden",textAlign:"center"});a.appendChild(Z(n,"div",{padding:"18px 16px 4px",fontWeight:"600",fontSize:"17px",lineHeight:"22px"},e)),t&&a.appendChild(Z(n,"div",{padding:"0 16px 16px",fontSize:"13px",lineHeight:"18px",whiteSpace:"pre-line"},t));let c=false,u=()=>{c=true,r.remove()},l=i?.length?i:[{text:"OK"}];for(let m of l){let b=Z(n,"button",{display:"block",width:"100%",padding:"11px 8px",border:"0",borderTop:"0.5px solid rgba(60,60,67,0.29)",background:"transparent",color:"#007aff",fontSize:"17px",fontWeight:m.style==="cancel"?"600":"400",cursor:"pointer"},m.text);b.addEventListener("click",()=>{c||(u(),m.onPress?.())}),a.appendChild(b)}r.appendChild(a),o?.cancelable&&r.addEventListener("click",m=>{c||m.target!==r||(u(),o.onDismiss?.())}),n.body.appendChild(r)}};var Ie=null;function lt(e){Ie=e&&e.trim()?e.trim():null}function ct(){return Ie?{name:Ie}:null}function dt(){let e=ct()?.name;return typeof e=="string"&&e?e:"This app"}var ki={location:{plist:["NSLocationWhenInUseUsageDescription"],plugins:[["expo-location","locationWhenInUsePermission"]]},locationBackground:{plist:["NSLocationAlwaysAndWhenInUseUsageDescription"],plugins:[["expo-location","locationAlwaysAndWhenInUsePermission"]]},camera:{plist:["NSCameraUsageDescription"],plugins:[["expo-camera","cameraPermission"],["expo-image-picker","cameraPermission"]]},microphone:{plist:["NSMicrophoneUsageDescription"],plugins:[["expo-audio","microphonePermission"],["expo-camera","microphonePermission"],["expo-image-picker","microphonePermission"]]},photos:{plist:["NSPhotoLibraryUsageDescription"],plugins:[["expo-image-picker","photosPermission"],["expo-media-library","photosPermission"]]},contacts:{plist:["NSContactsUsageDescription"],plugins:[["expo-contacts","contactsPermission"]]},calendar:{plist:["NSCalendarsFullAccessUsageDescription","NSCalendarsUsageDescription"],plugins:[["expo-calendar","calendarPermission"]]},reminders:{plist:["NSRemindersFullAccessUsageDescription","NSRemindersUsageDescription"],plugins:[["expo-calendar","remindersPermission"]]},tracking:{plist:["NSUserTrackingUsageDescription"],plugins:[["expo-tracking-transparency","userTrackingPermission"]]},motion:{plist:["NSMotionUsageDescription"],plugins:[["expo-sensors","motionPermission"]]},bluetooth:{plist:["NSBluetoothAlwaysUsageDescription"],plugins:[]}};function Ii(e){let t=ki[e],i=ct();if(!t||!i)return null;let o=dt(),n=r=>typeof r=="string"&&r.trim()?r.replace(/\$\(PRODUCT_NAME\)/g,o).trim():null;for(let r of t.plist){let a=n(i.ios?.infoPlist?.[r]);if(a)return a}for(let[r,a]of t.plugins)for(let c of i.plugins??[])if(Array.isArray(c)&&c[0]===r&&c[1]&&typeof c[1]=="object"){let u=n(c[1][a]);if(u)return u}return null}var ut="Test prompt from Buoy. Your phone's settings won't change.",pt=Promise.resolve();function Ci(e){return t=>{let i=()=>new Promise(n=>{let r=Y(),a=R(t),c=dt(),u=r==="ios"?`Allow \u201C${c}\u201D to ${a.purpose}?`:`Allow ${c} to ${a.purpose}?`,l=Xt(t,r),m=false,b=C=>{m||(m=true,n(C))},M=r==="ios"?Ii(t):null;e.alert(u,M?`${M}
1
+ "use client";var je=Object.defineProperty;var Kt=Object.getOwnPropertyDescriptor;var Gt=Object.getOwnPropertyNames;var Yt=Object.prototype.hasOwnProperty;var Jt=(e,t)=>{for(var n in t)je(e,n,{get:t[n],enumerable:true})},ze=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Gt(t))!Yt.call(e,o)&&o!==n&&je(e,o,{get:()=>t[o],enumerable:!(i=Kt(t,o))||i.enumerable});return e},Zt=(e,t,n)=>(ze(e,t,"default"),n&&ze(n,t,"default"));var He=(()=>{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{callCapacitorNative as Xt,capacitorPlatform as Qt,emitCapacitorEvent as ie,hasCapacitorPlugin as en,loadCapacitorAppHost as tn}from"@buoy-gg/license/web";function Fe(e){let t=e;if(!t?.coords||typeof t.coords.latitude!="number"||typeof t.coords.longitude!="number")return e;let n=i=>Math.round(i/.02)*.02;return{...t,coords:{...t.coords,latitude:Number(n(t.coords.latitude).toFixed(4)),longitude:Number(n(t.coords.longitude).toFixed(4)),accuracy:Math.max(t.coords.accuracy??0,3e3),altitude:null,altitudeAccuracy:null,heading:null,speed:null}}}import{callCapacitorNative as F,hasCapacitorPlugin as Ve,installCapacitorBridge as nn,interceptCapacitor as oe,makeCapacitorCallbackId as on}from"@buoy-gg/license/web";var re=["undetermined","granted","limited","denied","blocked","restricted"],rn=["ask","allow","limited","deny"],we={location:{id:"location",label:"Location",limited:{ios:"Approximate",android:"Approximate"},purpose:"use your location"},locationBackground:{id:"locationBackground",label:"Background Location",purpose:"use your location in the background"},camera:{id:"camera",label:"Camera",purpose:"access your camera"},microphone:{id:"microphone",label:"Microphone",purpose:"access your microphone"},notifications:{id:"notifications",label:"Notifications",limited:{ios:"Provisional"},purpose:"send you notifications"},photos:{id:"photos",label:"Photos",limited:{ios:"Selected Photos",android:"Selected Photos"},purpose:"access your photos"},contacts:{id:"contacts",label:"Contacts",limited:{ios:"Selected Contacts"},purpose:"access your contacts"},calendar:{id:"calendar",label:"Calendar",purpose:"access your calendar"},reminders:{id:"reminders",label:"Reminders",only:"ios",purpose:"access your reminders"},tracking:{id:"tracking",label:"Tracking",only:"ios",purpose:"track your activity across other companies' apps and websites"},motion:{id:"motion",label:"Motion & Fitness",purpose:"access your motion and fitness activity"},bluetooth:{id:"bluetooth",label:"Bluetooth",purpose:"use Bluetooth"}},ve=Object.keys(we);function Ae(e){return typeof e=="string"&&(e in we||e.startsWith("android:")&&e.length>8)}function R(e){let t=we[e];if(t)return t;let n=e.slice(8).replace(/^android\.permission\./,"");return{id:e,label:n.toLowerCase().split("_").map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join(" "),only:"android",purpose:`use ${n.toLowerCase().replace(/_/g," ")}`}}function se(e,t){let n=R(e),i=["undetermined","granted"];return n.limited?.[t]&&i.push("limited"),i.push("denied"),t==="android"&&i.push("blocked"),t==="ios"&&e!=="notifications"&&i.push("restricted"),i}function We(e,t,n){return se(e,t).includes(n)}function Ke(e,t,n){return We(e,t,n)?n:n==="blocked"?"denied":n==="restricted"?t==="android"?"blocked":"denied":n==="limited"?"granted":n}function Ge(e,t){return t==="undetermined"?true:e==="android"&&t==="denied"}function sn(e,t,n,i){return Ge(t,n)?i==="allow"||i==="once"?"granted":i==="limited"?We(e,t,"limited")?"limited":"granted":t==="android"&&n==="denied"?"blocked":"denied":n}function Ye(e,t){return t==="ios"?e==="location":e==="camera"||e==="microphone"}function an(e,t){let n=R(e).limited?.[t],i=t==="ios",o=[];if(i&&Ye(e,t)&&o.push({answer:"once",label:"Allow Once"}),e==="location"||e==="locationBackground"?o.push({answer:"allow",label:i?"Allow While Using App":"While using the app"}):o.push({answer:"allow",label:"Allow"}),!i&&Ye(e,t)&&o.push({answer:"once",label:"Only this time"}),n){let r=e==="location"?i?"Allow With Approximate Location":"Approximate location":e==="photos"?i?"Limit Access\u2026":"Select photos":e==="contacts"?"Select Contacts\u2026":`Allow ${n}`;o.push({answer:"limited",label:r})}return o.push({answer:"deny",label:i?"Don\u2019t Allow":"Don\u2019t allow"}),o}function ln(e,t,n){switch(n){case"undetermined":return"Never asked. The next request shows a prompt.";case"granted":return"Full access.";case"limited":return e==="location"?"Allowed, with an approximate position.":e==="photos"?"Allowed for the photos the person picked.":e==="contacts"?"Allowed for the contacts the person picked.":e==="notifications"?"Delivered quietly to Notification Center, without asking.":"Partial access.";case"denied":return t==="ios"?"The person said no. The app can't ask again, only send them to Settings.":"The person said no once. The app can ask one more time.";case"blocked":return"The person said no for good. Only Settings can change it.";case"restricted":return"Turned off by Screen Time or device management. The person can't change it."}}function cn(e,t){if(!e||typeof e!="object")return null;let n=e,i=typeof n.ios?.status=="number"?n.ios.status:void 0;return i===3||i===4?"limited":n.status==="granted"?n.accessPrivileges==="limited"||n.ios?.accuracy==="reduced"||n.android?.accuracy==="coarse"?"limited":"granted":n.status==="denied"?t==="android"&&n.canAskAgain===false?"blocked":"denied":n.status==="undetermined"?"undetermined":null}function D(e,t,n){switch(n){case"undetermined":return"Not Asked";case"granted":return"Allowed";case"limited":return R(e).limited?.[t]??"Limited";case"denied":return"Denied";case"blocked":return"Blocked";case"restricted":return"Restricted"}}var dn={location:"location",coarseLocation:"location",camera:"camera",photos:"photos",receive:"notifications",display:"notifications",notifications:"notifications",microphone:"microphone",contacts:"contacts",calendar:"calendar",reminders:"reminders",bluetooth:"bluetooth",motion:"motion",tracking:"tracking"};function V(e){return dn[e]??null}function Se(e,t){switch(e){case"granted":return"granted";case"limited":return"limited";case"prompt":return"undetermined";case"prompt-with-rationale":return t==="android"?"denied":"undetermined";case"denied":return t==="android"?"blocked":"denied";default:return null}}function un(e,t){switch(e){case"granted":return"granted";case"limited":return"limited";case"undetermined":return"prompt";case"denied":return t==="android"?"prompt-with-rationale":"denied";case"blocked":case"restricted":return"denied"}}function W(e,t,n){if(e==="location"&&"location"in t){let i=Se(t.location,n),o=Se(t.coarseLocation,n);return i!=="granted"&&o==="granted"?"limited":i}for(let[i,o]of Object.entries(t))if(V(i)===e)return Se(o,n);return null}function Je(e,t,n){let i={...e};for(let o of Object.keys(e)){let r=V(o);if(!r)continue;let c=t(r);c!==null&&(r==="location"&&c==="limited"?i[o]=o==="coarseLocation"||n==="ios"?"granted":"denied":c==="limited"&&r!=="photos"&&r!=="contacts"?i[o]="granted":i[o]=un(c,n))}return i}import{devToolsStorageKeys as pn,persistentStorage as Ze}from"@buoy-gg/shared-ui/web";function mn(){try{let e=globalThis.localStorage;return e?Qe(e.getItem(Pe)):void 0}catch{return}}var q={requestAnswer:"ask",persist:true,showChip:true,notifyApp:true,enforce:true,interceptSettings:true},Pe=pn.permissions.state();function K(e,t){return typeof e=="boolean"?e:t}function Xe(e){let t=e&&typeof e=="object"?e:{};return{requestAnswer:rn.includes(t.requestAnswer)?t.requestAnswer:q.requestAnswer,persist:K(t.persist,q.persist),showChip:K(t.showChip,q.showChip),notifyApp:K(t.notifyApp,q.notifyApp),enforce:K(t.enforce,q.enforce),interceptSettings:K(t.interceptSettings,q.interceptSettings)}}function Qe(e){if(!e)return null;try{let t=JSON.parse(e);if(!t||t.v!==1)return null;let n={};for(let[i,o]of Object.entries(t.overrides??{}))Ae(i)&&re.includes(o)&&(n[i]=o);return{v:1,overrides:n,settings:Xe(t.settings)}}catch{return null}}async function fn(){try{return Qe(await Ze.getItem(Pe))}catch{return null}}var ke=Promise.resolve();function et(e){let t=JSON.stringify(e);return ke=ke.then(()=>Ze.setItem(Pe,t)).catch(()=>{}),ke.then(()=>{})}var tt=200,hn=50,nt="__buoyPermissionsStore",it=globalThis,s=it[nt]??(it[nt]={platform:"ios",booted:false,overrides:new Map,settings:{...q},seen:new Map,libraries:new Set,log:[],nextLogId:1,listeners:new Set,snapshot:null,prompter:null,changeHooks:new Set,realRequesters:new Map,host:{isSimulator:null,deviceName:null,bundleId:null},once:new Set});s.once??(s.once=new Set);var G=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function A(){s.snapshot=null;for(let e of Array.from(s.listeners))try{e()}catch{}}function B(){if(!s.settings.persist){et({v:1,overrides:{},settings:s.settings});return}et(gn())}function gn(){return{v:1,overrides:Object.fromEntries(Array.from(s.overrides,([e,t])=>[e,s.once.has(e)?"undetermined":t])),settings:s.settings}}function T(e){let t=s.seen.get(e);return t||(t={sources:new Set,real:null,calls:0,lastCallAt:null,lastReadAt:null,changedAt:null},s.seen.set(e,t)),t}function ot(e){if(e&&(s.settings=e.settings,s.overrides.clear(),!!e.settings.persist))for(let[t,n]of Object.entries(e.overrides)){let i=t;s.overrides.set(i,Ke(i,s.platform,n))}}function rt(e){s.platform=e.platform,e.host&&(s.host=e.host),A()}function yn(){if(s.booted)return;s.booted=true;let e=mn();if(e!==void 0){ot(e),A();return}fn().then(t=>{s.overrides.size>0||(ot(t),A())})}function bn(e,t){s.realRequesters.has(e)||s.realRequesters.set(e,t)}async function wn(e){let t=xe(e),n=s.realRequesters.get(t);if(!n)throw new Error(`No installed library can ask the system for ${R(t).label}.`);let i=await n();return i!==null&&U(t,i),w()}function vn(e){s.prompter=e}function An(e){return s.changeHooks.add(e),()=>s.changeHooks.delete(e)}function Y(e,t){for(let n of Array.from(s.changeHooks))try{n({id:e,from:t})}catch{}}function Sn(e,t){let n=!s.libraries.has(e);s.libraries.add(e);for(let i of t){let o=T(i);o.sources.has(e)||(o.sources.add(e),n=true)}n&&A()}function J(){return s.platform}function _(){return s.settings}function O(e){return s.overrides.get(e)??null}function Pn(e){return s.overrides.has(e)}function kn(){return s.overrides.size>0}function U(e,t,n){if(t===null)return;let i=T(e);n&&i.sources.add(n),i.real!==t&&(i.real=t,A())}function $(e){let t={...e,id:s.nextLogId++,at:G()};if(s.log.unshift(t),s.log.length>tt&&(s.log.length=tt),e.permission){let n=T(e.permission);(e.kind==="check"||e.kind==="request")&&n.sources.add(e.source),n.calls+=1,n.lastCallAt=t.at,(e.kind==="check"||e.kind==="request")&&(n.lastReadAt=t.at),e.real!==null&&e.kind!=="gated"&&(n.real=e.real)}return A(),t}async function xn(e){let t=s.overrides.get(e);if(t===void 0)throw new Error(`${e} is not overridden`);if(!Ge(s.platform,t))return{state:t};let n,i=s.settings.requestAnswer;i==="ask"&&s.prompter?n=await s.prompter(e):n=i==="ask"?"allow":i;let o=s.overrides.get(e);if(o===void 0)return{state:t,answer:n};let r=sn(e,s.platform,o,n);return n==="once"&&r==="granted"&&s.once.add(e),r!==o&&(s.overrides.set(e,r),B(),A(),Y(e,"request")),{state:r,answer:n}}function xe(e){if(!Ae(e))throw new Error(`Unknown permission "${String(e)}". Use one of: ${ve.join(", ")}, or android:<android.permission.NAME>.`);return e}function st(e,t){let n=xe(e);if(!re.includes(t))throw new Error(`Unknown state "${String(t)}". Use one of: ${re.join(", ")}.`);let i=t,o=se(n,s.platform),r=s.platform==="ios"&&i==="blocked"?"denied":i;if(!o.includes(r))throw new Error(`${R(n).label} can't be "${i}" on ${s.platform}. It can be: ${o.join(", ")}.`);return(s.overrides.get(n)!==r||s.once.has(n))&&(s.overrides.set(n,r),s.once.delete(n),T(n).changedAt=G(),B(),A(),Y(n,"tool")),w()}function at(e){let t=xe(e);return s.overrides.delete(t)&&(s.once.delete(t),T(t).changedAt=G(),B(),A(),Y(t,"tool")),w()}function Ce(){if(s.overrides.size>0){let e=G();for(let t of s.overrides.keys())T(t).changedAt=e;s.overrides.clear(),s.once.clear(),B(),A(),Y(null,"tool")}return w()}function Cn(){return Object.fromEntries(s.overrides)}function In(e){let t=G();for(let n of s.overrides.keys())T(n).changedAt=t;s.overrides.clear(),s.once.clear();for(let[n,i]of Object.entries(e)){let o=n;!i||!Ae(o)||(s.overrides.set(o,Ke(o,s.platform,i)),T(o).changedAt=t)}return B(),A(),Y(null,"tool"),w()}function lt(e){let t={};for(let[i,o]of Object.entries(e))o!==void 0&&(t[i]=o);if(t.requestAnswer!==void 0&&!["ask","allow","limited","deny"].includes(t.requestAnswer))throw new Error('requestAnswer must be "ask", "allow", "limited" or "deny".');let n=Xe({...s.settings,...t});return s.settings=n,B(),A(),w()}function Rn(){s.log=[];for(let e of s.seen.values())e.calls=0,e.lastCallAt=null;return A(),w()}function En(e,t){if(!e||!t)return null;let n=i=>i==="granted"||i==="limited";return n(e)&&!n(t)?"The phone hasn't allowed this, so calls that need it, like getting a position or a photo, still fail.":null}function w(){if(s.snapshot)return s.snapshot;let e=new Set([...s.seen.keys(),...s.overrides.keys()]),t=i=>{let o=ve.indexOf(i);return o===-1?1e3:o},n=Array.from(e).filter(i=>{let o=R(i).only;return!o||o===s.platform}).sort((i,o)=>t(i)-t(o)||i.localeCompare(o)).map(i=>{let o=s.seen.get(i),r=s.overrides.get(i)??null,c=o?.real??null;return{id:i,label:R(i).label,states:se(i,s.platform),override:r,real:c,effective:r??c,sources:o?Array.from(o.sources).sort():[],calls:o?.calls??0,lastCallAt:o?.lastCallAt??null,lastReadAt:o?.lastReadAt??null,changedAt:o?.changedAt??null,stale:o?.changedAt!=null&&o.lastReadAt!=null&&o.lastReadAt<o.changedAt,once:s.once.has(i),warning:En(r,c),canRequestReal:s.realRequesters.has(i)}});return s.snapshot={platform:s.platform,host:s.host,libraries:Array.from(s.libraries).sort(),permissions:n,overriddenCount:s.overrides.size,settings:s.settings,log:s.log.slice(0,hn)},s.snapshot}function Z(e){return s.listeners.add(e),()=>s.listeners.delete(e)}var ae=10,Ie=[{plugin:"Geolocation",library:"@capacitor/geolocation",aliases:{location:"location"}},{plugin:"Camera",library:"@capacitor/camera",aliases:{camera:"camera",photos:"photos"}},{plugin:"PushNotifications",library:"@capacitor/push-notifications",aliases:{notifications:"receive"}},{plugin:"LocalNotifications",library:"@capacitor/local-notifications",aliases:{notifications:"display"}}],Tn=[{plugin:"Geolocation",methods:["getCurrentPosition"],permission:()=>"location",message:()=>"Location permission was denied"},{plugin:"Camera",methods:["getPhoto","pickImages","pickLimitedLibraryPhotos"],permission:e=>e.source==="CAMERA"?"camera":"photos",message:e=>e==="camera"?"User denied access to camera":"User denied access to photos"}];function E(e){return Ie.find(t=>t.plugin===e)?.library??`Capacitor ${e}`}var ct=e=>e==="denied"||e==="blocked"||e==="restricted";function le(e){let t=new Set;for(let n of Object.keys(e)){let i=V(n);i&&t.add(i)}return Array.from(t)}function M(e){return e&&typeof e=="object"?e:{}}var dt=false;function On(){if(dt)return true;if(!nn())return false;dt=true;let e=J();oe({plugin:"*",methods:["checkPermissions"],order:ae,promise:async(t,n)=>{let i=M(await n()),o=le(i);if(o.length===0)return i;for(let r of o){let c=W(r,i,e);U(r,c,E(t.plugin));let a=O(r);$({source:E(t.plugin),method:`${t.plugin}.checkPermissions`,permission:r,kind:"check",real:c,returned:a??c,overridden:a!==null})}return Je(i,O,e)}}),oe({plugin:"*",methods:["requestPermissions"],order:ae,promise:async(t,n)=>{let i=Array.isArray(t.options.permissions)?t.options.permissions.map(String):null,o=d=>{let l=V(d);return l!==null&&O(l)!==null},r=i??Object.keys(M(await F(t.plugin,"checkPermissions").catch(()=>({}))));if(!r.some(o)){let d=M(await n());for(let l of le(d)){let y=W(l,d,e);U(l,y,E(t.plugin)),$({source:E(t.plugin),method:`${t.plugin}.requestPermissions`,permission:l,kind:"request",real:y,returned:y,overridden:false})}return d}let c=r.filter(d=>!o(d)),a=c.length?M(await F(t.plugin,"requestPermissions",{...t.options,permissions:c})):M(await F(t.plugin,"checkPermissions").catch(()=>({})));for(let d of le(a)){if(O(d)!==null)continue;let l=W(d,a,e);U(d,l,E(t.plugin)),$({source:E(t.plugin),method:`${t.plugin}.requestPermissions`,permission:d,kind:"request",real:l,returned:l,overridden:false})}let u=new Set;for(let d of r.filter(o)){let l=V(d);if(u.has(l))continue;u.add(l);let{state:y,answer:C}=await xn(l);$({source:E(t.plugin),method:`${t.plugin}.requestPermissions`,permission:l,kind:"request",real:null,returned:y,overridden:true,answer:C})}for(let d of r)d in a||(a={...a,[d]:"prompt"});return Je(a,O,e)}});for(let t of Tn)oe({plugin:t.plugin,methods:t.methods,order:ae,promise:(n,i)=>{let o=t.permission(n.options),r=O(o);if(_().enforce&&r==="limited"&&t.plugin==="Geolocation")return i().then(a=>Fe(a));if(!_().enforce||!ct(r))return i();let c=t.message(o);return $({source:E(t.plugin),method:`${t.plugin}.${n.method}`,permission:o,kind:"gated",real:null,returned:r,overridden:true,error:c}),Promise.reject(new Error(c))}});oe({plugin:"Geolocation",methods:["watchPosition"],order:ae,callback:(t,n,i)=>{let o=O("location");if(_().enforce&&o==="limited")return i((c,a)=>n(a?c:Fe(c),a));if(!_().enforce||!ct(o))return i(n);let r="Location permission was denied";return $({source:E("Geolocation"),method:"Geolocation.watchPosition",permission:"location",kind:"gated",real:null,returned:o,overridden:true,error:r}),setTimeout(()=>n(null,new Error(r)),0),on()}});for(let t of Ie){if(!Ve(t.plugin))continue;let n=Object.keys(t.aliases);Sn(t.library,n);for(let i of n){let o=t.aliases[i];bn(i,async()=>{let r=M(await F(t.plugin,"requestPermissions",{permissions:[o]})),c=W(i,r,e);return $({source:t.library,method:`${t.plugin}.requestPermissions (system)`,permission:i,kind:"request",real:c,returned:c,overridden:false}),c})}}return true}async function Nn(){let e=J();for(let t of Ie)if(Ve(t.plugin))try{let n=M(await F(t.plugin,"checkPermissions"));for(let i of le(n))U(i,W(i,n,e),t.library)}catch{}}function X(e,t,n,i){let o=e.createElement(t);return Object.assign(o.style,n),i!==void 0&&(o.textContent=i),o}var Ln={alert(e,t,n,i){let o=globalThis.document;if(!o?.body){i?.onDismiss?.();return}let r=X(o,"div",{position:"fixed",inset:"0",zIndex:"2147483000",background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",padding:"24px",fontFamily:"-apple-system, system-ui, Roboto, sans-serif"});r.setAttribute("role","alertdialog"),r.setAttribute("data-testid","buoy-permission-prompt");let c=X(o,"div",{width:"100%",maxWidth:"290px",background:"#f2f2f7",color:"#000",borderRadius:"14px",overflow:"hidden",textAlign:"center"});c.appendChild(X(o,"div",{padding:"18px 16px 4px",fontWeight:"600",fontSize:"17px",lineHeight:"22px"},e)),t&&c.appendChild(X(o,"div",{padding:"0 16px 16px",fontSize:"13px",lineHeight:"18px",whiteSpace:"pre-line"},t));let a=false,u=()=>{a=true,r.remove()},d=n?.length?n:[{text:"OK"}];for(let l of d){let y=X(o,"button",{display:"block",width:"100%",padding:"11px 8px",border:"0",borderTop:"0.5px solid rgba(60,60,67,0.29)",background:"transparent",color:"#007aff",fontSize:"17px",fontWeight:l.style==="cancel"?"600":"400",cursor:"pointer"},l.text);y.addEventListener("click",()=>{a||(u(),l.onPress?.())}),c.appendChild(y)}r.appendChild(c),i?.cancelable&&r.addEventListener("click",l=>{a||l.target!==r||(u(),i.onDismiss?.())}),o.body.appendChild(r)}};var Re=null;function ut(e){Re=e&&e.trim()?e.trim():null}function pt(){return Re?{name:Re}:null}function mt(){let e=pt()?.name;return typeof e=="string"&&e?e:"This app"}var Dn={location:{plist:["NSLocationWhenInUseUsageDescription"],plugins:[["expo-location","locationWhenInUsePermission"]]},locationBackground:{plist:["NSLocationAlwaysAndWhenInUseUsageDescription"],plugins:[["expo-location","locationAlwaysAndWhenInUsePermission"]]},camera:{plist:["NSCameraUsageDescription"],plugins:[["expo-camera","cameraPermission"],["expo-image-picker","cameraPermission"]]},microphone:{plist:["NSMicrophoneUsageDescription"],plugins:[["expo-audio","microphonePermission"],["expo-camera","microphonePermission"],["expo-image-picker","microphonePermission"]]},photos:{plist:["NSPhotoLibraryUsageDescription"],plugins:[["expo-image-picker","photosPermission"],["expo-media-library","photosPermission"]]},contacts:{plist:["NSContactsUsageDescription"],plugins:[["expo-contacts","contactsPermission"]]},calendar:{plist:["NSCalendarsFullAccessUsageDescription","NSCalendarsUsageDescription"],plugins:[["expo-calendar","calendarPermission"]]},reminders:{plist:["NSRemindersFullAccessUsageDescription","NSRemindersUsageDescription"],plugins:[["expo-calendar","remindersPermission"]]},tracking:{plist:["NSUserTrackingUsageDescription"],plugins:[["expo-tracking-transparency","userTrackingPermission"]]},motion:{plist:["NSMotionUsageDescription"],plugins:[["expo-sensors","motionPermission"]]},bluetooth:{plist:["NSBluetoothAlwaysUsageDescription"],plugins:[]}};function qn(e){let t=Dn[e],n=pt();if(!t||!n)return null;let i=mt(),o=r=>typeof r=="string"&&r.trim()?r.replace(/\$\(PRODUCT_NAME\)/g,i).trim():null;for(let r of t.plist){let c=o(n.ios?.infoPlist?.[r]);if(c)return c}for(let[r,c]of t.plugins)for(let a of n.plugins??[])if(Array.isArray(a)&&a[0]===r&&a[1]&&typeof a[1]=="object"){let u=o(a[1][c]);if(u)return u}return null}var ft="Test prompt from Buoy. Your phone's settings won't change.",ht=Promise.resolve();function $n(e){return t=>{let n=()=>new Promise(o=>{let r=J(),c=R(t),a=mt(),u=r==="ios"?`Allow \u201C${a}\u201D to ${c.purpose}?`:`Allow ${a} to ${c.purpose}?`,d=an(t,r),l=false,y=L=>{l||(l=true,o(L))},C=r==="ios"?qn(t):null;e.alert(u,C?`${C}
2
2
 
3
- ${ut}`:ut,l.map(C=>({text:C.label,style:C.answer==="deny"?"cancel":"default",onPress:()=>b(C.answer)})),{cancelable:r==="android",onDismiss:()=>b("deny")})}),o=pt.then(i,i);return pt=o.catch(()=>{}),o}}var mt="__buoyPermissionsInstalled";function Ri(){ie("App","appStateChange",{isActive:false}),ie("App","pause",{}),setTimeout(()=>{ie("App","resume",{}),ie("App","appStateChange",{isActive:true})},60)}function Ce(){let e=Vt();if(!e)return false;let t=globalThis;if(t[mt])return false;t[mt]=true,it({platform:e,host:{isSimulator:null,deviceName:null,bundleId:null}}),li(),ui(Ci(xi));let i=globalThis.document?.title??null;return lt(i),Wt("App")&&Ft("App","getInfo").then(o=>lt(o?.name??i)).catch(()=>{}),Pi()?(pi(({from:o})=>{o==="tool"&&_().notifyApp&&Ri()}),Gt().then(o=>{o&&it({platform:e,host:{isSimulator:o.isSimulator,deviceName:o.deviceName,bundleId:o.bundleId}})}),setTimeout(()=>{Si()},1500),true):false}import{useEffect as Ti,useSyncExternalStore as ft}from"react";var ht={};zt(ht,{AccessibilityInfo:()=>Di,ActivityIndicator:()=>To,Alert:()=>No,Animated:()=>Li,AppRegistry:()=>$i,AppState:()=>Mi,Appearance:()=>qi,BackHandler:()=>Bi,Button:()=>Oo,CheckBox:()=>eo,Clipboard:()=>_i,DeviceEventEmitter:()=>yo,Dimensions:()=>Ui,Easing:()=>ji,FlatList:()=>to,I18nManager:()=>zi,Image:()=>io,ImageBackground:()=>oo,InteractionManager:()=>Fi,Keyboard:()=>Hi,KeyboardAvoidingView:()=>no,LayoutAnimation:()=>Vi,Linking:()=>Wi,LogBox:()=>go,Modal:()=>Co,NativeEventEmitter:()=>Gi,NativeModules:()=>Ni,PanResponder:()=>Ki,Picker:()=>ro,PixelRatio:()=>Yi,Platform:()=>Ji,Pressable:()=>Io,ProgressBar:()=>so,RefreshControl:()=>ao,SafeAreaView:()=>lo,ScrollView:()=>gt,SectionList:()=>co,Share:()=>Zi,StatusBar:()=>uo,StyleSheet:()=>le,Switch:()=>Ro,Text:()=>h,TextInput:()=>So,Touchable:()=>po,TouchableHighlight:()=>xo,TouchableNativeFeedback:()=>mo,TouchableOpacity:()=>k,TouchableWithoutFeedback:()=>ko,UIManager:()=>Xi,Vibration:()=>Qi,View:()=>y,VirtualizedList:()=>fo,YellowBox:()=>ho,findNodeHandle:()=>Eo,unstable_createElement:()=>Ei,useColorScheme:()=>bo,useLocaleContext:()=>wo,useWindowDimensions:()=>vo});Ht(ht,Oi);import*as Oi from"react-native-web";import{unstable_createElement as Ei,NativeModules as Ni,AccessibilityInfo as Di,Animated as Li,Appearance as qi,AppRegistry as $i,AppState as Mi,BackHandler as Bi,Clipboard as _i,Dimensions as Ui,Easing as ji,I18nManager as zi,Keyboard as Hi,InteractionManager as Fi,LayoutAnimation as Vi,Linking as Wi,NativeEventEmitter as Gi,PanResponder as Ki,PixelRatio as Yi,Platform as Ji,Share as Zi,StyleSheet as le,UIManager as Xi,Vibration as Qi,CheckBox as eo,FlatList as to,Image as io,ImageBackground as oo,KeyboardAvoidingView as no,Picker as ro,ProgressBar as so,RefreshControl as ao,SafeAreaView as lo,SectionList as co,StatusBar as uo,Touchable as po,TouchableNativeFeedback as mo,VirtualizedList as fo,YellowBox as ho,LogBox as go,DeviceEventEmitter as yo,useColorScheme as bo,useLocaleContext as wo,useWindowDimensions as vo}from"react-native-web";import*as P from"react-native-web";import{createElement as Ao,forwardRef as Po}from"react";function x(e){let t=Po((o,n)=>{let{accessibilityState:r,accessibilityValue:a,...c}=o;for(let u of["busy","checked","disabled","expanded","selected"])r?.[u]!==void 0&&c[`aria-${u}`]===void 0&&(c[`aria-${u}`]=r[u]);for(let[u,l]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))a?.[u]!==void 0&&c[`aria-${l}`]===void 0&&(c[`aria-${l}`]=a[u]);return Ao(e,{...c,ref:n})}),i=e.State;return i&&Object.assign(t,{State:i}),t.displayName=e.displayName??e.name??"NativeWebView",t}var y=x(P.View),h=x(P.Text),So=x(P.TextInput),k=x(P.TouchableOpacity),xo=x(P.TouchableHighlight),ko=x(P.TouchableWithoutFeedback),Io=x(P.Pressable),gt=x(P.ScrollView),Co=x(P.Modal),Ro=x(P.Switch),To=x(P.ActivityIndicator),Oo=x(P.Button),Eo=P.findNodeHandle,No={alert(e,t,i,o){if(typeof document>"u")return;let n=document.createElement("dialog");n.dataset.buoyRoot="",n.setAttribute("aria-label",e),n.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 r=document.createElement("h2");if(r.textContent=e,r.style.cssText="font-size:18px;margin:0 0 12px",n.appendChild(r),t){let l=document.createElement("p");l.textContent=t,l.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",n.appendChild(l)}let a=document.createElement("div");a.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let c=i?.length?i:[{text:"OK"}],u=()=>{n.close?.(),n.remove()};for(let l of c){let m=document.createElement("button");m.type="button",m.textContent=l.text??"OK",m.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${l.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,m.onclick=()=>{u(),l.onPress?.()},a.appendChild(m)}n.addEventListener("cancel",l=>{l.preventDefault(),o?.cancelable!==false&&(u(),o?.onDismiss?.())}),n.appendChild(a),document.body.appendChild(n),n.showModal?n.showModal():n.setAttribute("open","")}};import{FloatingTool as yt,PermissionsIcon as bt,X as Do,dismissFloatingTool as Lo,getFloatingTools as qo,night as X,openBuoyTool as $o,openFloatingTool as wt}from"@buoy-gg/shared-ui/web";import{jsx as S,jsxs as Re}from"react/jsx-runtime";var ce="permissions-chip",Mo=8e3,vt={id:ce,render:e=>S(St,{...e})},Bo=()=>qo().some(e=>e.id===ce);function _o(){wt(vt)}var j=null,Te=new Set,de=()=>{};function ue(e){j&&clearTimeout(j.timer),j=e;for(let t of Array.from(Te))t();de()}function Uo(e){return Te.add(e),()=>{Te.delete(e)}}var At=()=>j;function jo(){ue({overrides:yi(),timer:setTimeout(()=>ue(null),Mo)}),xe()}function zo(){let e=j;e&&(ue(null),bi(e.overrides))}var Pt=false;function Ho(){if(Pt)return;Pt=true;let e=false;de=()=>{let t=(hi()||j!==null)&&_().showChip;t&&!e?wt(vt):!t&&Bo()&&Lo(ce),e=t},J(de),de()}function St({id:e,revealToken:t}){let i=ft(J,w,w),o=ft(Uo,At,At);Ti(()=>{o&&i.overriddenCount>0&&ue(null)},[o,i.overriddenCount]);let n=i.permissions.filter(c=>c.override!==null),r=n.length===1?n[0]:null,a=r?`${r.label}: ${r.once&&r.override==="granted"?"Allowed Once":N(r.id,i.platform,r.override)}`:`${n.length} permissions simulated`;return o&&n.length===0?S(yt,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:"Move or hide the permissions strip",handleAdornment:S(bt,{size:12}),children:Re(y,{style:I.row,children:[S(h,{style:I.title,numberOfLines:1,testID:"permissions-chip-summary",children:"Real permissions"}),S(k,{testID:"permissions-chip-undo",accessibilityRole:"button",accessibilityLabel:"Undo, put the simulated permissions back",onPress:zo,style:I.undo,hitSlop:{top:8,bottom:8,left:8,right:8},children:S(h,{style:I.undoText,children:"Undo"})})]})}):S(yt,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:`Move or hide the permissions strip. ${a}`,handleAdornment:S(bt,{size:12}),children:Re(y,{style:I.row,children:[Re(k,{testID:"permissions-chip-open",accessibilityRole:"button",accessibilityLabel:`${a}. Open Permissions`,onPress:()=>{$o("permissions")},style:I.open,children:[S(y,{style:I.dot}),S(h,{style:I.title,numberOfLines:1,testID:"permissions-chip-summary",children:a})]}),S(y,{style:I.separator}),S(k,{testID:"permissions-chip-reset",accessibilityRole:"button",accessibilityLabel:"Use real permissions",onPress:jo,style:I.button,hitSlop:{top:8,bottom:8,left:4,right:8},children:S(Do,{size:16,color:X.color.textSecondary})})]})})}var I=le.create({row:{flexDirection:"row",alignItems:"center",gap:10,paddingLeft:12,paddingRight:4,minHeight:40,minWidth:200},open:{flexDirection:"row",alignItems:"center",gap:8,flexShrink:1},dot:{width:7,height:7,borderRadius:4,backgroundColor:X.color.accent},title:{color:X.color.text,fontSize:14,fontWeight:"600",flexShrink:1},button:{width:32,height:32,alignItems:"center",justifyContent:"center",borderRadius:16},undo:{paddingHorizontal:12,paddingVertical:6},undoText:{color:X.color.accent,fontSize:14,fontWeight:"600"},separator:{width:le.hairlineWidth,height:20,backgroundColor:X.color.separator}});import{PermissionsIcon as Fo,PERMISSIONS_ICON_COLOR as Vo,createToolFactory as Wo,defineToolPreset as Go}from"@buoy-gg/shared-ui/web";import{useEffect as Ko,useSyncExternalStore as Yo}from"react";import{reloadApp as Jo}from"@buoy-gg/shared-ui/web";var Oe={ios:{code:"ERR_DENIED_FOREGROUND_LOCATION_PERMISSION",reason:"Location permission is required to do this operation"},android:{code:"ERR_LOCATION_UNAUTHORIZED",reason:"Not authorized to use location services"}},xt={ios:{code:"ERR_DENIED_BACKGROUND_LOCATION_PERMISSION",reason:"Background location permission is required to do this operation"},android:{code:"ERR_LOCATION_BACKGROUND_UNAUTHORIZED",reason:"Not authorized to use background location services"}},Zo=[{module:"ExpoLocation",library:"expo-location",permissions:[{get:"getForegroundPermissionsAsync",request:"requestForegroundPermissionsAsync",permission:"location",flavor:"location"},{get:"getBackgroundPermissionsAsync",request:"requestBackgroundPermissionsAsync",permission:"locationBackground",flavor:"locationBackground"},{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"location",flavor:"location"}],gated:[{method:"getCurrentPositionAsync",permission:"location",...Oe},{method:"getLastKnownPositionAsync",permission:"location",...Oe},{method:"watchPositionImplAsync",permission:"location",...Oe},{method:"startGeofencingAsync",permission:"locationBackground",...xt},{method:"startLocationUpdatesAsync",permission:"locationBackground",...xt}]},{module:"ExpoMaps",library:"expo-maps",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"location",flavor:"plain"}]},{module:"ExpoCamera",library:"expo-camera",permissions:[{get:"getCameraPermissionsAsync",request:"requestCameraPermissionsAsync",permission:"camera",flavor:"plain"},{get:"getMicrophonePermissionsAsync",request:"requestMicrophonePermissionsAsync",permission:"microphone",flavor:"plain"}]},{module:"ExpoNotificationPermissionsModule",library:"expo-notifications",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"notifications",flavor:"notifications",defaultArgs:e=>e==="ios"?[{allowAlert:true,allowBadge:true,allowSound:true}]:[void 0]}]},{module:"ExpoMediaLibrary",library:"expo-media-library",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"photos",flavor:"privileges",defaultArgs:()=>[false]}],gated:["getAssetsAsync","getAlbumsAsync","getAssetInfoAsync","createAssetAsync","saveToLibraryAsync"].map(e=>({method:e,permission:"photos",ios:{code:"ERR_MEDIA_LIBRARY_PERMISSIONS",reason:"Media Library permission is required to do this operation"}}))},{module:"ExponentImagePicker",library:"expo-image-picker",permissions:[{get:"getCameraPermissionsAsync",request:"requestCameraPermissionsAsync",permission:"camera",flavor:"plain"},{get:"getMediaLibraryPermissionsAsync",request:"requestMediaLibraryPermissionsAsync",permission:"photos",flavor:"privileges",defaultArgs:()=>[false]}],gated:[{method:"launchCameraAsync",permission:"camera",ios:{code:"ERR_MISSING_CAMERA_PERMISSION",reason:"Missing camera or camera roll permission"},android:{code:"ERR_USER_REJECTED_PERMISSIONS",reason:"User rejected permissions"}}]},{module:"ExpoContacts",library:"expo-contacts",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"contacts",flavor:"privileges"}]},{module:"ExpoCalendar",library:"expo-calendar",permissions:[{get:"getCalendarPermissionsAsync",request:"requestCalendarPermissionsAsync",permission:"calendar",flavor:"plain"},{get:"getRemindersPermissionsAsync",request:"requestRemindersPermissionsAsync",permission:"reminders",flavor:"plain"}]},{module:"CalendarNext",library:"expo-calendar",permissions:[{get:"getCalendarPermissions",request:"requestCalendarPermissions",permission:"calendar",flavor:"plain"},{get:"getRemindersPermissions",request:"requestRemindersPermissions",permission:"reminders",flavor:"plain"}]},{module:"ExpoTrackingTransparency",library:"expo-tracking-transparency",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"tracking",flavor:"plain"}]},{module:"ExpoAudio",library:"expo-audio",permissions:[{get:"getRecordingPermissionsAsync",request:"requestRecordingPermissionsAsync",permission:"microphone",flavor:"plain"}]},{module:"ExponentPedometer",library:"expo-sensors",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"motion",flavor:"plain"}]}];function Xo(){let e=globalThis.expo?.modules;return e&&typeof e=="object"?e:null}function Qo(e){try{return new Set(Object.keys(e))}catch{return new Set}}function en(e,t=[]){return e.flavor!=="privileges"?[]:t.length>0?t.slice(0,1):[false]}async function kt(){let e=Xo();if(!e)return;let t=Qo(e),i=Y(),o=[];for(let n of Zo){if(!t.has(n.module))continue;let r=e[n.module];if(!r)continue;let a=new Set;for(let c of n.permissions){if(a.has(c.permission))continue;let u=r[c.get],l=u?.__buoyPermissionsOriginal??u;typeof l=="function"&&(a.add(c.permission),o.push(Promise.resolve().then(()=>l.apply(r,en(c))).then(m=>U(c.permission,ei(m,i),n.library)).catch(()=>{})))}}await Promise.all(o)}import{createSyncAdapter as tn}from"@buoy-gg/shared-ui/web";import{BUOY_SYNTHETIC_MARK as on}from"@buoy-gg/shared-ui/web";var It=null;function Ee(e){try{It?.emit("appStateDidChange",{app_state:e,[on]:true})}catch{}}function nn(){Y()==="ios"&&Ee("inactive"),Ee("background")}function rn(){Ee("active")}var pe=null,Ct=false,Rt=null;function sn(){return Ct}function me(){return Rt?(Rt(),true):false}function an(){!It||Ct||(pe&&clearTimeout(pe),pe=setTimeout(()=>{pe=null,nn(),setTimeout(rn,60)},120))}function fe(e){return e&&typeof e=="object"?e:{}}function Ne(e){return e.permission??e.id??e.permissionId??e.name}function Q(e,t){let i=e[t];if(typeof i=="boolean")return i;if(i==="true")return true;if(i==="false")return false}var Tt=tn({version:1,getSnapshot(){return w()},subscribe(e){return J(e)},actions:{async getState(){return await kt(),sn()?{...w(),settingsStandInOpen:true}:w()},setOverride(e){let t=fe(e),i=Ne(t),o=t.state??t.status??t.value;if(i===void 0||o===void 0)throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").');return me(),ot(i,o)},clearOverride(e){let t=Ne(fe(e));if(t===void 0)throw new Error("clearOverride needs `permission`.");return me(),nt(t)},requestReal(e){let t=Ne(fe(e));if(t===void 0)throw new Error("requestReal needs `permission`.");return di(t)},resetAll(){return me(),xe()},updateSettings(e){let t=fe(e);return rt({requestAnswer:t.requestAnswer??t.answer,persist:Q(t,"persist"),showChip:Q(t,"showChip"),notifyApp:Q(t,"notifyApp"),enforce:Q(t,"enforce"),interceptSettings:Q(t,"interceptSettings")})},clearLog(){return wi()},simulateReturnFromSettings(){return me()||an(),w()}}});import{useEffect as ln,useReducer as cn,useState as Ot}from"react";import{Check as dn,ChevronLeft as un,ChevronRight as Et,NightCard as $,NightFootnote as z,NightRows as De,NightSectionLabel as Nt,night as p,useSafeAreaInsets as pn,useToolScreenHeader as mn}from"@buoy-gg/shared-ui/web";import{Fragment as Dt,jsx as d,jsxs as g}from"react/jsx-runtime";var Le=1500,fn=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function hn(e,t){return e.effective?e.once&&e.effective==="granted"?"Allowed Once":N(e.id,t,e.effective):"Not Checked"}function Lt({snapshot:e,onAction:t,onReload:i}){let o=pn({minBottom:16}),[n,r]=Ot(null),[a,c]=Ot({name:"list"}),u=(v,he)=>{r(null),t(v,he).catch(ge=>{r(ge instanceof Error?ge.message:String(ge))})},l=a.name==="detail"?e?.permissions.find(v=>v.id===a.id):void 0,m=()=>c(a.name==="detail"&&a.from==="other"?{name:"other"}:{name:"list"}),b=a.name==="other"?"Other Permissions":l?l.label:null,M=mn(b?{title:b,onBack:m,searchable:false}:null,[b,a.name,a.name==="detail"?a.from:null]);if(!e)return d(y,{style:f.waiting,testID:"permissions-waiting",children:d(z,{centered:true,children:"Waiting for the app\u2026"})});let{platform:C,permissions:qe}=e,$e=qe.filter(v=>v.calls>0||v.override!==null),ee=qe.filter(v=>!(v.calls>0||v.override!==null)),Me=(v,he)=>c({name:"detail",id:v,from:he}),te;return a.name==="detail"&&l?te=d(bn,{row:l,platform:C,log:e.log,run:u,onPicked:m}):a.name==="other"?te=g(y,{children:[d(qt,{rows:ee,platform:C,onOpen:v=>Me(v,"other")}),d(z,{children:"Your app can ask for these but hasn't yet."})]}):te=g(Dt,{children:[$e.length>0?d(qt,{rows:$e,platform:C,onOpen:v=>Me(v,"list"),onReload:i}):d($,{padded:true,children:d(h,{style:f.empty,testID:"permissions-empty",children:"Your app hasn't checked any permissions yet. Open a screen that uses location, the camera or notifications and it will show up here."})}),ee.length>0?d($,{children:g(k,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${ee.length}`,activeOpacity:.6,onPress:()=>c({name:"other"}),style:f.row,children:[d(h,{style:f.rowTitle,children:"Other Permissions"}),g(y,{style:f.rowRight,children:[d(h,{style:f.rowValue,children:ee.length}),d(Et,{size:16,color:p.color.textTertiary})]})]})}):null,e.overriddenCount>0?d($,{children:d(k,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>u("resetAll"),style:f.row,children:d(h,{style:f.destructive,children:"Use Real Permissions"})})}):null]}),g(gt,{style:f.fill,contentContainerStyle:[f.content,{paddingBottom:o.bottom}],testID:"permissions-scroll",children:[!M&&a.name!=="list"?g(k,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:m,style:f.inlineBack,children:[d(un,{size:18,color:p.color.accent}),d(h,{style:f.inlineBackText,children:a.name==="detail"&&a.from==="other"?"Other Permissions":"Permissions"}),b?d(h,{style:f.inlineTitle,children:b}):null]}):null,n?d(z,{tone:"danger",centered:true,children:d(h,{testID:"permissions-error",children:n})}):null,te]})}function qt({rows:e,platform:t,onOpen:i,onReload:o}){let[,n]=cn(u=>u+1,0),r=fn(),a=e.filter(u=>u.stale&&u.changedAt!==null&&r-u.changedAt<Le).map(u=>Le-(r-u.changedAt)),c=a.length>0?Math.min(...a):null;return ln(()=>{if(c===null)return;let u=setTimeout(n,c+50);return()=>clearTimeout(u)},[c]),d($,{children:d(De,{children:e.map(u=>{let l=u.stale&&u.changedAt!==null&&r-u.changedAt>=Le;return g(y,{children:[d(gn,{row:u,platform:t,onPress:()=>i(u.id)}),l?g(y,{style:f.stale,testID:`permissions-stale-${u.id}`,children:[d(h,{style:f.staleText,children:"The app hasn't checked again since this changed."}),o?d(k,{testID:`permissions-reload-${u.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:o,hitSlop:{top:8,bottom:8,left:8,right:8},children:d(h,{style:f.staleAction,children:"Reload App"})}):null]}):null]},u.id)})})})}function gn({row:e,platform:t,onPress:i}){let o=e.override!==null,n=hn(e,t),r=e.real?N(e.id,t,e.real):"Not Checked";return g(k,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${n}${o?`, simulated. Phone: ${r}`:""}`,activeOpacity:.6,onPress:i,style:f.row,children:[g(y,{style:f.rowLeft,children:[d(h,{style:f.rowTitle,children:e.label}),o?g(h,{style:f.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",r]}):null]}),g(y,{style:f.rowRight,children:[o?d(y,{style:f.dot}):null,d(h,{style:[f.rowValue,o?f.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:n}),d(Et,{size:16,color:p.color.textTertiary})]})]})}function $t({title:e,detail:t,selected:i,testID:o,onPress:n}){return g(k,{testID:o,accessibilityRole:"button",accessibilityLabel:`${e}. ${t}`,accessibilityState:{selected:i},activeOpacity:.6,onPress:n,style:f.option,children:[g(y,{style:f.optionText,children:[d(h,{style:f.rowTitle,children:e}),d(h,{style:f.optionDetail,children:t})]}),d(y,{style:f.check,children:i?d(dn,{size:18,color:p.color.accent}):null})]})}var yn={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function bn({row:e,platform:t,log:i,run:o,onPicked:n}){let r=e.real?N(e.id,t,e.real):null,a=l=>{l===null?o("clearOverride",{permission:e.id}):o("setOverride",{permission:e.id,state:l}),n()},c=i.filter(l=>l.permission===e.id).slice(0,8),u=e.canRequestReal&&e.real==="undetermined";return g(Dt,{children:[g(y,{children:[d(Nt,{children:"What the app sees"}),d($,{children:g(De,{children:[d($t,{title:"Phone's Setting",detail:r?`Use what the phone says: ${r}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>a(null)},"real"),e.states.map(l=>d($t,{title:N(e.id,t,l),detail:Qt(e.id,t,l),selected:e.override===l,testID:`permissions-state-${e.id}-${l}`,onPress:()=>a(l)},l))]})})]}),u?g(y,{children:[d($,{children:d(k,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>o("requestReal",{permission:e.id}),style:f.row,children:d(h,{style:f.action,children:"Show Real Prompt"})})}),d(z,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?d(z,{tone:"warning",children:d(h,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,c.length>0?g(y,{children:[d(Nt,{children:"Recent"}),d($,{children:d(De,{children:c.map(l=>d(vn,{entry:l,platform:t},l.id))})}),e.sources.length>0?g(z,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function wn(e){let t=new Date(e),i=o=>String(o).padStart(2,"0");return`${i(t.getHours())}:${i(t.getMinutes())}:${i(t.getSeconds())}`}function vn({entry:e,platform:t}){let i=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":N(e.permission,t,e.returned):"";return g(y,{style:f.recentRow,testID:`permissions-log-${e.id}`,children:[d(h,{style:f.recentTime,children:wn(e.at)}),d(h,{style:f.recentVerb,numberOfLines:1,children:yn[e.kind]}),d(h,{style:[f.recentResult,e.error?f.recentFailed:null],numberOfLines:1,children:i})]})}var f=le.create({fill:{flex:1},content:{paddingHorizontal:p.gutter,paddingTop:12,gap:p.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:p.color.textSecondary,fontSize:p.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:p.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:p.color.text,fontSize:p.font.row},rowSub:{color:p.color.textTertiary,fontSize:p.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:p.color.textSecondary,fontSize:p.font.row},rowValueSimulated:{color:p.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:p.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:p.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:p.color.textSecondary,fontSize:p.font.caption,flexShrink:1},staleAction:{color:p.color.accent,fontSize:p.font.caption,fontWeight:"600"},destructive:{color:p.color.danger,fontSize:p.font.row},action:{color:p.color.accent,fontSize:p.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:p.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:p.color.textTertiary,fontSize:p.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:p.color.accent,fontSize:p.font.row},inlineTitle:{color:p.color.text,fontSize:p.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:p.rowPadH,paddingVertical:10},recentTime:{color:p.color.textTertiary,fontSize:p.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:p.color.text,fontSize:p.font.body,flex:1},recentResult:{color:p.color.textSecondary,fontSize:p.font.body},recentFailed:{color:p.color.danger}});import{jsx as An}from"react/jsx-runtime";var Pn=Tt.actions;async function Sn(e,t){let i=Pn[e];if(!i)throw new Error(`Unknown permissions action: ${e}`);return i(t)}function xn(){Jo("auto","buoy permissions").catch(()=>{})}function Mt(){Ko(()=>{Ce(),kt()},[]);let e=Yo(J,w,w);return An(Lt,{snapshot:e,onAction:Sn,onReload:xn})}import{jsx as kn}from"react/jsx-runtime";var Bt=Go({id:"permissions",name:"PERMISSIONS",description:"Test denied, blocked, limited and not-asked permission states",slot:"both",color:Vo,icon:({size:e,color:t})=>kn(Fo,{size:e,color:t}),component:Mt,modal:{subtitle:"choose what the app is allowed to do"}}),In=Wo(Bt);import{PermissionsIcon as Cn,PERMISSIONS_ICON_COLOR as Rn}from"@buoy-gg/shared-ui/web";var Tn=typeof navigator<"u"&&navigator.product==="ReactNative",On=(()=>{try{return globalThis.Capacitor?.isNativePlatform?.()===true}catch{return false}})();(Tn||On)&&typeof Ue<"u"&&Ue&&(Ce(),Ho());export{be as KNOWN_PERMISSION_IDS,ce as PERMISSIONS_CHIP_ID,Rn as PERMISSIONS_ICON_COLOR,ne as PERMISSION_STATES,Mt as PermissionsBody,St as PermissionsChip,Cn as PermissionsIcon,Lt as PermissionsToolView,nt as clearPermissionOverride,In as createPermissionsTool,E as getPermissionOverride,w as getPermissionsSnapshot,Ce as installPermissions,fi as isPermissionOverridden,_o as openPermissionsChip,R as permissionInfo,Tt as permissionsSyncAdapter,Bt as permissionsToolPreset,xe as resetPermissions,ot as setPermissionOverride,N as stateLabel,J as subscribePermissions,re as supportedStates,rt as updatePermissionSettings};
3
+ ${ft}`:ft,d.map(L=>({text:L.label,style:L.answer==="deny"?"cancel":"default",onPress:()=>y(L.answer)})),{cancelable:r==="android",onDismiss:()=>y("deny")})}),i=ht.then(n,n);return ht=i.catch(()=>{}),i}}var gt="__buoyPermissionsInstalled";function Mn(){ie("App","appStateChange",{isActive:false}),ie("App","pause",{}),setTimeout(()=>{ie("App","resume",{}),ie("App","appStateChange",{isActive:true})},60)}function Ee(){let e=Qt();if(!e)return false;let t=globalThis;if(t[gt])return false;t[gt]=true,rt({platform:e,host:{isSimulator:null,deviceName:null,bundleId:null}}),yn(),vn($n(Ln));let n=globalThis.document?.title??null;return ut(n),en("App")&&Xt("App","getInfo").then(i=>ut(i?.name??n)).catch(()=>{}),On()?(An(({from:i})=>{i==="tool"&&_().notifyApp&&Mn()}),tn().then(i=>{i&&rt({platform:e,host:{isSimulator:i.isSimulator,deviceName:i.deviceName,bundleId:i.bundleId}})}),setTimeout(()=>{Nn()},1500),true):false}import{useEffect as Bn,useSyncExternalStore as yt}from"react";var bt={};Jt(bt,{AccessibilityInfo:()=>zn,ActivityIndicator:()=>zi,Alert:()=>Vi,Animated:()=>Hn,AppRegistry:()=>Vn,AppState:()=>Wn,Appearance:()=>Fn,BackHandler:()=>Kn,Button:()=>Hi,CheckBox:()=>li,Clipboard:()=>Gn,DeviceEventEmitter:()=>ki,Dimensions:()=>Yn,Easing:()=>Jn,FlatList:()=>ci,I18nManager:()=>Zn,Image:()=>di,ImageBackground:()=>ui,InteractionManager:()=>Qn,Keyboard:()=>Xn,KeyboardAvoidingView:()=>pi,LayoutAnimation:()=>ei,Linking:()=>ti,LogBox:()=>Pi,Modal:()=>Ui,NativeEventEmitter:()=>ni,NativeModules:()=>jn,PanResponder:()=>ii,Picker:()=>mi,PixelRatio:()=>oi,Platform:()=>wt,Pressable:()=>_i,ProgressBar:()=>fi,RefreshControl:()=>hi,SafeAreaView:()=>gi,ScrollView:()=>Pt,SectionList:()=>yi,Share:()=>ri,StatusBar:()=>bi,StyleSheet:()=>ce,Switch:()=>ji,Text:()=>h,TextInput:()=>$i,Touchable:()=>wi,TouchableHighlight:()=>Mi,TouchableNativeFeedback:()=>vi,TouchableOpacity:()=>x,TouchableWithoutFeedback:()=>Bi,UIManager:()=>si,Vibration:()=>ai,View:()=>b,VirtualizedList:()=>Ai,YellowBox:()=>Si,findNodeHandle:()=>Fi,unstable_createElement:()=>Un,useColorScheme:()=>xi,useLocaleContext:()=>Ci,useWindowDimensions:()=>Ii});Zt(bt,_n);import*as _n from"react-native-web";import{unstable_createElement as Un,NativeModules as jn,AccessibilityInfo as zn,Animated as Hn,Appearance as Fn,AppRegistry as Vn,AppState as Wn,BackHandler as Kn,Clipboard as Gn,Dimensions as Yn,Easing as Jn,I18nManager as Zn,Keyboard as Xn,InteractionManager as Qn,LayoutAnimation as ei,Linking as ti,NativeEventEmitter as ni,PanResponder as ii,PixelRatio as oi,Platform as wt,Share as ri,StyleSheet as ce,UIManager as si,Vibration as ai,CheckBox as li,FlatList as ci,Image as di,ImageBackground as ui,KeyboardAvoidingView as pi,Picker as mi,ProgressBar as fi,RefreshControl as hi,SafeAreaView as gi,SectionList as yi,StatusBar as bi,Touchable as wi,TouchableNativeFeedback as vi,VirtualizedList as Ai,YellowBox as Si,LogBox as Pi,DeviceEventEmitter as ki,useColorScheme as xi,useLocaleContext as Ci,useWindowDimensions as Ii}from"react-native-web";import*as S from"react-native-web";import{createElement as Te,forwardRef as vt,useCallback as Ri,useRef as Ei}from"react";import{useEffect as Ti,useState as Oi}from"react";import{createPortal as Ni}from"react-dom";var Li='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as Di}from"react/jsx-runtime";var Q=Symbol.for("@buoy-gg/portal-host"),At=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 St(){let e=document;if(e[Q])return e[Q].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:Li});let n=()=>{let l=document.fullscreenElement,y=l&&l.tagName!=="CANVAS"?l:document.body;t.parentElement!==y&&y.appendChild(t)},i=new Map,o=l=>{(!t.contains(l.target)||!At(l.target))&&i.set(l.code||l.key,{key:l.key,code:l.code,location:l.location,keyCode:l.keyCode,which:l.which,altKey:l.altKey,ctrlKey:l.ctrlKey,metaKey:l.metaKey,shiftKey:l.shiftKey})},r=l=>{i.delete(l.code||l.key)},c=()=>i.clear(),a=()=>{let l=[...i.values()];i.clear();for(let y of l)document.dispatchEvent(new KeyboardEvent("keyup",{...y,bubbles:true}))},u=l=>{At(l.target)&&l.stopPropagation()},d=l=>l.stopPropagation();return n(),document.addEventListener("fullscreenchange",n),document.addEventListener("keydown",o,true),document.addEventListener("keyup",r,true),window.addEventListener("blur",c),t.addEventListener("focusin",a),t.addEventListener("keydown",u),t.addEventListener("keyup",u),t.addEventListener("keypress",u),t.addEventListener("wheel",d,{passive:true}),e[Q]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",n),document.removeEventListener("keydown",o,true),document.removeEventListener("keyup",r,true),window.removeEventListener("blur",c),t.remove(),delete e[Q]}},t}function qi({children:e}){let[t,n]=Oi(null);return Ti(()=>{let i=St(),o=document[Q];return o.users++,n(i),()=>{--o.users===0&&o.dispose()}},[]),t?Ni(Di("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}function k(e){let t=vt((i,o)=>{let{accessibilityState:r,accessibilityValue:c,...a}=i;for(let u of["busy","checked","disabled","expanded","selected"])r?.[u]!==void 0&&a[`aria-${u}`]===void 0&&(a[`aria-${u}`]=r[u]);for(let[u,d]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))c?.[u]!==void 0&&a[`aria-${d}`]===void 0&&(a[`aria-${d}`]=c[u]);return Te(e,{...a,ref:o})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var b=k(S.View),h=k(S.Text),$i=k(S.TextInput),x=k(S.TouchableOpacity),Mi=k(S.TouchableHighlight),Bi=k(S.TouchableWithoutFeedback),_i=k(S.Pressable),Pt=k(S.ScrollView),kt=vt((e,t)=>{let n=Ei(null),i=Ri(o=>{if(o){let r=o;for(;r.parentElement&&r.parentElement!==document.body;)r=r.parentElement;r.parentElement===document.body&&(n.current=r,Object.assign(r.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),St().appendChild(r))}else n.current&&(document.body.appendChild(n.current),n.current=null);typeof t=="function"?t(o):t&&(t.current=o)},[t]);return Te(qi,null,Te(S.Modal,{...e,ref:i}))});kt.displayName="Modal";var Ui=k(kt),ji=k(S.Switch),zi=k(S.ActivityIndicator),Hi=k(S.Button),Fi=S.findNodeHandle,Vi={alert(e,t,n,i){if(typeof document>"u")return;let o=document.createElement("dialog");o.dataset.buoyRoot="",o.setAttribute("aria-label",e),o.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 r=document.createElement("h2");if(r.textContent=e,r.style.cssText="font-size:18px;margin:0 0 12px",o.appendChild(r),t){let d=document.createElement("p");d.textContent=t,d.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",o.appendChild(d)}let c=document.createElement("div");c.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let a=n?.length?n:[{text:"OK"}],u=()=>{o.close?.(),o.remove()};for(let d of a){let l=document.createElement("button");l.type="button",l.textContent=d.text??"OK",l.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${d.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,l.onclick=()=>{u(),d.onPress?.()},c.appendChild(l)}o.addEventListener("cancel",d=>{d.preventDefault(),i?.cancelable!==false&&(u(),i?.onDismiss?.())}),o.appendChild(c),document.body.appendChild(o),o.showModal?o.showModal():o.setAttribute("open","")}};import{FloatingTool as xt,PermissionsIcon as Ct,X as Wi,dismissFloatingTool as Ki,getFloatingTools as Gi,night as ee,openBuoyTool as Yi,openFloatingTool as It}from"@buoy-gg/shared-ui/web";import{jsx as P,jsxs as Oe}from"react/jsx-runtime";var de="permissions-chip",Ji=8e3,Rt={id:de,render:e=>P(Ot,{...e})},Zi=()=>Gi().some(e=>e.id===de);function Xi(){It(Rt)}var j=null,Ne=new Set,ue=()=>{};function pe(e){j&&clearTimeout(j.timer),j=e;for(let t of Array.from(Ne))t();ue()}function Qi(e){return Ne.add(e),()=>{Ne.delete(e)}}var Et=()=>j;function eo(){pe({overrides:Cn(),timer:setTimeout(()=>pe(null),Ji)}),Ce()}function to(){let e=j;e&&(pe(null),In(e.overrides))}var Tt=false;function no(){if(Tt)return;Tt=true;let e=false;ue=()=>{let t=(kn()||j!==null)&&_().showChip;t&&!e?It(Rt):!t&&Zi()&&Ki(de),e=t},Z(ue),ue()}function Ot({id:e,revealToken:t}){let n=yt(Z,w,w),i=yt(Qi,Et,Et);Bn(()=>{i&&n.overriddenCount>0&&pe(null)},[i,n.overriddenCount]);let o=n.permissions.filter(a=>a.override!==null),r=o.length===1?o[0]:null,c=r?`${r.label}: ${r.once&&r.override==="granted"?"Allowed Once":D(r.id,n.platform,r.override)}`:`${o.length} permissions simulated`;return i&&o.length===0?P(xt,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:"Move or hide the permissions strip",handleAdornment:P(Ct,{size:12}),children:Oe(b,{style:I.row,children:[P(h,{style:I.title,numberOfLines:1,testID:"permissions-chip-summary",children:"Real permissions"}),P(x,{testID:"permissions-chip-undo",accessibilityRole:"button",accessibilityLabel:"Undo, put the simulated permissions back",onPress:to,style:I.undo,hitSlop:{top:8,bottom:8,left:8,right:8},children:P(h,{style:I.undoText,children:"Undo"})})]})}):P(xt,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:`Move or hide the permissions strip. ${c}`,handleAdornment:P(Ct,{size:12}),children:Oe(b,{style:I.row,children:[Oe(x,{testID:"permissions-chip-open",accessibilityRole:"button",accessibilityLabel:`${c}. Open Permissions`,onPress:()=>{Yi("permissions")},style:I.open,children:[P(b,{style:I.dot}),P(h,{style:I.title,numberOfLines:1,testID:"permissions-chip-summary",children:c})]}),P(b,{style:I.separator}),P(x,{testID:"permissions-chip-reset",accessibilityRole:"button",accessibilityLabel:"Use real permissions",onPress:eo,style:I.button,hitSlop:{top:8,bottom:8,left:4,right:8},children:P(Wi,{size:16,color:ee.color.textSecondary})})]})})}var I=ce.create({row:{flexDirection:"row",alignItems:"center",gap:10,paddingLeft:12,paddingRight:4,minHeight:40,minWidth:200},open:{flexDirection:"row",alignItems:"center",gap:8,flexShrink:1},dot:{width:7,height:7,borderRadius:4,backgroundColor:ee.color.accent},title:{color:ee.color.text,fontSize:14,fontWeight:"600",flexShrink:1},button:{width:32,height:32,alignItems:"center",justifyContent:"center",borderRadius:16},undo:{paddingHorizontal:12,paddingVertical:6},undoText:{color:ee.color.accent,fontSize:14,fontWeight:"600"},separator:{width:ce.hairlineWidth,height:20,backgroundColor:ee.color.separator}});import{PermissionsIcon as io,PERMISSIONS_ICON_COLOR as oo,createToolFactory as ro,defineToolPreset as so}from"@buoy-gg/shared-ui/web";import{useEffect as ao,useState as lo,useSyncExternalStore as co}from"react";import{capacitorPlatform as uo}from"@buoy-gg/license/web";import{reloadApp as po}from"@buoy-gg/shared-ui/web";var Le={ios:{code:"ERR_DENIED_FOREGROUND_LOCATION_PERMISSION",reason:"Location permission is required to do this operation"},android:{code:"ERR_LOCATION_UNAUTHORIZED",reason:"Not authorized to use location services"}},Nt={ios:{code:"ERR_DENIED_BACKGROUND_LOCATION_PERMISSION",reason:"Background location permission is required to do this operation"},android:{code:"ERR_LOCATION_BACKGROUND_UNAUTHORIZED",reason:"Not authorized to use background location services"}},mo=[{module:"ExpoLocation",library:"expo-location",permissions:[{get:"getForegroundPermissionsAsync",request:"requestForegroundPermissionsAsync",permission:"location",flavor:"location"},{get:"getBackgroundPermissionsAsync",request:"requestBackgroundPermissionsAsync",permission:"locationBackground",flavor:"locationBackground"},{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"location",flavor:"location"}],gated:[{method:"getCurrentPositionAsync",permission:"location",...Le},{method:"getLastKnownPositionAsync",permission:"location",...Le},{method:"watchPositionImplAsync",permission:"location",...Le},{method:"startGeofencingAsync",permission:"locationBackground",...Nt},{method:"startLocationUpdatesAsync",permission:"locationBackground",...Nt}]},{module:"ExpoMaps",library:"expo-maps",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"location",flavor:"plain"}]},{module:"ExpoCamera",library:"expo-camera",permissions:[{get:"getCameraPermissionsAsync",request:"requestCameraPermissionsAsync",permission:"camera",flavor:"plain"},{get:"getMicrophonePermissionsAsync",request:"requestMicrophonePermissionsAsync",permission:"microphone",flavor:"plain"}]},{module:"ExpoNotificationPermissionsModule",library:"expo-notifications",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"notifications",flavor:"notifications",defaultArgs:e=>e==="ios"?[{allowAlert:true,allowBadge:true,allowSound:true}]:[void 0]}]},{module:"ExpoMediaLibrary",library:"expo-media-library",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"photos",flavor:"privileges",defaultArgs:()=>[false]}],gated:["getAssetsAsync","getAlbumsAsync","getAssetInfoAsync","createAssetAsync","saveToLibraryAsync"].map(e=>({method:e,permission:"photos",ios:{code:"ERR_MEDIA_LIBRARY_PERMISSIONS",reason:"Media Library permission is required to do this operation"}}))},{module:"ExponentImagePicker",library:"expo-image-picker",permissions:[{get:"getCameraPermissionsAsync",request:"requestCameraPermissionsAsync",permission:"camera",flavor:"plain"},{get:"getMediaLibraryPermissionsAsync",request:"requestMediaLibraryPermissionsAsync",permission:"photos",flavor:"privileges",defaultArgs:()=>[false]}],gated:[{method:"launchCameraAsync",permission:"camera",ios:{code:"ERR_MISSING_CAMERA_PERMISSION",reason:"Missing camera or camera roll permission"},android:{code:"ERR_USER_REJECTED_PERMISSIONS",reason:"User rejected permissions"}}]},{module:"ExpoContacts",library:"expo-contacts",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"contacts",flavor:"privileges"}]},{module:"ExpoCalendar",library:"expo-calendar",permissions:[{get:"getCalendarPermissionsAsync",request:"requestCalendarPermissionsAsync",permission:"calendar",flavor:"plain"},{get:"getRemindersPermissionsAsync",request:"requestRemindersPermissionsAsync",permission:"reminders",flavor:"plain"}]},{module:"CalendarNext",library:"expo-calendar",permissions:[{get:"getCalendarPermissions",request:"requestCalendarPermissions",permission:"calendar",flavor:"plain"},{get:"getRemindersPermissions",request:"requestRemindersPermissions",permission:"reminders",flavor:"plain"}]},{module:"ExpoTrackingTransparency",library:"expo-tracking-transparency",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"tracking",flavor:"plain"}]},{module:"ExpoAudio",library:"expo-audio",permissions:[{get:"getRecordingPermissionsAsync",request:"requestRecordingPermissionsAsync",permission:"microphone",flavor:"plain"}]},{module:"ExponentPedometer",library:"expo-sensors",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"motion",flavor:"plain"}]}];function fo(){let e=globalThis.expo?.modules;return e&&typeof e=="object"?e:null}function ho(e){try{return new Set(Object.keys(e))}catch{return new Set}}function go(e,t=[]){return e.flavor!=="privileges"?[]:t.length>0?t.slice(0,1):[false]}async function Lt(){let e=fo();if(!e)return;let t=ho(e),n=J(),i=[];for(let o of mo){if(!t.has(o.module))continue;let r=e[o.module];if(!r)continue;let c=new Set;for(let a of o.permissions){if(c.has(a.permission))continue;let u=r[a.get],d=u?.__buoyPermissionsOriginal??u;typeof d=="function"&&(c.add(a.permission),i.push(Promise.resolve().then(()=>d.apply(r,go(a))).then(l=>U(a.permission,cn(l,n),o.library)).catch(()=>{})))}}await Promise.all(i)}import{createSyncAdapter as yo}from"@buoy-gg/shared-ui/web";import{BUOY_SYNTHETIC_MARK as bo}from"@buoy-gg/shared-ui/web";var Dt=null;function De(e){try{Dt?.emit("appStateDidChange",{app_state:e,[bo]:true})}catch{}}function wo(){J()==="ios"&&De("inactive"),De("background")}function vo(){De("active")}var me=null,qt=false,$t=null;function Ao(){return qt}function fe(){return $t?($t(),true):false}function So(){!Dt||qt||(me&&clearTimeout(me),me=setTimeout(()=>{me=null,wo(),setTimeout(vo,60)},120))}function he(e){return e&&typeof e=="object"?e:{}}function qe(e){return e.permission??e.id??e.permissionId??e.name}function te(e,t){let n=e[t];if(typeof n=="boolean")return n;if(n==="true")return true;if(n==="false")return false}var Mt=yo({version:1,getSnapshot(){return w()},subscribe(e){return Z(e)},actions:{async getState(){return await Lt(),Ao()?{...w(),settingsStandInOpen:true}:w()},setOverride(e){let t=he(e),n=qe(t),i=t.state??t.status??t.value;if(n===void 0||i===void 0)throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").');return fe(),st(n,i)},clearOverride(e){let t=qe(he(e));if(t===void 0)throw new Error("clearOverride needs `permission`.");return fe(),at(t)},requestReal(e){let t=qe(he(e));if(t===void 0)throw new Error("requestReal needs `permission`.");return wn(t)},resetAll(){return fe(),Ce()},updateSettings(e){let t=he(e);return lt({requestAnswer:t.requestAnswer??t.answer,persist:te(t,"persist"),showChip:te(t,"showChip"),notifyApp:te(t,"notifyApp"),enforce:te(t,"enforce"),interceptSettings:te(t,"interceptSettings")})},clearLog(){return Rn()},simulateReturnFromSettings(){return fe()||So(),w()}}});import{useEffect as Po,useReducer as ko,useState as Bt}from"react";import{Check as xo,ChevronLeft as Co,ChevronRight as _t,NightCard as N,NightFootnote as z,NightRows as $e,NightSectionLabel as Ut,night as m,useSafeAreaInsets as Io,useToolScreenHeader as Ro}from"@buoy-gg/shared-ui/web";import{Fragment as jt,jsx as p,jsxs as g}from"react/jsx-runtime";var Me=1500,Eo=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function To(e,t){return e.effective?e.once&&e.effective==="granted"?"Allowed Once":D(e.id,t,e.effective):"Not Checked"}function zt({snapshot:e,onAction:t,onReload:n,browserOnly:i}){let o=Io({minBottom:16}),[r,c]=Bt(null),[a,u]=Bt({name:"list"}),d=(v,ye)=>{c(null),t(v,ye).catch(be=>{c(be instanceof Error?be.message:String(be))})},l=a.name==="detail"?e?.permissions.find(v=>v.id===a.id):void 0,y=()=>u(a.name==="detail"&&a.from==="other"?{name:"other"}:{name:"list"}),C=a.name==="other"?"Other Permissions":l?l.label:null,L=Ro(C?{title:C,onBack:y,searchable:false}:null,[C,a.name,a.name==="detail"?a.from:null]);if(!e)return p(b,{style:f.waiting,testID:"permissions-waiting",children:p(z,{centered:true,children:"Waiting for the app\u2026"})});let{platform:ge,permissions:Be}=e,_e=Be.filter(v=>v.calls>0||v.override!==null),ne=Be.filter(v=>!(v.calls>0||v.override!==null)),Ue=(v,ye)=>u({name:"detail",id:v,from:ye}),H;return i?H=p(N,{padded:true,children:p(h,{style:f.empty,testID:"permissions-browser-only",children:"This app runs in a plain browser. The browser keeps its own permissions. Buoy can't change them here. This tool works when the app runs on a phone with Capacitor."})}):a.name==="detail"&&l?H=p(Lo,{row:l,platform:ge,log:e.log,run:d,onPicked:y}):a.name==="other"?H=g(b,{children:[p(Ht,{rows:ne,platform:ge,onOpen:v=>Ue(v,"other")}),p(z,{children:"Your app can ask for these but hasn't yet."})]}):H=g(jt,{children:[_e.length>0?p(Ht,{rows:_e,platform:ge,onOpen:v=>Ue(v,"list"),onReload:n}):p(N,{padded:true,children:p(h,{style:f.empty,testID:"permissions-empty",children:"Your app hasn't checked any permissions yet. Open a screen that uses location, the camera or notifications and it will show up here."})}),ne.length>0?p(N,{children:g(x,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${ne.length}`,activeOpacity:.6,onPress:()=>u({name:"other"}),style:f.row,children:[p(h,{style:f.rowTitle,children:"Other Permissions"}),g(b,{style:f.rowRight,children:[p(h,{style:f.rowValue,children:ne.length}),p(_t,{size:16,color:m.color.textTertiary})]})]})}):null,e.overriddenCount>0?p(N,{children:p(x,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>d("resetAll"),style:f.row,children:p(h,{style:f.destructive,children:"Use Real Permissions"})})}):null]}),g(Pt,{style:f.fill,contentContainerStyle:[f.content,{paddingBottom:o.bottom}],testID:"permissions-scroll",children:[!L&&a.name!=="list"?g(x,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:y,style:f.inlineBack,children:[p(Co,{size:18,color:m.color.accent}),p(h,{style:f.inlineBackText,children:a.name==="detail"&&a.from==="other"?"Other Permissions":"Permissions"}),C?p(h,{style:f.inlineTitle,children:C}):null]}):null,r?p(z,{tone:"danger",centered:true,children:p(h,{testID:"permissions-error",children:r})}):null,H]})}function Ht({rows:e,platform:t,onOpen:n,onReload:i}){let[,o]=ko(u=>u+1,0),r=Eo(),c=e.filter(u=>u.stale&&u.changedAt!==null&&r-u.changedAt<Me).map(u=>Me-(r-u.changedAt)),a=c.length>0?Math.min(...c):null;return Po(()=>{if(a===null)return;let u=setTimeout(o,a+50);return()=>clearTimeout(u)},[a]),p(N,{children:p($e,{children:e.map(u=>{let d=u.stale&&u.changedAt!==null&&r-u.changedAt>=Me;return g(b,{children:[p(Oo,{row:u,platform:t,onPress:()=>n(u.id)}),d?g(b,{style:f.stale,testID:`permissions-stale-${u.id}`,children:[p(h,{style:f.staleText,children:"The app hasn't checked again since this changed."}),i?p(x,{testID:`permissions-reload-${u.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:i,hitSlop:{top:8,bottom:8,left:8,right:8},children:p(h,{style:f.staleAction,children:"Reload App"})}):null]}):null]},u.id)})})})}function Oo({row:e,platform:t,onPress:n}){let i=e.override!==null,o=To(e,t),r=e.real?D(e.id,t,e.real):"Not Checked";return g(x,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${o}${i?`, simulated. Phone: ${r}`:""}`,activeOpacity:.6,onPress:n,style:f.row,children:[g(b,{style:f.rowLeft,children:[p(h,{style:f.rowTitle,children:e.label}),i?g(h,{style:f.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",r]}):null]}),g(b,{style:f.rowRight,children:[i?p(b,{style:f.dot}):null,p(h,{style:[f.rowValue,i?f.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:o}),p(_t,{size:16,color:m.color.textTertiary})]})]})}function Ft({title:e,detail:t,selected:n,testID:i,onPress:o}){return g(x,{testID:i,accessibilityRole:"button",accessibilityLabel:`${e}. ${t}`,accessibilityState:{selected:n},activeOpacity:.6,onPress:o,style:f.option,children:[g(b,{style:f.optionText,children:[p(h,{style:f.rowTitle,children:e}),p(h,{style:f.optionDetail,children:t})]}),p(b,{style:f.check,children:n?p(xo,{size:18,color:m.color.accent}):null})]})}var No={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function Lo({row:e,platform:t,log:n,run:i,onPicked:o}){let r=e.real?D(e.id,t,e.real):null,c=d=>{d===null?i("clearOverride",{permission:e.id}):i("setOverride",{permission:e.id,state:d}),o()},a=n.filter(d=>d.permission===e.id).slice(0,8),u=e.canRequestReal&&e.real==="undetermined";return g(jt,{children:[g(b,{children:[p(Ut,{children:"What the app sees"}),p(N,{children:g($e,{children:[p(Ft,{title:"Phone's Setting",detail:r?`Use what the phone says: ${r}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>c(null)},"real"),e.states.map(d=>p(Ft,{title:D(e.id,t,d),detail:ln(e.id,t,d),selected:e.override===d,testID:`permissions-state-${e.id}-${d}`,onPress:()=>c(d)},d))]})})]}),u?g(b,{children:[p(N,{children:p(x,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>i("requestReal",{permission:e.id}),style:f.row,children:p(h,{style:f.action,children:"Show Real Prompt"})})}),p(z,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?p(z,{tone:"warning",children:p(h,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,a.length>0?g(b,{children:[p(Ut,{children:"Recent"}),p(N,{children:p($e,{children:a.map(d=>p(qo,{entry:d,platform:t},d.id))})}),e.sources.length>0?g(z,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function Do(e){let t=new Date(e),n=i=>String(i).padStart(2,"0");return`${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}function qo({entry:e,platform:t}){let n=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":D(e.permission,t,e.returned):"";return g(b,{style:f.recentRow,testID:`permissions-log-${e.id}`,children:[p(h,{style:f.recentTime,children:Do(e.at)}),p(h,{style:f.recentVerb,numberOfLines:1,children:No[e.kind]}),p(h,{style:[f.recentResult,e.error?f.recentFailed:null],numberOfLines:1,children:n})]})}var f=ce.create({fill:{flex:1},content:{paddingHorizontal:m.gutter,paddingTop:12,gap:m.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:m.color.textSecondary,fontSize:m.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:m.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:m.color.text,fontSize:m.font.row},rowSub:{color:m.color.textTertiary,fontSize:m.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:m.color.textSecondary,fontSize:m.font.row},rowValueSimulated:{color:m.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:m.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:m.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:m.color.textSecondary,fontSize:m.font.caption,flexShrink:1},staleAction:{color:m.color.accent,fontSize:m.font.caption,fontWeight:"600"},destructive:{color:m.color.danger,fontSize:m.font.row},action:{color:m.color.accent,fontSize:m.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:m.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:m.color.textTertiary,fontSize:m.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:m.color.accent,fontSize:m.font.row},inlineTitle:{color:m.color.text,fontSize:m.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:m.rowPadH,paddingVertical:10},recentTime:{color:m.color.textTertiary,fontSize:m.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:m.color.text,fontSize:m.font.body,flex:1},recentResult:{color:m.color.textSecondary,fontSize:m.font.body},recentFailed:{color:m.color.danger}});import{jsx as $o}from"react/jsx-runtime";var Mo=Mt.actions;async function Bo(e,t){let n=Mo[e];if(!n)throw new Error(`Unknown permissions action: ${e}`);return n(t)}function _o(){po("auto","buoy permissions").catch(()=>{})}function Vt(){let[e]=lo(()=>wt.OS==="web"&&!uo());ao(()=>{Ee(),Lt()},[]);let t=co(Z,w,w);return $o(zt,{snapshot:t,onAction:Bo,onReload:_o,browserOnly:e})}import{jsx as Uo}from"react/jsx-runtime";var Wt=so({id:"permissions",name:"PERMISSIONS",description:"Test denied, blocked, limited and not-asked permission states",slot:"both",color:oo,icon:({size:e,color:t})=>Uo(io,{size:e,color:t}),component:Vt,modal:{subtitle:"choose what the app is allowed to do"}}),jo=ro(Wt);import{PermissionsIcon as zo,PERMISSIONS_ICON_COLOR as Ho}from"@buoy-gg/shared-ui/web";var Fo=typeof navigator<"u"&&navigator.product==="ReactNative",Vo=(()=>{try{return globalThis.Capacitor?.isNativePlatform?.()===true}catch{return false}})();(Fo||Vo)&&typeof He<"u"&&He&&(Ee(),no());export{ve as KNOWN_PERMISSION_IDS,de as PERMISSIONS_CHIP_ID,Ho as PERMISSIONS_ICON_COLOR,re as PERMISSION_STATES,Vt as PermissionsBody,Ot as PermissionsChip,zo as PermissionsIcon,zt as PermissionsToolView,at as clearPermissionOverride,jo as createPermissionsTool,O as getPermissionOverride,w as getPermissionsSnapshot,Ee as installPermissions,Pn as isPermissionOverridden,Xi as openPermissionsChip,R as permissionInfo,Mt as permissionsSyncAdapter,Wt as permissionsToolPreset,Ce as resetPermissions,st as setPermissionOverride,D as stateLabel,Z as subscribePermissions,se as supportedStates,lt as updatePermissionSettings};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/permissions",
3
- "version": "7.0.63",
3
+ "version": "7.0.64",
4
4
  "description": "Permission state overrides for React Native: make your app see not asked, allowed, limited, denied or blocked for location, camera, notifications and more, without touching device settings. Works with Expo modules, PermissionsAndroid and react-native-permissions.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -17,17 +17,17 @@
17
17
  "./lib/web/**/*.mjs"
18
18
  ],
19
19
  "dependencies": {
20
- "@buoy-gg/shared-ui": "^7.0.63"
20
+ "@buoy-gg/shared-ui": "^7.0.64"
21
21
  },
22
22
  "peerDependencies": {
23
- "@buoy-gg/license": "7.0.63",
23
+ "@buoy-gg/license": "7.0.64",
24
24
  "react": "*"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/react": "^19.1.0",
28
28
  "@types/react-native": "^0.73.0",
29
29
  "typescript": "~5.8.3",
30
- "@buoy-gg/license": "^7.0.63"
30
+ "@buoy-gg/license": "^7.0.64"
31
31
  },
32
32
  "react-native-builder-bob": {
33
33
  "source": "src",