@stacksjs/mobile 0.75.97 → 0.75.98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/bridge.d.ts +90 -0
- package/dist/controls.d.ts +41 -0
- package/dist/events.d.ts +28 -0
- package/dist/gestures.d.ts +38 -2
- package/dist/index.d.ts +649 -25
- package/dist/index.js +55 -1
- package/dist/native.d.ts +218 -0
- package/dist/refresh-control.d.ts +12 -0
- package/dist/sheet-gesture.d.ts +66 -0
- package/dist/sheets.d.ts +72 -0
- package/dist/shell.d.ts +21 -0
- package/dist/tab-bar.d.ts +15 -0
- package/dist/types.d.ts +18 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1 +1,55 @@
|
|
|
1
|
-
import{appReview as wt,biometrics as Tt,camera as Rt,deepLinks as q,device as Et,haptics as Lt,health as kt,keepAwake as Mt,lifecycle as Pt,liveActivities as _t,location as It,network as Nt,notifications as Ot,permissions as Ht,pushNotifications as Ct,secureStorage as Kt,share as $t,speech as Ft,splash as Dt,watchConnectivity as Bt}from"craft-native/mobile";import{haptics as Q}from"craft-native/mobile";function _(){if(typeof window>"u")return;return window}function L(t=_()){if(!t)return 0;if(typeof t.scrollY==="number")return t.scrollY;return t.document?.scrollingElement?.scrollTop??0}function ue(t,e=_()){if(!e)return()=>{};let r=!1,n=typeof requestAnimationFrame==="function"?requestAnimationFrame:(o)=>setTimeout(o,16),i=()=>{if(r)return;r=!0,n(()=>{r=!1,t(L(e))})};return t(L(e)),e.addEventListener("scroll",i,{passive:!0}),()=>e.removeEventListener("scroll",i)}function Z(t,e){let r=Math.max(0,-t),n=t<=0?Math.max(0,e)*0.5:0;return Math.round(Math.max(r,n))}function de(t){let e=t.host??_();if(!e)return()=>{};let r=t.threshold??72,n=null,i=!1,o=!1,s=typeof requestAnimationFrame==="function"?requestAnimationFrame:(m)=>setTimeout(m,16),a=null,l=(m)=>{a=null,t.onPull?.(m,i)},c=(m)=>{let S=a!==null;if(a=m,S)return;s(()=>{if(a!==null)l(a)})},h=(m)=>{let S=m.touches?.[0];return S?S.clientY:null},d=(m)=>{if(o||L(e)>0)return;n=h(m),i=!1},f=(m)=>{if(n===null)return;let S=h(m);if(S===null)return;let x=Z(L(e),S-n);if(!i&&x>=r)i=!0,Promise.resolve(Q.impact("medium")).catch(()=>{});else if(i&&x<r*0.8)i=!1;c(x)},y=async()=>{if(n===null)return;if(n=null,!i){l(0);return}i=!1,o=!0,l(r);try{await t.onRefresh()}finally{o=!1,l(0)}},p=()=>{if(n===null)return;n=null,i=!1,l(0)};return e.addEventListener("touchstart",d,{passive:!0}),e.addEventListener("touchmove",f,{passive:!0}),e.addEventListener("touchend",y),e.addEventListener("touchcancel",p),()=>{a=null,e.removeEventListener("touchstart",d),e.removeEventListener("touchmove",f),e.removeEventListener("touchend",y),e.removeEventListener("touchcancel",p)}}function H(){if(typeof window>"u")return;return window}var N="__stxPushed",tt="__stxScroll";function et(t=H()){let e=t?.history?.state;if(e===null||e===void 0)return!1;if(typeof e!=="object")return!0;let r=e;if(N in r)return r[N]===!0;return!(tt in r)}function pe(t=H()){if(!et(t))return!1;return t.history.back(),!0}function me(t,e,r=50){let n=t[t.length-1];if(t.length>=2&&t[t.length-2].path===e)t.pop();else if(!n||n.path!==e)t.push({path:e,title:""});if(t.length>r)t.splice(0,t.length-r);return{current:t[t.length-1],previous:t[t.length-2]??null}}function ge(t,e,r=12){let n=t?.title.trim()??"";return n&&n.length<=r?n:e}function he(){if(typeof window>"u")return[];let t=window;return t.__stacksNavTrail??=[]}function nt(t,e=rt()){let r;try{r=new URL(t)}catch{return null}let n=`${r.search}${r.hash}`;if(r.protocol==="http:"||r.protocol==="https:"){if(!e||r.origin!==e)return null;return`${r.pathname||"/"}${n}`}return`${`/${[r.host,r.pathname.replace(/^\/+/,"")].filter(Boolean).join("/")}`}${n}`}function rt(){if(typeof window>"u")return;return window.location?.origin}var O="stacks-mobile-deep-link";function ye(t,e){let r=(n)=>{let i=nt(n);if(i)t(i)};return e.getInitialURL().then((n)=>{if(!n)return;try{if(sessionStorage.getItem(O)===n)return;sessionStorage.setItem(O,n)}catch{}r(n)}).catch(()=>{}),e.onLink((n,i)=>{if(i?.initial)return;r(n)})}var ve=30;function it(t,e){let r=Math.PI/180,n=(e.latitude-t.latitude)*r,i=(e.longitude-t.longitude)*r,o=Math.sin(n/2)**2+Math.cos(t.latitude*r)*Math.cos(e.latitude*r)*Math.sin(i/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(o)))}function ot(t,e=25){let r=new Set;return t.filter((n)=>Number.isFinite(n.latitude)&&Number.isFinite(n.longitude)&&Number.isFinite(n.timestamp)&&n.accuracy>=0&&n.accuracy<=e).sort((n,i)=>n.timestamp-i.timestamp).filter((n)=>{if(r.has(n.timestamp))return!1;return r.add(n.timestamp),!0})}function C(t,e={}){let r=ot(t,e.maxAccuracyM??25),n=e.paceWindowS??30,i=[],o=0,s=0,a=null;for(let d of r){let f=i[i.length-1],y=a?(d.timestamp-a.timestamp)/1000:0;if(a=d,!f){i.push({fix:d,cumM:0});continue}if(y>30){i.push({fix:d,cumM:o});continue}let p=(d.timestamp-f.fix.timestamp)/1000,m=it(f.fix,d),S=Math.min(10,Math.max(3,f.fix.accuracy,d.accuracy));if(m<S)continue;if(o+=m,p>0&&m/p>=0.5)s+=p;i.push({fix:d,cumM:o})}let l=i[i.length-1],c=null,h=null;if(l){let d=l.fix.timestamp-n*1000,f=i.find((m)=>m.fix.timestamp>=d)??l,y=l.cumM-f.cumM,p=(l.fix.timestamp-f.fix.timestamp)/1000;if(y>=20&&p>0)h=y/p,c=p/(y/1000)}return{distanceM:o,movingS:s,paceSPerKm:c,averagePaceSPerKm:o>=50&&s>0?s/(o/1000):null,speedMps:h,accuracyM:r.length?r[r.length-1].accuracy:t.length?t[t.length-1].accuracy??null:null,fixes:r.length}}function Se(t){if(!t||!Number.isFinite(t)||t>3600)return"–";let e=Math.round(t);return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}function Ae(t){return t&&Number.isFinite(t)?(t*3.6).toFixed(1):"–"}var K={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function xe(t){let e=t.location,r=t.intervalMs??3000,n=K,i=null,o=()=>typeof document<"u"&&document.visibilityState==="hidden";async function s(){let c=await e.readRecording();return n=C(c,t),t.onUpdate?.(n),n}function a(){l(),i=setInterval(()=>{if(!o())s().catch(()=>{})},r)}function l(){if(i)clearInterval(i);i=null}return{get stats(){return n},async start(){return await e.startRecording({enableHighAccuracy:!0,...t.locationOptions}),n=K,t.onUpdate?.(n),a(),n},async attach(){let c=await e.getRecordingState().catch(()=>null);if(!c?.active)return null;if(await s().catch(()=>{}),!c.paused)a();return c},async pause(){l(),await e.pauseRecording(),await s().catch(()=>{})},async resume(){await e.resumeRecording(),a()},async stop(){l();let h=(await e.stopRecording())?.locations??[];return n=C(h,t),t.onUpdate?.(n),h},refresh:s}}var Te=150;function st(t,e){let r=Math.PI/180,n=(e.latitude-t.latitude)*r,i=(e.longitude-t.longitude)*r,o=Math.sin(n/2)**2+Math.cos(t.latitude*r)*Math.cos(e.latitude*r)*Math.sin(i/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(o)))}function k(t,e){let r=[...t].sort((n,i)=>n-i);return r[Math.min(r.length-1,Math.floor(e*r.length))]}function Re(t,e){let r=(t||[]).filter((s)=>Number.isFinite(s?.latitude)&&Number.isFinite(s?.longitude)),n=r.map((s)=>Number(s.accuracy)).filter((s)=>Number.isFinite(s)&&s>=0),i=n.length?k(n,0.5):Number.POSITIVE_INFINITY,o=0;if(r.length){let s={latitude:k(r.map((a)=>a.latitude),0.5),longitude:k(r.map((a)=>a.longitude),0.5)};o=k(r.map((a)=>st(s,a)),0.8)}if(r.length>=10&&o>150&&i<=15)return"outside";if(e<150)return"unsure";if(r.length<3||i>30||o<25)return"indoors";if(o<50&&i>10)return"indoors";return"unsure"}function Ee(t){let r=String(t||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d+)?)\s*(km|k|m|mi)?$/);if(!r)return null;let n=Number(r[1]),i=r[2]||(n>100?"m":"km"),o=i==="m"?n/1000:i==="mi"?n*1.609344:n;return o>0&&o<1000?Math.round(o*1000)/1000:null}var ke=64;var at=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,lt=/^(?:0|[1-9]\d*)$/;function D(t){let e=[],r=[],n=t&&typeof t==="object"&&!Array.isArray(t)?t:{};for(let[i,o]of Object.entries(n)){let s=o&&typeof o==="object"?o:null;if(!s){r.push(`spotlight kind "${i}" is not an object`);continue}let{slots:a,route:l}=s,c=typeof s.noun==="string"&&s.noun.trim()?s.noun.trim():"Item";if(!at.test(i)||i.includes("-slot-")){r.push(`spotlight kind "${i}" is not a usable name: lowercase letters, digits and single dashes, and never "-slot-"`);continue}if(typeof a!=="number"||!Number.isInteger(a)||a<=0||a>64){r.push(`spotlight kind "${i}" needs slots between 1 and 64, not ${String(a)}`);continue}if(typeof l!=="string"||!l.startsWith("/")||!l.includes(":id")){r.push(`spotlight kind "${i}" needs a route starting with "/" and carrying ":id", not ${String(l)}`);continue}e.push({name:i,slots:a,route:l,noun:c})}return{kinds:e,problems:r}}function R(t,e){return t.find((r)=>r.name===e)??null}function T(t,e,r){let n=R(t,e);if(!n||!Number.isInteger(r)||r<0||r>=n.slots)return null;return`${e}-slot-${r}`}function ct(t,e){if(typeof e!=="string")return null;let r=e.lastIndexOf("-slot-");if(r<=0)return null;let n=e.slice(0,r),i=e.slice(r+6);if(!lt.test(i))return null;let o=Number(i);return T(t,n,o)===e?{kind:n,slot:o}:null}function B(t){return t.flatMap((e)=>Array.from({length:e.slots},(r,n)=>`${e.name}-slot-${n}`))}function Me(t,e){let r=t&&typeof t==="object"?t:{};if(r.enabled===!1)return[];let i=[...(Array.isArray(r.activityTypes)?r.activityTypes.filter((o)=>typeof o==="string"&&o.trim().length>0):[]).map((o)=>o.trim()),...B(D(r.kinds).kinds)];return[...new Set(i)].map((o)=>`${e}.${o}`)}function U(t,e,r){let n=typeof r.name==="string"?r.name.replace(/\s+/g," ").trim():"";if(!n)return`${R(t,e)?.noun??"Item"} #${r.id}`;return n.length>120?`${n.slice(0,119).trimEnd()}…`:n}function ut(t,e,r,n,i=Date.now()){let o=R(t,r);if(!o||!Number.isInteger(n.id)||n.id<=0)return null;let s=e.filter((p)=>p.kind===r),a=U(t,r,n),l=s.find((p)=>p.itemId===n.id)??null,c=l?null:mt(s,o.slots),h=l||c!==null?null:gt(s),d=l?.slot??c??h?.slot;if(d===void 0||d===null)return null;let f={kind:r,slot:d,itemId:n.id,title:a,donatedAt:i},y=e.filter((p)=>p.kind!==r||p.slot!==d&&p.itemId!==n.id);return{entries:G(t,[...y,f]),entry:f,evicted:h,changed:!l||l.title!==a}}function dt(t,e,r){let n=t.find((i)=>i.kind===e&&i.itemId===r)??null;return{entries:n?t.filter((i)=>i!==n):[...t],removed:n}}function ft(t,e,r){let n=ct(t,r);if(!n)return null;let i=e.find((s)=>s.kind===n.kind&&s.slot===n.slot),o=R(t,n.kind)?.route;return i&&o?o.replace(":id",String(i.itemId)):null}function pt(t,e){if(!Array.isArray(e))return[];let r=new Map,n=new Set;for(let i of e){if(!i||typeof i!=="object")continue;let o=i,{kind:s,slot:a,itemId:l,title:c,donatedAt:h}=o;if(typeof s!=="string"||typeof a!=="number"||T(t,s,a)===null)continue;if(typeof l!=="number"||!Number.isInteger(l)||l<=0)continue;let d=`${s}-slot-${a}`,f=`${s}#${l}`;if(r.has(d)||n.has(f))continue;r.set(d,{kind:s,slot:a,itemId:l,title:typeof c==="string"&&c.trim()?c:U(t,s,{id:l}),donatedAt:typeof h==="number"&&Number.isFinite(h)&&h>0?h:0}),n.add(f)}return G(t,[...r.values()])}function G(t,e){let r=new Map(t.map((n,i)=>[n.name,i]));return[...e].sort((n,i)=>(r.get(n.kind)??0)-(r.get(i.kind)??0)||n.slot-i.slot)}function mt(t,e){let r=new Set(t.map((n)=>n.slot));for(let n=0;n<e;n++)if(!r.has(n))return n;return null}function gt(t){return t.reduce((e,r)=>!e||r.donatedAt<e.donatedAt?r:e,null)}function ht(){let t=globalThis.craft;return t&&typeof t==="object"?t.siri:void 0}var yt="stacks_spotlight_index",bt=3000;function Pe(t){let e=t.onProblem??((u)=>console.warn(`[spotlight] ${u}`)),r=Array.isArray(t.kinds)?{kinds:[...t.kinds],problems:[]}:D(t.kinds);for(let u of r.problems)e(u);let n=t.enabled===!1?[]:r.kinds,i=t.storageKey??yt,o=t.legacyStorageKeys??[],s=t.timeoutMs??bt,a=t.now??(()=>Date.now()),l=t.bridge??ht,c=null;function h(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function d(){if(c)return c;c=[];let u=h();if(!u)return c;try{let g=[i,...o].map((b)=>u.getItem(b)).find((b)=>b);c=g?pt(n,JSON.parse(g)):[]}catch{c=[]}return c}function f(u){c=u;let g=h();if(!g)return;try{g.setItem(i,JSON.stringify(u));for(let b of o)g.removeItem(b)}catch{}}async function y(u){if(!u)return null;let g;try{return await Promise.race([u,new Promise((b)=>{g=setTimeout(()=>b(null),s)})])}catch{return null}finally{if(g!==void 0)clearTimeout(g)}}let p=Promise.resolve();function m(u){let g=p.then(u,u);return p=g.catch(()=>{return}),g}async function S(u,g){let b=l()?.register;if(!b||n.length===0)return!1;return m(async()=>{let v=ut(n,d(),u,g,a()),A=v&&T(n,u,v.entry.slot);if(!v||!A)return!1;if(!v.changed)return f(v.entries),!0;let w=await y(b(v.entry.title,A))!==null;if(w)f(v.entries);return w})}async function x(u,g){let b=l()?.remove;if(!b)return!1;return m(async()=>{let{entries:v,removed:A}=dt(d(),u,g);if(!A)return!1;let w=T(n,u,A.slot),z=w?await y(b(w))!==null:!1;return f(v),z})}async function J(u,g){let b=R(n,u)?.slots;if(!b||!l()?.register)return 0;let v=0;for(let A of[...g].slice(0,b).reverse())if(await S(u,A))v++;return v}async function X(){let u=l()?.remove;if(!u)return f([]),0;return m(async()=>{let g=0;for(let b of d()){let v=T(n,b.kind,b.slot);if(v&&await y(u(v))!==null)g++}return f([]),g})}return{kinds:n,index:S,sync:J,remove:x,clear:X,routeFor:(u)=>ft(n,d(),u),entries:()=>d(),activityTypes:(u)=>B(n).map((g)=>`${u}.${g}`),reset:()=>{c=null}}}var F=["craftShortcut","craftSiriShortcut"];function _e(t,e){let r=(n)=>{let i=n.detail,o=typeof i==="string"?i:i&&typeof i==="object"?i.action??i.type:null,s=typeof o==="string"?t.routeFor(o):null;if(s)e(s)};if(typeof globalThis.addEventListener!=="function")return()=>{};for(let n of F)globalThis.addEventListener(n,r);return()=>{for(let n of F)globalThis.removeEventListener(n,r)}}import{tabBar as vt}from"craft-native/mobile";var St=vt;function At(t){return Array.from(t.querySelectorAll("a[data-native-tab]")).map((e)=>({id:e.getAttribute("href")||"",title:e.getAttribute("data-native-tab")||e.getAttribute("aria-label")||"",symbol:e.getAttribute("data-native-tab-symbol")||"circle",badge:(e.querySelector(".native-tab-badge")?.textContent||"").trim(),current:e.hasAttribute("data-stx-nav-current")||e.classList.contains("is-active")})).filter((e)=>e.id&&e.title)}function xt(t){return{tabs:t.map(({id:r,title:n,symbol:i,badge:o})=>o?{id:r,title:n,symbol:i,badge:o}:{id:r,title:n,symbol:i}),selected:t.find((r)=>r.current)?.id}}function j(t){let e=t.trim();return/^#[0-9a-f]{6}$/i.test(e)?e:void 0}function Oe(t,e={}){let r=e.api??St;if(!r.isAvailable())return null;let n=e.hidden??(()=>Boolean(t.ownerDocument?.querySelector("[data-native-hide-tab-bar]"))),i=typeof getComputedStyle==="function"?getComputedStyle(t):null,o=j(i?.getPropertyValue("--native-tab-active")||""),s=j(i?.getPropertyValue("--native-tab-active-dark")||""),a="",l=()=>{if(n()){if(a!=="hidden")r.hide();a="hidden";return}let{tabs:f,selected:y}=xt(At(t)),p=JSON.stringify({tabs:f,selected:y});if(p===a)return;let m=a&&a!=="hidden"?JSON.parse(a):null;if(m&&y&&JSON.stringify(m.tabs)===JSON.stringify(f))r.select(y);else r.set(f,{selected:y,tint:o,tintDark:s});a=p},c=typeof MutationObserver==="function"?new MutationObserver(l):null;c?.observe(t,{attributes:!0,attributeFilter:["data-stx-nav-current","class"],childList:!0,subtree:!0,characterData:!0});let h=r.onSelect((f)=>{Array.from(t.querySelectorAll("a[data-native-tab]")).find((p)=>p.getAttribute("href")===f)?.click()}),d=()=>l();if(typeof window<"u")window.addEventListener("stx:load",d);return l(),()=>{if(c?.disconnect(),h(),typeof window<"u")window.removeEventListener("stx:load",d);r.hide()}}var Ut=Tt,Gt=Rt,jt=Et,M=Lt,qt=Pt,Yt=It,Vt=Ot,Wt=Ht,Jt=Kt,Xt=$t,zt=wt;function Y(t){if(typeof t==="string")return t.trim()||null;if(!t||typeof t!=="object")return null;let e=t.url;return typeof e==="string"&&e.trim()?e:null}var Qt={async getInitialURL(){if(!await V())return null;return Y(await q.getInitialURL?.())},onLink(t){let e=null,r=!1,n=()=>{if(r)return;e=q.onLink?.((i,o)=>{let s=Y(i);if(s)t(s,{initial:o?.initial===!0})})??null};if(E()?.craft)n();else V().then(n);return()=>{r=!0,e?.()}}},Zt=Mt,te=Ft,ee=Nt,ne=Ct,re=kt,ie=_t,oe=Bt,Ke=Dt;function E(){if(typeof window>"u")return;return window}function P(){let t=E()?.craft;if(!t||typeof t!=="object")return null;if(!("platform"in t)||t.platform!=="ios"&&t.platform!=="android")return null;let e="capabilities"in t?t.capabilities:void 0,r=e&&typeof e==="object"&&!Array.isArray(e)?Object.fromEntries(Object.entries(e).filter(([,n])=>typeof n==="boolean")):{};return{platform:t.platform,capabilities:r}}function I(){return P()!==null}function W(){if(typeof window>"u")return!1;let t=window;if(t.CraftAndroid)return!0;let e=typeof navigator>"u"?"":navigator.userAgent;return Boolean(t.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test(e)}function se(t=2000){if(I()||W())return Promise.resolve(!0);let e=E(),r=e;if(!e||!(r?.craft||r?.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let i=()=>{clearTimeout(o),e.removeEventListener("craftReady",i),n(I())},o=setTimeout(i,t);e.addEventListener("craftReady",i,{once:!0})})}function V(t=15000){let e=E();if(e?.craft)return Promise.resolve(!0);let r=e;if(!e||!(W()||r?.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let i=()=>{clearTimeout(o),e.removeEventListener("craftReady",i),n(Boolean(e.craft))},o=setTimeout(i,t);e.addEventListener("craftReady",i)})}function ae(t){let e=E();if(!e)return()=>{};if(P()){let n=!1;return queueMicrotask(()=>{if(!n)t(new Event("craftReady"))}),()=>{n=!0}}let r=(n)=>{if(!P())return;e.removeEventListener("craftReady",r),t(n)};return e.addEventListener("craftReady",r),()=>e.removeEventListener("craftReady",r)}async function le(t){await M.impact("light");try{let e=await t();return await M.notification("success"),e}catch(e){throw await M.notification("error"),e}}var $e={get nativeBridge(){return P()},biometrics:Ut,camera:Gt,device:jt,haptics:M,lifecycle:qt,location:Yt,notifications:Vt,permissions:Wt,secureStorage:Jt,share:Xt,appReview:zt,deepLinks:Qt,keepAwake:Zt,speech:te,network:ee,pushNotifications:ne,health:re,liveActivities:ie,watchConnectivity:oe,isNativeMobile:I,whenNative:se,onReady:ae,withFeedback:le};export{Te as INDOOR_CHECK_AFTER_S,ke as MAX_SPOTLIGHT_SLOTS_PER_KIND,ve as ROUTE_GAP_S,zt as appReview,ge as backLabelFor,Ut as biometrics,Gt as camera,et as canGoBack,xe as createRouteRecorder,Pe as createSpotlightIndex,nt as deepLinkPath,Qt as deepLinks,jt as device,me as enterNavTrail,it as fixDistance,ye as followDeepLinks,P as getNativeMobileBridge,pe as goBack,M as haptics,W as hasNativeMobileHost,re as health,Re as indoorVerdict,I as isNativeMobile,Zt as keepAwake,qt as lifecycle,ie as liveActivities,Yt as location,Oe as mirrorTabBar,$e as mobile,xt as nativeTabs,he as navTrail,ee as network,Y as normalizeDeepLinkURL,Vt as notifications,ue as observePageScroll,de as observePullToRefresh,ae as onMobileReady,_e as onSpotlightTap,Se as paceLabel,L as pageScrollTop,Wt as permissions,ut as placeSpotlightItem,Z as pullDistance,ne as pushNotifications,pt as readSpotlightEntries,D as readSpotlightKinds,At as readTabLinks,dt as removeSpotlightItem,C as routeStats,Jt as secureStorage,Xt as share,te as speech,Ae as speedLabel,Ke as splash,T as spotlightAction,B as spotlightActions,Me as spotlightActivityTypes,ht as spotlightBridge,R as spotlightKind,ft as spotlightRoute,ct as spotlightSlot,U as spotlightTitle,St as tabBar,Ee as typedDistanceKm,ot as usableFixes,oe as watchConnectivity,V as whenBridgeReady,se as whenNativeMobile,le as withNativeFeedback};
|
|
1
|
+
import{appReview as mn,biometrics as he,camera as Q,deepLinks as lt,device as O,haptics as Z,health as U,keepAwake as ct,lifecycle as gn,liveActivities as be,location as P,network as ut,notifications as ee,permissions as W,pushNotifications as ve,secureStorage as te,share as dt,speech as ye,splash as hn,watchConnectivity as Y}from"craft-native/mobile";var Bn=2500;function x(){if(typeof window>"u")return;return window}function ht(){let e=x()?.craft;return e&&typeof e==="object"?e:void 0}function bt(){return typeof navigator>"u"?"":navigator.userAgent||""}function ie(){let e=x();if(!e)return!1;if(e.CraftAndroid)return!0;return Boolean(e.webkit?.messageHandlers?.craft)&&/iPhone|iPad|iPod/.test(bt())}function j(){let e=x();if(!e||e.craft)return!1;return ie()||Boolean(e.webkit?.messageHandlers?.craft)}function I(e=15000){let t=x();if(t?.craft)return Promise.resolve(!0);if(!t||!j())return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(o),t.removeEventListener("craftReady",r),n(Boolean(t.craft))},o=setTimeout(r,e);t.addEventListener("craftReady",r)})}function vt(e,t){if(!e)return null;let n=t.split("."),r=e;for(let i of n.slice(0,-1))if(r=r?.[i],!r||typeof r!=="object"&&typeof r!=="function")return null;let o=r?.[n[n.length-1]];return typeof o==="function"?o.bind(r):null}function T(e){return vt(ht(),e)}async function yt(e,t=2500){let n=T(e);if(n||!j())return n;return await I(t),T(e)}async function b(e,t,n,r={}){let o=await yt(e,r.timeoutMs);if(!o)return n();try{return await o(...t)}catch(i){if(r.fallbackOnError)return n();throw i}}async function g(e,t=2500){if(j())await I(t);return e()}function ae(e,t=2500){let n,r=!1;if(!j())n=e();else I(t).then(()=>{if(!r)n=e()});return()=>{if(r=!0,typeof n==="function")n()}}function R(e,t){let n=x();if(!n)return()=>{};let r=(o)=>t(o.detail??{});return n.addEventListener(e,r),()=>n.removeEventListener(e,r)}var Se="native-dialog-styles",xt=`
|
|
2
|
+
.native-dialog { position: fixed; inset: 0; z-index: 2147483000; font-size: var(--native-font-size, 17px); font-family: var(--native-font-family, -apple-system, system-ui, sans-serif); -webkit-tap-highlight-color: transparent; }
|
|
3
|
+
.native-dialog-backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / 0.3); opacity: 0; transition: opacity 220ms ease; }
|
|
4
|
+
.native-dialog--menu .native-dialog-backdrop { background: rgb(0 0 0 / 0.12); -webkit-backdrop-filter: blur(14px) saturate(140%); backdrop-filter: blur(14px) saturate(140%); }
|
|
5
|
+
.native-dialog.is-open .native-dialog-backdrop { opacity: 1; }
|
|
6
|
+
.native-dialog-panel { position: absolute; outline: none; }
|
|
7
|
+
.native-dialog--sheet .native-dialog-panel { right: 0; bottom: 0; left: 0; display: flex; flex-direction: column; gap: 0.47em; max-width: 32rem; margin: 0 auto; padding: 0 0.47em calc(0.47em + env(safe-area-inset-bottom, 0px)); transform: translateY(110%); transition: transform 380ms cubic-bezier(0.32, 0.72, 0, 1); }
|
|
8
|
+
.native-dialog--sheet.is-open .native-dialog-panel { transform: none; }
|
|
9
|
+
.native-dialog--alert .native-dialog-panel { top: 50%; left: 50%; width: min(16.5em, calc(100vw - 3rem)); transform: translate(-50%, -50%) scale(1.12); opacity: 0; transition: transform 260ms cubic-bezier(0.2, 0.9, 0.3, 1.05), opacity 200ms ease; }
|
|
10
|
+
.native-dialog--alert.is-open .native-dialog-panel { transform: translate(-50%, -50%); opacity: 1; }
|
|
11
|
+
.native-dialog-group { overflow: hidden; border-radius: 0.8em; background: var(--native-dialog-background, rgb(242 242 247 / 0.92)); -webkit-backdrop-filter: blur(24px) saturate(180%); backdrop-filter: blur(24px) saturate(180%); }
|
|
12
|
+
.native-dialog-header { padding: 0.85em 1em; text-align: center; }
|
|
13
|
+
.native-dialog--sheet .native-dialog-header { border-bottom: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); }
|
|
14
|
+
.native-dialog-title { margin: 0; font-size: 0.765em; font-weight: 600; color: var(--native-secondary-label, rgb(60 60 67 / 0.6)); }
|
|
15
|
+
.native-dialog--alert .native-dialog-title { font-size: 1em; color: inherit; }
|
|
16
|
+
.native-dialog-message { margin: 0.25em 0 0; font-size: 0.765em; color: var(--native-secondary-label, rgb(60 60 67 / 0.6)); }
|
|
17
|
+
.native-dialog--alert .native-dialog-message { color: inherit; }
|
|
18
|
+
.native-dialog-actions { display: flex; flex-direction: column; }
|
|
19
|
+
.native-dialog--alert .native-dialog-actions { border-top: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); }
|
|
20
|
+
.native-dialog--alert .native-dialog-actions.is-row { flex-direction: row; }
|
|
21
|
+
.native-dialog-action { width: 100%; min-height: 3.3em; padding: 0 1em; border: 0; border-top: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); color: var(--native-accent, rgb(0 122 255)); background: transparent; font: inherit; font-size: 1.18em; cursor: pointer; }
|
|
22
|
+
.native-dialog--alert .native-dialog-action { min-height: 2.6em; font-size: 1em; }
|
|
23
|
+
.native-dialog-action:first-child { border-top: 0; }
|
|
24
|
+
.native-dialog-actions.is-row .native-dialog-action { flex: 1; border-top: 0; border-left: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); }
|
|
25
|
+
.native-dialog-actions.is-row .native-dialog-action:first-child { border-left: 0; }
|
|
26
|
+
.native-dialog-action.is-cancel { font-weight: 600; }
|
|
27
|
+
.native-dialog-action.is-destructive { color: var(--native-destructive, rgb(255 59 48)); }
|
|
28
|
+
.native-dialog-action:active, .native-dialog-action:focus-visible { background: var(--native-pressed, rgb(0 0 0 / 0.08)); outline: none; }
|
|
29
|
+
.native-menu { position: absolute; width: min(15.5em, calc(100vw - 1.5rem)); overflow: hidden; border-radius: 0.8em; background: var(--native-dialog-background, rgb(242 242 247 / 0.92)); box-shadow: 0 10px 40px rgb(0 0 0 / 0.2); -webkit-backdrop-filter: blur(24px) saturate(180%); backdrop-filter: blur(24px) saturate(180%); transform: scale(0.6); transform-origin: var(--native-menu-origin, top left); opacity: 0; transition: transform 300ms cubic-bezier(0.2, 0.9, 0.3, 1.1), opacity 160ms ease; }
|
|
30
|
+
.native-dialog.is-open .native-menu { transform: none; opacity: 1; }
|
|
31
|
+
.native-menu-title { margin: 0; padding: 0.6em 1em; border-bottom: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); font-size: 0.765em; color: var(--native-secondary-label, rgb(60 60 67 / 0.6)); }
|
|
32
|
+
.native-menu-item { display: flex; gap: 0.75em; align-items: center; justify-content: space-between; width: 100%; min-height: 2.6em; padding: 0 1em; border: 0; border-top: 0.5px solid var(--native-separator, rgb(60 60 67 / 0.29)); color: inherit; background: transparent; font: inherit; text-align: left; cursor: pointer; }
|
|
33
|
+
.native-menu-item:first-of-type { border-top: 0; }
|
|
34
|
+
.native-menu-item.is-destructive { color: var(--native-destructive, rgb(255 59 48)); }
|
|
35
|
+
.native-menu-item:disabled { opacity: 0.35; }
|
|
36
|
+
.native-menu-item:active, .native-menu-item:focus-visible { background: var(--native-pressed, rgb(0 0 0 / 0.08)); outline: none; }
|
|
37
|
+
.native-menu-icon { flex-shrink: 0; width: 1.1em; height: 1.1em; }
|
|
38
|
+
.dark .native-dialog-group, .dark .native-menu { background: var(--native-dialog-background-dark, rgb(44 44 46 / 0.9)); color: rgb(255 255 255); }
|
|
39
|
+
.dark .native-dialog-action { color: var(--native-accent-dark, rgb(10 132 255)); }
|
|
40
|
+
.dark .native-dialog-action.is-destructive, .dark .native-menu-item.is-destructive { color: var(--native-destructive-dark, rgb(255 69 58)); }
|
|
41
|
+
.dark .native-dialog-title, .dark .native-dialog-message, .dark .native-menu-title { color: rgb(235 235 245 / 0.6); }
|
|
42
|
+
.dark .native-dialog--alert .native-dialog-title, .dark .native-dialog--alert .native-dialog-message { color: rgb(255 255 255); }
|
|
43
|
+
.dark .native-dialog-action, .dark .native-menu-item, .dark .native-dialog-header, .dark .native-menu-title, .dark .native-dialog-actions { border-color: rgb(84 84 88 / 0.6); }
|
|
44
|
+
.dark .native-dialog-action:active, .dark .native-menu-item:active { background: rgb(255 255 255 / 0.1); }
|
|
45
|
+
@media (prefers-reduced-motion: reduce) {
|
|
46
|
+
.native-dialog-backdrop, .native-dialog-panel, .native-menu { transition: opacity 150ms ease; }
|
|
47
|
+
.native-dialog--sheet .native-dialog-panel, .native-dialog--alert .native-dialog-panel, .native-menu { transform: none; }
|
|
48
|
+
.native-dialog--alert .native-dialog-panel { transform: translate(-50%, -50%); }
|
|
49
|
+
}
|
|
50
|
+
:root[data-native-reduce-motion] .native-dialog--sheet .native-dialog-panel, :root[data-native-reduce-motion] .native-menu { transform: none; transition: opacity 150ms ease; }
|
|
51
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
52
|
+
.native-dialog-group, .native-menu { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--native-dialog-solid, rgb(242 242 247)); }
|
|
53
|
+
.dark .native-dialog-group, .dark .native-menu { background: var(--native-dialog-solid-dark, rgb(44 44 46)); }
|
|
54
|
+
}
|
|
55
|
+
`;function we(){return x()?.document}function St(e){if(e.getElementById(Se))return;let t=e.createElement("style");t.id=Se,t.textContent=xt,(e.head??e.documentElement).appendChild(t)}var wt=0;function w(e,t,n,r){let o=e.createElement(t);if(o.className=n,r!==void 0)o.textContent=r;return o}var ke='button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function kt(e,t){if(t.key!=="Tab")return;let n=Array.from(e.querySelectorAll(ke));if(n.length===0){t.preventDefault();return}let r=n[0],o=n[n.length-1],i=e.ownerDocument.activeElement;if(t.shiftKey&&(i===r||!e.contains(i)))t.preventDefault(),o.focus();else if(!t.shiftKey&&(i===o||!e.contains(i)))t.preventDefault(),r.focus()}function Ae(e,t,n,r){St(e);let o=x(),i=e.activeElement,a=w(e,"div",`native-dialog native-dialog--${t}`);return a.setAttribute("data-native-dialog",t),a.appendChild(w(e,"div","native-dialog-backdrop")),new Promise((s)=>{let l=!1,d=(h)=>{if(l)return;l=!0,a.classList.remove("is-open"),e.removeEventListener("keydown",p,!0),setTimeout(()=>{if(a.remove(),i&&typeof i.focus==="function")i.focus()},260),s(h)},p=(h)=>{if(h.key==="Escape"){h.preventDefault(),d(r());return}kt(c,h)},c=n({root:a,settle:d});a.appendChild(c),e.body.appendChild(a),e.addEventListener("keydown",p,!0);let m=o;(typeof m?.requestAnimationFrame==="function"?(h)=>m.requestAnimationFrame(()=>m.requestAnimationFrame(h)):(h)=>setTimeout(h,16))(()=>{if(!l)a.classList.add("is-open")}),(c.querySelector("[data-native-autofocus]")??c.querySelector(ke))?.focus()})}function se(e){let t=we();if(!t?.body)return Promise.resolve(null);let n=`native-dialog-${++wt}`,r=e.actions.find((a)=>a.style==="cancel"),o=e.variant==="sheet"?e.actions.filter((a)=>a.style!=="cancel"):e.actions,i=e.variant==="sheet"?r??{id:"__cancel",title:e.cancelLabel||"Cancel",style:"cancel"}:void 0;return Ae(t,e.variant,({root:a,settle:s})=>{let l=(u)=>u.style==="cancel"?null:u.id,d=w(t,"div","native-dialog-panel");d.setAttribute("role","alertdialog"),d.setAttribute("aria-modal","true"),d.tabIndex=-1;let p=w(t,"div","native-dialog-group");if(e.title||e.message){let u=w(t,"div","native-dialog-header");if(e.title){let f=w(t,"p","native-dialog-title",e.title);f.id=`${n}-title`,u.appendChild(f),d.setAttribute("aria-labelledby",f.id)}if(e.message){let f=w(t,"p","native-dialog-message",e.message);f.id=`${n}-message`,u.appendChild(f),d.setAttribute("aria-describedby",f.id)}p.appendChild(u)}let c=w(t,"div","native-dialog-actions");if(e.variant==="alert"&&o.length===2)c.classList.add("is-row");for(let u of o){let f=w(t,"button",`native-dialog-action${u.style==="destructive"?" is-destructive":""}${u.style==="cancel"?" is-cancel":""}`,u.title);f.type="button",f.setAttribute("data-action-id",u.id),f.addEventListener("click",()=>s(l(u))),c.appendChild(f)}if(p.appendChild(c),d.appendChild(p),i){let u=w(t,"div","native-dialog-group"),f=w(t,"button","native-dialog-action is-cancel",i.title);f.type="button",f.setAttribute("data-action-id",i.id),f.addEventListener("click",()=>s(null)),u.appendChild(f),d.appendChild(u)}let m=a.querySelector(".native-dialog-backdrop");if(e.variant==="sheet")m?.addEventListener("click",()=>s(null));return d},()=>{if(e.variant==="sheet")return null;if(r)return null;return o.length===1?o[0].id:null})}async function Ee(e){await se({variant:"alert",title:e.title,message:e.message,actions:[{id:"ok",title:e.okLabel||"OK"}]})}async function Te(e){return await se({variant:"alert",title:e.title,message:e.message,actions:[{id:"cancel",title:e.cancelLabel||"Cancel",style:"cancel"},{id:"confirm",title:e.confirmLabel||"OK",style:e.destructive?"destructive":"default"}]})==="confirm"}function Le(e){return se({variant:"sheet",title:e.title,message:e.message,actions:e.actions,cancelLabel:e.cancelLabel})}function At(e,t,n){let i=Math.max(12,Math.min(e.x,n.width-t.width-12)),a=e.y+e.height+8,s=a+t.height<=n.height-12,l=e.y-8-t.height,d=s||l<12?Math.max(12,Math.min(a,n.height-t.height-12)):l,p=e.x+e.width/2>n.width/2?"right":"left";return{top:d,left:i,origin:`${s||l<12?"top":"bottom"} ${p}`}}function Re(e){let t=we();if(!t?.body)return Promise.resolve(null);let n=x();return Ae(t,"menu",({root:r,settle:o})=>{let i=w(t,"div","native-menu native-dialog-panel");if(i.setAttribute("role","menu"),e.title)i.appendChild(w(t,"p","native-menu-title",e.title)),i.setAttribute("aria-label",e.title);for(let a of e.items){let s=w(t,"button",`native-menu-item${a.destructive?" is-destructive":""}`);if(s.type="button",s.setAttribute("role","menuitem"),s.setAttribute("data-action-id",a.id),a.disabled)s.disabled=!0;if(s.appendChild(w(t,"span","native-menu-label",a.title)),a.icon){let l=w(t,"i",`native-menu-icon ${a.icon}`);l.setAttribute("aria-hidden","true"),s.appendChild(l)}s.addEventListener("click",()=>o(a.id)),i.appendChild(s)}return r.querySelector(".native-dialog-backdrop")?.addEventListener("click",()=>o(null)),queueMicrotask(()=>{let a=i.getBoundingClientRect?.(),s=At(e.anchor,{width:a?.width||248,height:a?.height||e.items.length*44},{width:n?.innerWidth||390,height:n?.innerHeight||844});i.style.top=`${s.top}px`,i.style.left=`${s.left}px`,i.style.setProperty("--native-menu-origin",s.origin)}),i},()=>null)}var Oe=()=>!0,E=()=>!1,L=()=>null;function Pe(){return x()?.navigator??(typeof navigator>"u"?void 0:navigator)}function de(e){return{x:Math.round(e.x??e.left??0),y:Math.round(e.y??e.top??0),width:Math.round(e.width),height:Math.round(e.height)}}var _={alert:(e)=>b("dialog.alert",[e],()=>Ee(e),{fallbackOnError:!0}).then(()=>{}),confirm:(e)=>b("dialog.confirm",[e],()=>Te(e),{fallbackOnError:!0}).then(Boolean),actionSheet:async(e)=>{let t={...e,anchor:e.anchor?de(e.anchor):void 0},n=await b("dialog.actionSheet",[t],()=>Le(e),{fallbackOnError:!0});if(typeof n!=="string")return null;return e.actions.find((r)=>r.id===n)?.style==="cancel"?null:n}};function Wn(){return(e)=>_.actionSheet(e)}async function Yn(e){if((e.style??(e.destructive?"sheet":"alert"))==="alert")return _.confirm(e);return await _.actionSheet({title:e.title,message:e.message,anchor:e.anchor,actions:[{id:"confirm",title:e.confirmLabel||"OK",style:e.destructive?"destructive":"default"},{id:"cancel",title:e.cancelLabel||"Cancel",style:"cancel"}]})==="confirm"}var pe={show:async(e)=>{let t={title:e.title,anchor:de(e.anchor),items:e.items.map(({id:r,title:o,symbol:i,destructive:a,disabled:s})=>({id:r,title:o,symbol:i,destructive:a,disabled:s}))},n=await b("contextMenu.show",[t],()=>Re(e),{fallbackOnError:!0});return typeof n==="string"?n:null}};function jn(e,t){return pe.show({...t,anchor:de(e.getBoundingClientRect())})}function Et(e,t){let n=x();if(!n)return{cancelled:!0};if(typeof n.craft?.openURL==="function")return Promise.resolve(n.craft.openURL(e)).catch(()=>{}),{cancelled:!1};if(t.mode==="auth")return n.location?.assign(e),{cancelled:!1};if(!(typeof n.open==="function"?n.open(e,"_blank","noopener"):null))n.location?.assign(e);return{cancelled:!1}}var Ie={open:async(e,t={})=>{let n=await b("browser.open",[e,t],()=>Et(e,t),{fallbackOnError:!0});if(!n||typeof n!=="object")return{cancelled:!1};let{url:r,cancelled:o}=n;return typeof r==="string"?{url:r,cancelled:Boolean(o)}:{cancelled:Boolean(o)}}},le=new Map,ce=new Map;function Me(e,t){return`${e}|${t.pointSize??""}|${t.weight??""}|${t.color??""}|${t.scale??""}`}var Ne={isAvailable:()=>T("symbols.image")!==null,image:(e,t={})=>{let n=Me(e,t),r=le.get(n);if(r)return r;let o=b("symbols.image",[e,t],L).then((i)=>typeof i==="string"&&i.startsWith("data:")?i:null,L).then((i)=>(ce.set(n,i),i));return le.set(n,o),o},cached:(e,t={})=>ce.get(Me(e,t)),clearCache:()=>{le.clear(),ce.clear()}},z={setStyle:(e)=>b("statusBar.setStyle",[e],E,{fallbackOnError:!0}).then((t)=>t!==!1)},D={setUnderPageColor:(e)=>b("chrome.setUnderPageColor",[e],E,{fallbackOnError:!0}).then((t)=>t!==!1),setKeyboardAccessory:(e)=>b("chrome.setKeyboardAccessory",[e],E,{fallbackOnError:!0}).then((t)=>t!==!1)},M={isAvailable:()=>T("refresh.enable")!==null,enable:(e)=>b("refresh.enable",[e??{}],E,{fallbackOnError:!0}).then((t)=>t!==!1),disable:()=>b("refresh.disable",[],E,{fallbackOnError:!0}).then((e)=>e!==!1),end:()=>b("refresh.end",[],E,{fallbackOnError:!0}).then((e)=>e!==!1),onRefresh:(e)=>R("craftRefresh",()=>e())},B={complete:(e)=>b("background.complete",[e],E,{fallbackOnError:!0}).then((t)=>t!==!1)},He={write:(e)=>b("clipboard.write",[e],async()=>{let t=Pe()?.clipboard;if(!t?.writeText)return!1;return t.writeText(e).then(Oe,E)},{fallbackOnError:!0}).then((t)=>t!==!1),read:()=>b("clipboard.read",[],async()=>{let e=Pe()?.clipboard;if(!e?.readText)return null;return e.readText().catch(L)},{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null)},_e={isAvailable:()=>T("db.query")!==null,query:(e,t=[])=>b("db.query",[e,t],L).then((n)=>Array.isArray(n)?n:null),execute:(e,t=[])=>b("db.execute",[e,t],L).then((n)=>{if(!n||typeof n!=="object")return null;let{rowsAffected:r,lastInsertId:o}=n;return{rowsAffected:Number(r)||0,lastInsertId:Number(o)||0}})};function ue(e,t){let n=x()?.document;if(!n?.body)return null;let r=n.createElement("a");return r.href=e,r.download=t,r.rel="noopener",r.style.display="none",n.body.appendChild(r),r.click(),r.remove(),t}function Tt(e){let t=x()?.document;if(!t?.body)return Promise.resolve(null);return new Promise((n)=>{let r=t.createElement("input");if(r.type="file",r.style.display="none",e.length)r.accept=e.map((i)=>i.includes("/")||i.startsWith(".")?i:`.${i}`).join(",");let o=(i)=>{r.remove(),n(i)};r.addEventListener("cancel",()=>o(null)),r.addEventListener("change",()=>{let i=r.files?.[0];if(!i)return o(null);let a=new FileReader;a.onload=()=>o({name:i.name,mimeType:i.type||void 0,data:typeof a.result==="string"?a.result:void 0}),a.onerror=()=>o({name:i.name,mimeType:i.type||void 0}),a.readAsDataURL(i)}),t.body.appendChild(r),r.click()})}var De={openPDF:(e,t=0)=>b("openPDF",[e,t],()=>{let n=x();return Boolean(n?.open?.(e,"_blank","noopener"))}).then((n)=>n!==!1),takeScreenshot:()=>b("takeScreenshot",[],L,{fallbackOnError:!0}).then((e)=>typeof e==="string"?e:null),scanQRCode:()=>b("scanQRCode",[],L).then((e)=>{if(!e||typeof e!=="object")return null;let{type:t,data:n}=e;return typeof n==="string"?{type:String(t??""),data:n}:null},L),pickFile:(e=[])=>b("pickFile",[e],()=>Tt(e)).then((t)=>{if(!t||typeof t!=="object")return null;let n=t;if(typeof n.name!=="string")return null;return{name:n.name,path:typeof n.path==="string"?n.path:void 0,data:typeof n.data==="string"?n.data:void 0,mimeType:typeof n.mimeType==="string"?n.mimeType:void 0}},L),saveFile:(e,t,n)=>b("saveFile",[e,t,n],()=>{if(e.startsWith("data:"))return ue(e,t);let r=new Blob([e],{type:n||"text/plain"}),o=URL.createObjectURL(r),i=ue(o,t);return setTimeout(()=>URL.revokeObjectURL(o),1000),i}).then((r)=>typeof r==="string"?r:null),downloadFile:(e,t)=>b("downloadFile",[e,t],()=>ue(e,t)).then((n)=>typeof n==="string"?n:null)},Be={set:(e)=>b("shortcuts.set",[e.map(({symbol:t,...n})=>t?{...n,iconName:t}:n)],E).then((t)=>t!==!1),clear:()=>b("shortcuts.clear",[],E).then((e)=>e!==!1),onShortcut:(e)=>R("craftShortcut",(t)=>{if(typeof t.type==="string")e(t.type)})},Fe={update:(e)=>b("widget.update",[e],E).then((t)=>t!==!1),reload:()=>b("widget.reload",[],E).then((e)=>e!==!1)},Lt={portrait:"portrait-primary",portraitUpsideDown:"portrait-secondary",landscape:"landscape",landscapeLeft:"landscape-primary",landscapeRight:"landscape-secondary"};function Ce(){return x()?.screen?.orientation}var Ke={lock:(e)=>b("lockOrientation",[e],()=>{let t=Ce();return t?.lock?t.lock(Lt[e]).then(Oe,E):!1}).then((t)=>t!==!1),unlock:()=>b("unlockOrientation",[],()=>(Ce()?.unlock?.(),!0)).then((e)=>e!==!1)},$e={signInWithApple:()=>b("signInWithApple",[],L).then((e)=>{if(!e||typeof e!=="object"||typeof e.userId!=="string")return null;return e})},qe={isAvailable:()=>T("iap.purchase")!==null,products:(e)=>b("iap.getProducts",[e],()=>[]).then((t)=>Array.isArray(t)?t:[]),purchase:(e)=>b("iap.purchase",[e],L).then((t)=>t&&typeof t==="object"?t:null,(t)=>{if(/cancel/i.test(String(t?.message??t)))return null;throw t}),restore:()=>b("iap.restore",[],()=>[]).then((e)=>Array.isArray(e)?e:[])};function Vn(e,t){let n=t.delay??500,r=t.tolerance??10,o=null,i=null,a=!1,s=()=>{if(o)clearTimeout(o);if(o=null,i&&!a)t.onPressEnd?.();i=null},l=(m)=>{let u=m;if(u.button!==void 0&&u.button!==0)return;a=!1,i={x:u.clientX,y:u.clientY},t.onPressStart?.(),o=setTimeout(()=>{if(o=null,!i)return;a=!0,t.onLongPress({...i}),i=null},n)},d=(m)=>{if(!i)return;let u=m;if(Math.hypot(u.clientX-i.x,u.clientY-i.y)>r)s()},p=(m)=>{if(!a)return;a=!1,m.preventDefault(),m.stopPropagation()},c=(m)=>m.preventDefault();return e.addEventListener("pointerdown",l),e.addEventListener("pointermove",d),e.addEventListener("pointerup",s),e.addEventListener("pointercancel",s),e.addEventListener("pointerleave",s),e.addEventListener("click",p,!0),e.addEventListener("contextmenu",c),()=>{s(),e.removeEventListener("pointerdown",l),e.removeEventListener("pointermove",d),e.removeEventListener("pointerup",s),e.removeEventListener("pointercancel",s),e.removeEventListener("pointerleave",s),e.removeEventListener("click",p,!0),e.removeEventListener("contextmenu",c)}}function Rt(e,t,n){if(n<=1||t.width<=0)return 0;let r=Math.floor((e-t.left)/t.width*n);return Math.max(0,Math.min(n-1,r))}function Xn(e,t){let n=null,r=null,o=!1,i=0,a=(u)=>{let f=e.getBoundingClientRect();return Rt(u,{left:f.left+2,width:f.width-4},t.count())},s=(u)=>{let f=u;if(f.button!==void 0&&f.button!==0)return;let h=a(f.clientX);if(h!==t.selected())return;n=h,i=h,o=!1,r=f.pointerId;try{e.setPointerCapture?.(f.pointerId)}catch{}t.onPress?.(!0)},l=(u)=>{if(n===null)return;let f=a(u.clientX);if(f===i)return;o=!0,i=f,t.onScrub(f)},d=(u)=>{if(n===null)return;if(r!==null)try{e.releasePointerCapture?.(r)}catch{}if(t.onPress?.(!1),u&&o)t.onCommit(i);else if(o)t.onScrub(n);n=null,r=null},p=(u)=>{if(!o)return;o=!1,u.preventDefault(),u.stopPropagation()},c=()=>d(!0),m=()=>d(!1);return e.addEventListener("pointerdown",s),e.addEventListener("pointermove",l),e.addEventListener("pointerup",c),e.addEventListener("pointercancel",m),e.addEventListener("click",p,!0),()=>{e.removeEventListener("pointerdown",s),e.removeEventListener("pointermove",l),e.removeEventListener("pointerup",c),e.removeEventListener("pointercancel",m),e.removeEventListener("click",p,!0)}}function Jn(e,t,n){if(n<=0)return null;switch(e){case"ArrowRight":case"ArrowDown":return(t+1)%n;case"ArrowLeft":case"ArrowUp":return(t-1+n)%n;case"Home":return 0;case"End":return n-1;default:return null}}function Qn(e,t){e.querySelectorAll('[role="tab"]')[t]?.focus()}function Zn(e){let t=(n)=>{if(!n.target?.closest?.("[data-native-pressable]"))return;let o=T("haptics.prepare");if(o)Promise.resolve().then(()=>o("impact")).catch(()=>{})};return e.addEventListener("touchstart",t,{passive:!0,capture:!0}),()=>e.removeEventListener("touchstart",t,{capture:!0})}function fe(e){let t=x();try{return Boolean(t?.matchMedia?.(e).matches)}catch{return!1}}function Ue(e){return e!==null&&e!==void 0&&e!=="false"&&e!=="0"}function We(){let e=x()?.document?.documentElement,t=Number.parseFloat(e?.style?.getPropertyValue("--craft-font-scale")||"");return{fontScale:Number.isFinite(t)&&t>0?t:1,reduceMotion:Ue(e?.getAttribute("data-craft-reduce-motion"))||fe("(prefers-reduced-motion: reduce)"),reduceTransparency:Ue(e?.getAttribute("data-craft-reduce-transparency"))||fe("(prefers-reduced-transparency: reduce)"),colorScheme:e?.classList?.contains("dark")||fe("(prefers-color-scheme: dark)")?"dark":"light"}}function Pt(e){let t=We(),n=Number(e?.fontScale);return{contentSizeCategory:typeof e?.contentSizeCategory==="string"?e.contentSizeCategory:void 0,fontScale:Number.isFinite(n)&&n>0?n:t.fontScale,reduceMotion:typeof e?.reduceMotion==="boolean"?e.reduceMotion:t.reduceMotion,reduceTransparency:typeof e?.reduceTransparency==="boolean"?e.reduceTransparency:t.reduceTransparency,colorScheme:e?.colorScheme==="dark"||e?.colorScheme==="light"?e.colorScheme:t.colorScheme}}function Ye(e,t={}){if(t.immediate!==!1)e(We());return R("craftAppearance",(n)=>e(Pt(n)))}function rr(e){return R("craftResume",(t)=>e({backgroundedMs:Number(t.backgroundedMs)||0}))}function or(e){return R("craftMemoryWarning",()=>e())}function je(e){return(t)=>{Promise.resolve().then(()=>e(t)).then(()=>B.complete(!0),()=>B.complete(!1))}}function ir(e){let t=je(e);return R("craftSilentPush",(n)=>t(n.payload??{}))}function ar(e){let t=je(()=>e());return R("craftBackgroundRefresh",()=>t(void 0))}import{haptics as Mt}from"craft-native/mobile";function me(){if(typeof window>"u")return;return window}function F(e=me()){if(!e)return 0;if(typeof e.scrollY==="number")return e.scrollY;if(typeof e.scrollTop==="number")return e.scrollTop;return e.document?.scrollingElement?.scrollTop??0}function Ct(e,t=me()){if(!t)return()=>{};let n=!1,r=typeof requestAnimationFrame==="function"?requestAnimationFrame:(i)=>setTimeout(i,16),o=()=>{if(n)return;n=!0,r(()=>{n=!1,e(F(t))})};return e(F(t)),t.addEventListener("scroll",o,{passive:!0}),()=>t.removeEventListener("scroll",o)}function Ot(e,t){let n=Math.max(0,-e),r=e<=0?Math.max(0,t)*0.5:0;return Math.round(Math.max(n,r))}function cr(e){let t=e.host??me();if(!t)return()=>{};let n=e.threshold??72,r=null,o=!1,i=!1,a=typeof requestAnimationFrame==="function"?requestAnimationFrame:(h)=>setTimeout(h,16),s=null,l=(h)=>{s=null,e.onPull?.(h,o,{bounce:Math.min(h,Math.max(0,-F(t)))})},d=(h)=>{let A=s!==null;if(s=h,A)return;a(()=>{if(s!==null)l(s)})},p=(h)=>{let A=h.touches?.[0];return A?A.clientY:null},c=(h)=>{if(i||F(t)>0)return;r=p(h),o=!1},m=(h)=>{if(r===null)return;let A=p(h);if(A===null)return;let N=Ot(F(t),A-r);if(!o&&N>=n)o=!0,Promise.resolve(Mt.impact("medium")).catch(()=>{});else if(o&&N<n*0.8)o=!1;d(N)},u=async()=>{if(r===null)return;if(r=null,!o){l(0);return}o=!1,i=!0,l(n);try{await e.onRefresh()}finally{i=!1,l(0)}},f=()=>{if(r===null)return;r=null,o=!1,l(0)};return t.addEventListener("touchstart",c,{passive:!0}),t.addEventListener("touchmove",m,{passive:!0}),t.addEventListener("touchend",u),t.addEventListener("touchcancel",f),()=>{s=null,t.removeEventListener("touchstart",c),t.removeEventListener("touchmove",m),t.removeEventListener("touchend",u),t.removeEventListener("touchcancel",f)}}function It(e,t=52){let n=Math.max(1,t),r=Math.min(1,Math.max(0,e/n)),o=e<0?1+Math.min(0.1,-e/600):1;return{progress:Math.round(r*1000)/1000,stretch:Math.round(o*1000)/1000}}function ur(e,t={}){let n="",r=()=>t.title?.offsetHeight||t.height||52;return Ct((o)=>{let i=It(o,r()),a=`${i.progress}|${i.stretch}`;if(a===n)return;n=a,e.style.setProperty("--native-nav-progress",String(i.progress)),e.style.setProperty("--native-nav-stretch",String(i.stretch)),t.onChange?.(i)},t.host)}function dr(e){if(!e||typeof window>"u")return;let t=window.document?.querySelector(e);return t?t:void 0}function Ve(){if(typeof window>"u")return;return window}var ze="__stxPushed",Nt="__stxScroll";function Ht(e=Ve()){let t=e?.history?.state;if(t===null||t===void 0)return!1;if(typeof t!=="object")return!0;let n=t;if(ze in n)return n[ze]===!0;return!(Nt in n)}function fr(e=Ve()){if(!Ht(e))return!1;return e.history.back(),!0}function mr(e,t,n=50){let r=e[e.length-1];if(e.length>=2&&e[e.length-2].path===t)e.pop();else if(!r||r.path!==t)e.push({path:t,title:""});if(e.length>n)e.splice(0,e.length-n);return{current:e[e.length-1],previous:e[e.length-2]??null}}function gr(e,t,n=12){let r=e?.title.trim()??"";return r&&r.length<=n?r:t}function hr(){if(typeof window>"u")return[];let e=window;return e.__stacksNavTrail??=[]}function _t(e,t=Dt()){let n;try{n=new URL(e)}catch{return null}let r=`${n.search}${n.hash}`;if(n.protocol==="http:"||n.protocol==="https:"){if(!t||n.origin!==t)return null;return`${n.pathname||"/"}${r}`}return`${`/${[n.host,n.pathname.replace(/^\/+/,"")].filter(Boolean).join("/")}`}${r}`}function Dt(){if(typeof window>"u")return;return window.location?.origin}var Ge="stacks-mobile-deep-link";function br(e,t){let n=(r)=>{let o=_t(r);if(o)e(o)};return t.getInitialURL().then((r)=>{if(!r)return;try{if(sessionStorage.getItem(Ge)===r)return;sessionStorage.setItem(Ge,r)}catch{}n(r)}).catch(()=>{}),t.onLink((r,o)=>{if(o?.initial)return;n(r)})}var yr=30;function Bt(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,o=(t.longitude-e.longitude)*n,i=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(o/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(i)))}function Ft(e,t=25){let n=new Set;return e.filter((r)=>Number.isFinite(r.latitude)&&Number.isFinite(r.longitude)&&Number.isFinite(r.timestamp)&&r.accuracy>=0&&r.accuracy<=t).sort((r,o)=>r.timestamp-o.timestamp).filter((r)=>{if(n.has(r.timestamp))return!1;return n.add(r.timestamp),!0})}function Xe(e,t={}){let n=Ft(e,t.maxAccuracyM??25),r=t.paceWindowS??30,o=[],i=0,a=0,s=null;for(let c of n){let m=o[o.length-1],u=s?(c.timestamp-s.timestamp)/1000:0;if(s=c,!m){o.push({fix:c,cumM:0});continue}if(u>30){o.push({fix:c,cumM:i});continue}let f=(c.timestamp-m.fix.timestamp)/1000,h=Bt(m.fix,c),A=Math.min(10,Math.max(3,m.fix.accuracy,c.accuracy));if(h<A)continue;if(i+=h,f>0&&h/f>=0.5)a+=f;o.push({fix:c,cumM:i})}let l=o[o.length-1],d=null,p=null;if(l){let c=l.fix.timestamp-r*1000,m=o.find((h)=>h.fix.timestamp>=c)??l,u=l.cumM-m.cumM,f=(l.fix.timestamp-m.fix.timestamp)/1000;if(u>=20&&f>0)p=u/f,d=f/(u/1000)}return{distanceM:i,movingS:a,paceSPerKm:d,averagePaceSPerKm:i>=50&&a>0?a/(i/1000):null,speedMps:p,accuracyM:n.length?n[n.length-1].accuracy:e.length?e[e.length-1].accuracy??null:null,fixes:n.length}}function xr(e){if(!e||!Number.isFinite(e)||e>3600)return"–";let t=Math.round(e);return`${Math.floor(t/60)}:${String(t%60).padStart(2,"0")}`}function Sr(e){return e&&Number.isFinite(e)?(e*3.6).toFixed(1):"–"}var Je={distanceM:0,movingS:0,paceSPerKm:null,averagePaceSPerKm:null,speedMps:null,accuracyM:null,fixes:0};function wr(e){let t=e.location,n=e.intervalMs??3000,r=Je,o=null,i=()=>typeof document<"u"&&document.visibilityState==="hidden";async function a(){let d=await t.readRecording();return r=Xe(d,e),e.onUpdate?.(r),r}function s(){l(),o=setInterval(()=>{if(!i())a().catch(()=>{})},n)}function l(){if(o)clearInterval(o);o=null}return{get stats(){return r},async start(){return await t.startRecording({enableHighAccuracy:!0,...e.locationOptions}),r=Je,e.onUpdate?.(r),s(),r},async attach(){let d=await t.getRecordingState().catch(()=>null);if(!d?.active)return null;if(await a().catch(()=>{}),!d.paused)s();return d},async pause(){l(),await t.pauseRecording(),await a().catch(()=>{})},async resume(){await t.resumeRecording(),s()},async stop(){l();let p=(await t.stopRecording())?.locations??[];return r=Xe(p,e),e.onUpdate?.(r),p},refresh:a}}var Ar=150;function Kt(e,t){let n=Math.PI/180,r=(t.latitude-e.latitude)*n,o=(t.longitude-e.longitude)*n,i=Math.sin(r/2)**2+Math.cos(e.latitude*n)*Math.cos(t.latitude*n)*Math.sin(o/2)**2;return 12742017.6*Math.asin(Math.min(1,Math.sqrt(i)))}function G(e,t){let n=[...e].sort((r,o)=>r-o);return n[Math.min(n.length-1,Math.floor(t*n.length))]}function Er(e,t){let n=(e||[]).filter((a)=>Number.isFinite(a?.latitude)&&Number.isFinite(a?.longitude)),r=n.map((a)=>Number(a.accuracy)).filter((a)=>Number.isFinite(a)&&a>=0),o=r.length?G(r,0.5):Number.POSITIVE_INFINITY,i=0;if(n.length){let a={latitude:G(n.map((s)=>s.latitude),0.5),longitude:G(n.map((s)=>s.longitude),0.5)};i=G(n.map((s)=>Kt(a,s)),0.8)}if(n.length>=10&&i>150&&o<=15)return"outside";if(t<150)return"unsure";if(n.length<3||o>30||i<25)return"indoors";if(i<50&&o>10)return"indoors";return"unsure"}function Tr(e){let n=String(e||"").trim().toLowerCase().replace(",",".").match(/^(\d+(?:\.\d+)?)\s*(km|k|m|mi)?$/);if(!n)return null;let r=Number(n[1]),o=n[2]||(r>100?"m":"km"),i=o==="m"?r/1000:o==="mi"?r*1.609344:r;return i>0&&i<1000?Math.round(i*1000)/1000:null}var J=new Set,Qe=!1,V=null;function $t(e){return e.isConnected&&e.getClientRects().length>0}function Ze(){return[...J].find((e)=>$t(e.element))}function X(){let e=Ze(),t=Boolean(e);if(t===Qe)return;if(Qe=t,t)M.enable(e?.tintColor?{tintColor:e.tintColor}:{});else M.disable()}function qt(){let e=Ze();if(!e){M.end();return}Promise.resolve().then(()=>e.run()).catch(()=>{}).finally(()=>M.end())}function Pr(e,t){let n={element:e,tintColor:t.tintColor,run:t.onRefresh};J.add(n);let r=e.ownerDocument?.defaultView;if(!V){let o=M.onRefresh(qt),i=()=>X();r?.addEventListener("stx:load",i),V=()=>{o(),r?.removeEventListener("stx:load",i)}}return X(),r?.requestAnimationFrame?.(()=>X()),()=>{if(J.delete(n),J.size===0)V?.(),V=null;X()}}var Cr=0.5;function Ut(e,t,n){let r=[];if(n.includes("large")||n.length===0)r.push({name:"large",y:0});if(n.includes("medium"))r.push({name:"medium",y:Math.max(0,Math.round(e-t*0.5))});return r.push({name:"dismiss",y:Math.max(1,e)}),r.sort((o,i)=>o.y-i.y)}function Wt(e){let{y:t,velocity:n,stops:r}=e,o=r.filter((s)=>s.name!=="dismiss"),i=r.find((s)=>s.name==="dismiss");if(o.length===0)return"dismiss";if(n>0.5)return(r.filter((l)=>l.y>t+1)[0]??i).name;if(n<-0.5){let s=o.filter((l)=>l.y<t-1);return(s[s.length-1]??o[0]).name}let a=o[o.length-1];if(t>a.y+(i.y-a.y)*0.5)return"dismiss";return o.reduce((s,l)=>Math.abs(l.y-t)<Math.abs(s.y-t)?l:s).name}function Yt(e,t=400){if(e<=0)return 0;return e*t*0.55/(t+e*0.55)}function Or(e){let{panel:t}=e,n=null,r=[],o=0,i=()=>e.viewport?.()??t.ownerDocument?.defaultView?.innerHeight??800,a=()=>Ut(t.offsetHeight||t.getBoundingClientRect().height,i(),e.detents()),s=(p)=>{let c=p;if(c.button!==void 0&&c.button!==0)return;if(c.target?.closest?.("button, a, input, select, textarea, [role=button]"))return;let m=a().find((u)=>u.name===e.detent())?.y??0;n={y:c.clientY,base:m,pointerId:c.pointerId},o=m,r=[{y:m,t:c.timeStamp}],t.classList.add("is-dragging");try{p.currentTarget?.setPointerCapture?.(c.pointerId)}catch{}},l=(p)=>{if(!n)return;let c=p,m=n.base+c.clientY-n.y;o=m<0?-Yt(-m):m,r.push({y:o,t:c.timeStamp});while(r.length>2&&c.timeStamp-r[0].t>100)r.shift();t.style.transform=`translateY(${o}px)`;let u=t.offsetHeight||1;t.parentElement?.style.setProperty("--native-sheet-presence",String(Math.max(0,Math.min(1,1-o/u))))},d=(p)=>{if(!n)return;let c=p;n=null;let m=r[0],u=Math.max(1,c.timeStamp-m.t),f=(o-m.y)/u;t.classList.remove("is-dragging"),t.style.transform="",t.parentElement?.style.removeProperty("--native-sheet-presence"),e.onSettle(Wt({y:o,velocity:f,stops:a()}))};for(let p of e.handles)p.addEventListener("pointerdown",s),p.addEventListener("pointermove",l),p.addEventListener("pointerup",d),p.addEventListener("pointercancel",d);return()=>{for(let p of e.handles)p.removeEventListener("pointerdown",s),p.removeEventListener("pointermove",l),p.removeEventListener("pointerup",d),p.removeEventListener("pointercancel",d)}}var et=0,ge="";function Ir(e){let t=e.ownerDocument,n=[],r=e;while(r.parentElement&&r!==t.body){for(let a of Array.from(r.parentElement.children)){if(a===r||a.hasAttribute("inert")||a.hasAttribute("data-native-dialog"))continue;if(["SCRIPT","STYLE","TEMPLATE","LINK"].includes(a.tagName))continue;a.setAttribute("inert",""),n.push(a)}r=r.parentElement}let o=t.documentElement;if(et++===0)ge=o.style.overflow||"",o.style.overflow="hidden";let i=!1;return()=>{if(i)return;i=!0;for(let a of n)a.removeAttribute("inert");if(--et===0)if(ge)o.style.overflow=ge;else o.style.removeProperty("overflow")}}function Nr(e){let t=e.ownerDocument;if(e.parentElement===t.body)return()=>{};let n=t.createComment("native-sheet");return e.parentNode?.insertBefore(n,e),t.body.appendChild(e),()=>{if(n.parentNode)n.parentNode.insertBefore(e,n);else e.remove();n.remove()}}function Hr(e,t){let n=e.documentElement;if(!t){n.removeAttribute("data-native-sheet-card");return}let r=e.defaultView,o=(r?.scrollY??0)+(r?.innerHeight??800)/2;n.style.setProperty("--native-sheet-card-origin",`${Math.round(o)}px`),n.setAttribute("data-native-sheet-card","")}function jt(e,t){e.style.setProperty("--native-font-scale",String(t.fontScale)),e.toggleAttribute("data-native-reduce-motion",t.reduceMotion),e.toggleAttribute("data-native-reduce-transparency",t.reduceTransparency)}function zt(e){let t=e.replace(/\s+/g,"").toLowerCase();return!t||t==="transparent"||/^rgba\(\d+,\d+,\d+,0(\.0+)?\)$/.test(t)||/\/0(\.0+)?\)$/.test(t)}function Gt(e){let t=e.defaultView;if(!t?.getComputedStyle)return null;for(let n of[e.body,e.documentElement]){if(!n)continue;let r=t.getComputedStyle(n).backgroundColor;if(r&&!zt(r))return r}return null}function Vt(e){if(e.documentElement.classList.contains("dark"))return!0;if(e.documentElement.classList.contains("light"))return!1;return Boolean(e.defaultView?.matchMedia?.("(prefers-color-scheme: dark)").matches)}function Fr(e,t={}){let n=t.root??e.documentElement;D.setKeyboardAccessory(t.keyboardAccessory===!0);let r="",o="",i=()=>{let p=Gt(e);if(p&&p!==r)r=p,D.setUnderPageColor(p);let c=Vt(e)?"light":"dark";if(c!==o)o=c,z.setStyle(c)},a=Ye((p)=>{jt(n,p),i()}),s=e.defaultView,l=typeof s?.MutationObserver==="function"?new s.MutationObserver(i):null;l?.observe(e.documentElement,{attributes:!0,attributeFilter:["class","style","data-theme"]});let d=s?.matchMedia?.("(prefers-color-scheme: dark)");return d?.addEventListener?.("change",i),s?.addEventListener("stx:load",i),i(),()=>{a(),l?.disconnect(),d?.removeEventListener?.("change",i),s?.removeEventListener("stx:load",i)}}var $r=64;var Xt=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,Jt=/^(?:0|[1-9]\d*)$/;function nt(e){let t=[],n=[],r=e&&typeof e==="object"&&!Array.isArray(e)?e:{};for(let[o,i]of Object.entries(r)){let a=i&&typeof i==="object"?i:null;if(!a){n.push(`spotlight kind "${o}" is not an object`);continue}let{slots:s,route:l}=a,d=typeof a.noun==="string"&&a.noun.trim()?a.noun.trim():"Item";if(!Xt.test(o)||o.includes("-slot-")){n.push(`spotlight kind "${o}" is not a usable name: lowercase letters, digits and single dashes, and never "-slot-"`);continue}if(typeof s!=="number"||!Number.isInteger(s)||s<=0||s>64){n.push(`spotlight kind "${o}" needs slots between 1 and 64, not ${String(s)}`);continue}if(typeof l!=="string"||!l.startsWith("/")||!l.includes(":id")){n.push(`spotlight kind "${o}" needs a route starting with "/" and carrying ":id", not ${String(l)}`);continue}t.push({name:o,slots:s,route:l,noun:d})}return{kinds:t,problems:n}}function q(e,t){return e.find((n)=>n.name===t)??null}function K(e,t,n){let r=q(e,t);if(!r||!Number.isInteger(n)||n<0||n>=r.slots)return null;return`${t}-slot-${n}`}function Qt(e,t){if(typeof t!=="string")return null;let n=t.lastIndexOf("-slot-");if(n<=0)return null;let r=t.slice(0,n),o=t.slice(n+6);if(!Jt.test(o))return null;let i=Number(o);return K(e,r,i)===t?{kind:r,slot:i}:null}function rt(e){return e.flatMap((t)=>Array.from({length:t.slots},(n,r)=>`${t.name}-slot-${r}`))}function qr(e,t){let n=e&&typeof e==="object"?e:{};if(n.enabled===!1)return[];let o=[...(Array.isArray(n.activityTypes)?n.activityTypes.filter((i)=>typeof i==="string"&&i.trim().length>0):[]).map((i)=>i.trim()),...rt(nt(n.kinds).kinds)];return[...new Set(o)].map((i)=>`${t}.${i}`)}function ot(e,t,n){let r=typeof n.name==="string"?n.name.replace(/\s+/g," ").trim():"";if(!r)return`${q(e,t)?.noun??"Item"} #${n.id}`;return r.length>120?`${r.slice(0,119).trimEnd()}…`:r}function Zt(e,t,n,r,o=Date.now()){let i=q(e,n);if(!i||!Number.isInteger(r.id)||r.id<=0)return null;let a=t.filter((f)=>f.kind===n),s=ot(e,n,r),l=a.find((f)=>f.itemId===r.id)??null,d=l?null:rn(a,i.slots),p=l||d!==null?null:on(a),c=l?.slot??d??p?.slot;if(c===void 0||c===null)return null;let m={kind:n,slot:c,itemId:r.id,title:s,donatedAt:o},u=t.filter((f)=>f.kind!==n||f.slot!==c&&f.itemId!==r.id);return{entries:it(e,[...u,m]),entry:m,evicted:p,changed:!l||l.title!==s}}function en(e,t,n){let r=e.find((o)=>o.kind===t&&o.itemId===n)??null;return{entries:r?e.filter((o)=>o!==r):[...e],removed:r}}function tn(e,t,n){let r=Qt(e,n);if(!r)return null;let o=t.find((a)=>a.kind===r.kind&&a.slot===r.slot),i=q(e,r.kind)?.route;return o&&i?i.replace(":id",String(o.itemId)):null}function nn(e,t){if(!Array.isArray(t))return[];let n=new Map,r=new Set;for(let o of t){if(!o||typeof o!=="object")continue;let i=o,{kind:a,slot:s,itemId:l,title:d,donatedAt:p}=i;if(typeof a!=="string"||typeof s!=="number"||K(e,a,s)===null)continue;if(typeof l!=="number"||!Number.isInteger(l)||l<=0)continue;let c=`${a}-slot-${s}`,m=`${a}#${l}`;if(n.has(c)||r.has(m))continue;n.set(c,{kind:a,slot:s,itemId:l,title:typeof d==="string"&&d.trim()?d:ot(e,a,{id:l}),donatedAt:typeof p==="number"&&Number.isFinite(p)&&p>0?p:0}),r.add(m)}return it(e,[...n.values()])}function it(e,t){let n=new Map(e.map((r,o)=>[r.name,o]));return[...t].sort((r,o)=>(n.get(r.kind)??0)-(n.get(o.kind)??0)||r.slot-o.slot)}function rn(e,t){let n=new Set(e.map((r)=>r.slot));for(let r=0;r<t;r++)if(!n.has(r))return r;return null}function on(e){return e.reduce((t,n)=>!t||n.donatedAt<t.donatedAt?n:t,null)}function an(){let e=globalThis.craft;return e&&typeof e==="object"?e.siri:void 0}var sn="stacks_spotlight_index",ln=3000;function Ur(e){let t=e.onProblem??((v)=>console.warn(`[spotlight] ${v}`)),n=Array.isArray(e.kinds)?{kinds:[...e.kinds],problems:[]}:nt(e.kinds);for(let v of n.problems)t(v);let r=e.enabled===!1?[]:n.kinds,o=e.storageKey??sn,i=e.legacyStorageKeys??[],a=e.timeoutMs??ln,s=e.now??(()=>Date.now()),l=e.bridge??an,d=null;function p(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function c(){if(d)return d;d=[];let v=p();if(!v)return d;try{let y=[o,...i].map((S)=>v.getItem(S)).find((S)=>S);d=y?nn(r,JSON.parse(y)):[]}catch{d=[]}return d}function m(v){d=v;let y=p();if(!y)return;try{y.setItem(o,JSON.stringify(v));for(let S of i)y.removeItem(S)}catch{}}async function u(v){if(!v)return null;let y;try{return await Promise.race([v,new Promise((S)=>{y=setTimeout(()=>S(null),a)})])}catch{return null}finally{if(y!==void 0)clearTimeout(y)}}let f=Promise.resolve();function h(v){let y=f.then(v,v);return f=y.catch(()=>{return}),y}async function A(v,y){let S=l()?.register;if(!S||r.length===0)return!1;return h(async()=>{let k=Zt(r,c(),v,y,s()),C=k&&K(r,v,k.entry.slot);if(!k||!C)return!1;if(!k.changed)return m(k.entries),!0;let H=await u(S(k.entry.title,C))!==null;if(H)m(k.entries);return H})}async function N(v,y){let S=l()?.remove;if(!S)return!1;return h(async()=>{let{entries:k,removed:C}=en(c(),v,y);if(!C)return!1;let H=K(r,v,C.slot),gt=H?await u(S(H))!==null:!1;return m(k),gt})}async function ft(v,y){let S=q(r,v)?.slots;if(!S||!l()?.register)return 0;let k=0;for(let C of[...y].slice(0,S).reverse())if(await A(v,C))k++;return k}async function mt(){let v=l()?.remove;if(!v)return m([]),0;return h(async()=>{let y=0;for(let S of c()){let k=K(r,S.kind,S.slot);if(k&&await u(v(k))!==null)y++}return m([]),y})}return{kinds:r,index:A,sync:ft,remove:N,clear:mt,routeFor:(v)=>tn(r,c(),v),entries:()=>c(),activityTypes:(v)=>rt(r).map((y)=>`${v}.${y}`),reset:()=>{d=null}}}var tt=["craftShortcut","craftSiriShortcut"];function Wr(e,t){let n=(r)=>{let o=r.detail,i=typeof o==="string"?o:o&&typeof o==="object"?o.action??o.type:null,a=typeof i==="string"?e.routeFor(i):null;if(a)t(a)};if(typeof globalThis.addEventListener!=="function")return()=>{};for(let r of tt)globalThis.addEventListener(r,n);return()=>{for(let r of tt)globalThis.removeEventListener(r,n)}}import{tabBar as cn}from"craft-native/mobile";var un=cn;function dn(e){return Array.from(e.querySelectorAll("a[data-native-tab]")).map((t)=>({id:t.getAttribute("href")||"",title:t.getAttribute("data-native-tab")||t.getAttribute("aria-label")||"",symbol:t.getAttribute("data-native-tab-symbol")||"circle",badge:(t.querySelector(".native-tab-badge")?.textContent||"").trim(),current:t.hasAttribute("data-stx-nav-current")||t.classList.contains("is-active")})).filter((t)=>t.id&&t.title)}function pn(e){return{tabs:e.map(({id:n,title:r,symbol:o,badge:i})=>i?{id:n,title:r,symbol:o,badge:i}:{id:n,title:r,symbol:o}),selected:e.find((n)=>n.current)?.id}}function st(){if(typeof window>"u")return;let e=window.stxRouter;return e&&typeof e==="object"?e:void 0}function fn(){return typeof st()?.selectTab==="function"}function zr(e,t={}){let n=(r)=>{if(fn()||r.defaultPrevented)return;let o=r.target?.closest?.("a[data-native-tab]");if(!o||!e.contains(o))return;if(!o.hasAttribute("data-stx-nav-current")&&!o.classList.contains("is-active")&&o.getAttribute("aria-current")!=="page")return;r.preventDefault();let i=e.ownerDocument.defaultView;if(t.scrollToTop)t.scrollToTop();else i?.scrollTo?.({top:0,behavior:i.matchMedia?.("(prefers-reduced-motion: reduce)").matches?"auto":"smooth"});i?.dispatchEvent(new CustomEvent("stx:tabreselect",{detail:{href:o.getAttribute("href")||""}}))};return e.addEventListener("click",n),()=>e.removeEventListener("click",n)}function at(e){let t=e.trim();return/^#[0-9a-f]{6}$/i.test(t)?t:void 0}function Gr(e,t={}){let n=t.api??un;if(!n.isAvailable())return null;let r=t.hidden??(()=>Boolean(e.ownerDocument?.querySelector("[data-native-hide-tab-bar]"))),o=typeof getComputedStyle==="function"?getComputedStyle(e):null,i=at(o?.getPropertyValue("--native-tab-active")||""),a=at(o?.getPropertyValue("--native-tab-active-dark")||""),s="",l=()=>{if(r()){if(s!=="hidden")n.hide();s="hidden";return}let{tabs:m,selected:u}=pn(dn(e)),f=JSON.stringify({tabs:m,selected:u});if(f===s)return;let h=s&&s!=="hidden"?JSON.parse(s):null;if(h&&u&&JSON.stringify(h.tabs)===JSON.stringify(m))n.select(u);else n.set(m,{selected:u,tint:i,tintDark:a});s=f},d=typeof MutationObserver==="function"?new MutationObserver(l):null;d?.observe(e,{attributes:!0,attributeFilter:["data-stx-nav-current","class"],childList:!0,subtree:!0,characterData:!0});let p=n.onSelect((m)=>{let u=st();if(u?.selectTab){u.selectTab(m);return}Array.from(e.querySelectorAll("a[data-native-tab]")).find((h)=>h.getAttribute("href")===m)?.click()}),c=()=>l();if(typeof window<"u")window.addEventListener("stx:load",c),window.addEventListener("stx:screen-shown",c);return l(),()=>{if(d?.disconnect(),p(),typeof window<"u")window.removeEventListener("stx:load",c),window.removeEventListener("stx:screen-shown",c);n.hide()}}var bn={isAvailable:()=>g(()=>he.isAvailable()),getBiometricType:()=>g(()=>he.getBiometricType()),authenticate:(e)=>g(()=>he.authenticate(e))},vn={takePicture:(e)=>g(()=>Q.takePicture(e)),pickImage:()=>g(()=>Q.pickImage()),pickMultiple:(e)=>g(()=>Q.pickMultiple(e)),isAvailable:()=>g(()=>Q.isAvailable())},yn={getInfo:()=>g(()=>O.getInfo()),getCapabilities:()=>g(()=>O.getCapabilities()),isMobile:()=>O.isMobile(),isIOS:()=>O.isIOS(),isAndroid:()=>O.isAndroid(),getLocale:()=>O.getLocale(),getTimezone:()=>O.getTimezone()},xn=gn,Sn={getCurrentPosition:(e)=>g(()=>P.getCurrentPosition(e)),watchPosition:(e,t)=>P.watchPosition(e,t),clearWatch:(e)=>P.clearWatch(e),startRecording:(e)=>g(()=>P.startRecording(e)),pauseRecording:()=>g(()=>P.pauseRecording()),resumeRecording:()=>g(()=>P.resumeRecording()),stopRecording:()=>g(()=>P.stopRecording()),getRecordingState:()=>g(()=>P.getRecordingState()),readRecording:()=>g(()=>P.readRecording())},wn={show:(e)=>g(()=>ee.show(e)),schedule:(e)=>g(()=>ee.schedule(e)),cancelAll:()=>g(()=>ee.cancelAll()),setBadge:(e)=>g(()=>ee.setBadge(e))},kn={check:(e)=>g(()=>W.check(e)),request:(e)=>g(()=>W.request(e)),checkMultiple:(e)=>g(()=>W.checkMultiple(e)),requestMultiple:(e)=>g(()=>W.requestMultiple(e)),openSettings:()=>g(()=>W.openSettings())},An={set:(e,t)=>g(()=>te.set(e,t)),get:(e)=>g(()=>te.get(e)),delete:(e)=>g(()=>te.delete(e)),clear:()=>g(()=>te.clear())},En={share:(e)=>g(()=>dt.share(e)),isAvailable:()=>dt.isAvailable()},Tn={request:()=>g(()=>mn.request())},ne={impact:(e)=>Promise.resolve().then(()=>Z.impact(e)).catch(()=>{}),notification:(e)=>Promise.resolve().then(()=>Z.notification(e)).catch(()=>{}),selection:()=>Promise.resolve().then(()=>Z.selection()).catch(()=>{}),vibrate:(e)=>Promise.resolve().then(()=>Z.vibrate(e)).catch(()=>{}),prepare:(e)=>{let t=T("haptics.prepare");return t?Promise.resolve().then(()=>t(e)).then(()=>{},()=>{}):Promise.resolve()}};function pt(e){if(typeof e==="string")return e.trim()||null;if(!e||typeof e!=="object")return null;let t=e.url;return typeof t==="string"&&t.trim()?t:null}var Ln={async getInitialURL(){if(!await I())return null;return pt(await lt.getInitialURL?.())},onLink(e){let t=null,n=!1,r=()=>{if(n)return;t=lt.onLink?.((o,i)=>{let a=pt(o);if(a)e(a,{initial:i?.initial===!0})})??null};if(oe()?.craft)r();else I().then(r);return()=>{n=!0,t?.()}}},Rn={enable:()=>g(()=>ct.enable()),disable:()=>g(()=>ct.disable())},Pn={isAvailable:()=>ye.isAvailable(),speak:(e,t)=>g(()=>ye.speak(e,t)),stop:()=>g(()=>ye.stop())},Mn={getStatus:()=>g(()=>ut.getStatus()),onChange:(e)=>ae(()=>ut.onChange(e))},Cn={register:()=>g(()=>ve.register()),onToken:(e)=>ve.onToken(e),onNotification:(e)=>ae(()=>ve.onNotification(e))},On={requestAuthorization:(e,t)=>g(()=>U.requestAuthorization(e,t)),getData:(e,t)=>g(()=>U.getData(e,t)),saveWorkout:(e)=>g(()=>U.saveWorkout(e)),getWorkouts:(e)=>g(()=>U.getWorkouts(e)),getDailyStatistics:(e,t)=>g(()=>U.getDailyStatistics(e,t))},In={start:(e)=>g(()=>be.start(e)),update:(e)=>g(()=>be.update(e)),end:()=>g(()=>be.end())},Nn={send:(e)=>g(()=>Y.send(e)),updateContext:(e)=>g(()=>Y.updateContext(e)),isReachable:()=>g(()=>Y.isReachable()),onMessage:(e)=>Y.onMessage(e),onReachabilityChange:(e)=>Y.onReachabilityChange(e)},Zr=hn;function oe(){return x()}function re(){let e=oe()?.craft;if(!e||typeof e!=="object")return null;if(!("platform"in e)||e.platform!=="ios"&&e.platform!=="android")return null;let t="capabilities"in e?e.capabilities:void 0,n=t&&typeof t==="object"&&!Array.isArray(t)?Object.fromEntries(Object.entries(t).filter(([,r])=>typeof r==="boolean")):{};return{platform:e.platform,capabilities:n}}function xe(){return re()!==null}function Hn(e=2000){if(xe()||ie())return Promise.resolve(!0);let t=oe();if(!t||!(t.craft||t.webkit?.messageHandlers?.craft))return Promise.resolve(!1);return new Promise((n)=>{let r=()=>{clearTimeout(o),t.removeEventListener("craftReady",r),n(xe())},o=setTimeout(r,e);t.addEventListener("craftReady",r,{once:!0})})}function _n(e){let t=oe();if(!t)return()=>{};if(re()){let r=!1;return queueMicrotask(()=>{if(!r)e(new Event("craftReady"))}),()=>{r=!0}}let n=(r)=>{if(!re())return;t.removeEventListener("craftReady",n),e(r)};return t.addEventListener("craftReady",n),()=>t.removeEventListener("craftReady",n)}async function Dn(e){await ne.impact("light");try{let t=await e();return await ne.notification("success"),t}catch(t){throw await ne.notification("error"),t}}var eo={get nativeBridge(){return re()},biometrics:bn,camera:vn,device:yn,haptics:ne,lifecycle:xn,location:Sn,notifications:wn,permissions:kn,secureStorage:An,share:En,appReview:Tn,deepLinks:Ln,keepAwake:Rn,speech:Pn,network:Mn,pushNotifications:Cn,health:On,liveActivities:In,watchConnectivity:Nn,dialog:_,contextMenu:pe,browser:Ie,symbols:Ne,statusBar:z,chrome:D,refresh:M,background:B,clipboard:He,db:_e,files:De,shortcuts:Be,widgets:Fe,orientation:Ke,auth:$e,storeKit:qe,isNativeMobile:xe,whenNative:Hn,onReady:_n,withFeedback:Dn};export{Bn as BRIDGE_WAIT_MS,Ar as INDOOR_CHECK_AFTER_S,$r as MAX_SPOTLIGHT_SLOTS_PER_KIND,yr as ROUTE_GAP_S,Cr as SHEET_FLICK_VELOCITY,g as afterBridge,Tn as appReview,jt as applyAppearance,$e as auth,gr as backLabelFor,B as background,bn as biometrics,j as bridgePending,Ie as browser,b as callNative,vn as camera,Ht as canGoBack,D as chrome,He as clipboard,Yn as confirmAction,pe as contextMenu,x as craftHost,ht as craftRoot,wr as createRouteRecorder,Ur as createSpotlightIndex,We as currentAppearance,_e as db,_t as deepLinkPath,Ln as deepLinks,yn as device,_ as dialog,mr as enterNavTrail,De as files,Bt as fixDistance,Qn as focusSegment,br as followDeepLinks,re as getNativeMobileBridge,fr as goBack,zr as handleTabReselect,ne as haptics,ie as hasNativeMobileHost,On as health,Er as indoorVerdict,Fr as installNativeChrome,Zn as installPressables,xe as isNativeMobile,$t as isShown,Rn as keepAwake,It as largeTitleMetrics,xn as lifecycle,Nr as liftToBody,In as liveActivities,Sn as location,Ir as lockBackground,Gr as mirrorTabBar,eo as mobile,yt as nativeFunction,T as nativeFunctionNow,pn as nativeTabs,hr as navTrail,Mn as network,Pt as normalizeAppearance,pt as normalizeDeepLinkURL,wn as notifications,ur as observeLargeTitle,Vn as observeLongPress,Pr as observeNativeRefresh,Ct as observePageScroll,cr as observePullToRefresh,Xn as observeSegmentScrub,Or as observeSheetDrag,Ye as onAppearance,ar as onBackgroundRefresh,R as onCraftEvent,or as onMemoryWarning,_n as onMobileReady,rr as onResume,ir as onSilentPush,Wr as onSpotlightTap,Ke as orientation,xr as paceLabel,Gt as pageBackground,Vt as pageIsDark,F as pageScrollTop,kn as permissions,At as placeMenu,Zt as placeSpotlightItem,Le as presentActionSheet,Ee as presentAlert,se as presentChoice,Te as presentConfirm,Re as presentContextMenu,Hr as presentPageAsCard,Ot as pullDistance,Cn as pushNotifications,nn as readSpotlightEntries,nt as readSpotlightKinds,dn as readTabLinks,M as refresh,en as removeSpotlightItem,dr as resolveScrollHost,Xe as routeStats,fn as routerHandlesTabs,Yt as rubberBand,An as secureStorage,Rt as segmentAt,Jn as segmentForKey,Wt as settleSheet,En as share,Ut as sheetStops,Be as shortcuts,jn as showContextMenuFor,Pn as speech,Sr as speedLabel,Zr as splash,K as spotlightAction,rt as spotlightActions,qr as spotlightActivityTypes,an as spotlightBridge,q as spotlightKind,tn as spotlightRoute,Qt as spotlightSlot,ot as spotlightTitle,z as statusBar,qe as storeKit,ae as subscribeWhenReady,Ne as symbols,un as tabBar,de as toNativeRect,kt as trapFocus,Tr as typedDistanceKm,Ft as usableFixes,Wn as useActionSheet,Nn as watchConnectivity,I as whenBridgeReady,Hn as whenNativeMobile,Fe as widgets,Dn as withNativeFeedback};
|
package/dist/native.d.ts
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import type { ActionSheetOptions, AlertOptions, ConfirmOptions, ContextMenuOptions, NativeRect } from './sheets';
|
|
2
|
+
export type { ActionSheetOptions, AlertOptions, ChoiceOptions, ConfirmOptions, ContextMenuItem, ContextMenuOptions, DialogAction, DialogActionStyle, NativeRect } from './sheets';
|
|
3
|
+
declare function hostNavigator(): Navigator | undefined;
|
|
4
|
+
/** A rectangle the bridge can serialise: getBoundingClientRect() returns a DOMRect, which it cannot. */
|
|
5
|
+
export declare function toNativeRect(rect: { x?: number, y?: number, left?: number, top?: number, width: number, height: number }): NativeRect;
|
|
6
|
+
/** Shows an action sheet: `useActionSheet()(options)`, for a page that keeps the function. */
|
|
7
|
+
export declare function useActionSheet(): (options: ActionSheetOptions) => Promise<string | null>;
|
|
8
|
+
/**
|
|
9
|
+
* Asks before doing something. `await confirmAction({ title: 'Delete this
|
|
10
|
+
* workout?', confirmLabel: 'Delete', destructive: true })` raises the iOS
|
|
11
|
+
* destructive-action sheet and resolves `true` when the action was chosen.
|
|
12
|
+
*/
|
|
13
|
+
export declare function confirmAction(options: ConfirmActionOptions): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Shows a context menu beside `element`, the one that was long-pressed.
|
|
16
|
+
* Resolves with the chosen item's id, or null.
|
|
17
|
+
*/
|
|
18
|
+
export declare function showContextMenuFor(element: Element, options: Omit<ContextMenuOptions, 'anchor'>): Promise<string | null>;
|
|
19
|
+
declare function openOnTheWeb(url: string, options: BrowserOpenOptions): BrowserResult;
|
|
20
|
+
declare function symbolKey(name: string, options: SymbolOptions): string;
|
|
21
|
+
declare function downloadOnTheWeb(href: string, filename: string): string | null;
|
|
22
|
+
declare function pickOnTheWeb(types: string[]): Promise<PickedFile | null>;
|
|
23
|
+
declare function screenOrientation(): LockableOrientation | undefined;
|
|
24
|
+
declare const done: () => true;
|
|
25
|
+
declare const no: () => false;
|
|
26
|
+
declare const nothing: () => null;
|
|
27
|
+
export declare const dialog: DialogApi;
|
|
28
|
+
export declare const contextMenu: ContextMenuApi;
|
|
29
|
+
export declare const browser: BrowserApi;
|
|
30
|
+
declare const symbolRequests: Map<string, Promise<string | null>>;
|
|
31
|
+
declare const symbolImages: Map<string, string | null>;
|
|
32
|
+
export declare const symbols: SymbolsApi;
|
|
33
|
+
export declare const statusBar: StatusBarApi;
|
|
34
|
+
export declare const chrome: ChromeApi;
|
|
35
|
+
export declare const refresh: RefreshApi;
|
|
36
|
+
export declare const background: BackgroundApi;
|
|
37
|
+
export declare const clipboard: ClipboardApi;
|
|
38
|
+
export declare const db: DatabaseApi;
|
|
39
|
+
export declare const files: FilesApi;
|
|
40
|
+
export declare const shortcuts: ShortcutsApi;
|
|
41
|
+
export declare const widgets: WidgetsApi;
|
|
42
|
+
/**
|
|
43
|
+
* @defaultValue
|
|
44
|
+
* ```ts
|
|
45
|
+
* {
|
|
46
|
+
* portrait: 'portrait-primary',
|
|
47
|
+
* portraitUpsideDown: 'portrait-secondary',
|
|
48
|
+
* landscape: 'landscape',
|
|
49
|
+
* landscapeLeft: 'landscape-primary',
|
|
50
|
+
* landscapeRight: 'landscape-secondary'
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
declare const WEB_ORIENTATIONS: Record<OrientationLock, string>;
|
|
55
|
+
export declare const orientation: OrientationApi;
|
|
56
|
+
export declare const auth: AuthApi;
|
|
57
|
+
export declare const storeKit: StoreKitApi;
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Dialogs
|
|
60
|
+
export declare interface DialogApi {
|
|
61
|
+
alert: (options: AlertOptions) => Promise<void>
|
|
62
|
+
confirm: (options: ConfirmOptions) => Promise<boolean>
|
|
63
|
+
actionSheet: (options: ActionSheetOptions) => Promise<string | null>
|
|
64
|
+
}
|
|
65
|
+
export declare interface ConfirmActionOptions extends ConfirmOptions {
|
|
66
|
+
style?: 'sheet' | 'alert'
|
|
67
|
+
anchor?: NativeRect
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Context menus
|
|
71
|
+
export declare interface ContextMenuApi {
|
|
72
|
+
show: (options: ContextMenuOptions) => Promise<string | null>
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// In-app browser
|
|
76
|
+
export declare interface BrowserOpenOptions {
|
|
77
|
+
mode?: 'safari' | 'auth'
|
|
78
|
+
callbackScheme?: string
|
|
79
|
+
}
|
|
80
|
+
export declare interface BrowserResult {
|
|
81
|
+
url?: string
|
|
82
|
+
cancelled: boolean
|
|
83
|
+
}
|
|
84
|
+
export declare interface BrowserApi {
|
|
85
|
+
open: (url: string, options?: BrowserOpenOptions) => Promise<BrowserResult>
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// SF Symbols
|
|
89
|
+
export declare interface SymbolOptions {
|
|
90
|
+
pointSize?: number
|
|
91
|
+
weight?: 'ultralight' | 'thin' | 'light' | 'regular' | 'medium' | 'semibold' | 'bold' | 'heavy' | 'black'
|
|
92
|
+
color?: string
|
|
93
|
+
scale?: 'small' | 'medium' | 'large'
|
|
94
|
+
}
|
|
95
|
+
export declare interface SymbolsApi {
|
|
96
|
+
isAvailable: () => boolean
|
|
97
|
+
image: (name: string, options?: SymbolOptions) => Promise<string | null>
|
|
98
|
+
cached: (name: string, options?: SymbolOptions) => string | null | undefined
|
|
99
|
+
clearCache: () => void
|
|
100
|
+
}
|
|
101
|
+
export declare interface StatusBarApi {
|
|
102
|
+
setStyle: (style: StatusBarStyle) => Promise<boolean>
|
|
103
|
+
}
|
|
104
|
+
export declare interface ChromeApi {
|
|
105
|
+
setUnderPageColor: (color: string) => Promise<boolean>
|
|
106
|
+
setKeyboardAccessory: (visible: boolean) => Promise<boolean>
|
|
107
|
+
}
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Native pull-to-refresh
|
|
110
|
+
export declare interface RefreshApi {
|
|
111
|
+
isAvailable: () => boolean
|
|
112
|
+
enable: (options?: { tintColor?: string }) => Promise<boolean>
|
|
113
|
+
disable: () => Promise<boolean>
|
|
114
|
+
end: () => Promise<boolean>
|
|
115
|
+
onRefresh: (callback: () => void) => () => void
|
|
116
|
+
}
|
|
117
|
+
export declare interface BackgroundApi {
|
|
118
|
+
complete: (ok: boolean) => Promise<boolean>
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Clipboard
|
|
122
|
+
export declare interface ClipboardApi {
|
|
123
|
+
write: (text: string) => Promise<boolean>
|
|
124
|
+
read: () => Promise<string | null>
|
|
125
|
+
}
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// The app's own SQLite database (Documents/craft.db)
|
|
128
|
+
export declare interface DatabaseExecuteResult {
|
|
129
|
+
rowsAffected: number
|
|
130
|
+
lastInsertId: number
|
|
131
|
+
}
|
|
132
|
+
export declare interface DatabaseApi {
|
|
133
|
+
isAvailable: () => boolean
|
|
134
|
+
query: <T = Record<string, unknown>>(sql: string, params?: unknown[]) => Promise<T[] | null>
|
|
135
|
+
execute: (sql: string, params?: unknown[]) => Promise<DatabaseExecuteResult | null>
|
|
136
|
+
}
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// Files, documents and the camera's scanner
|
|
139
|
+
export declare interface PickedFile {
|
|
140
|
+
name: string
|
|
141
|
+
path?: string
|
|
142
|
+
data?: string
|
|
143
|
+
mimeType?: string
|
|
144
|
+
}
|
|
145
|
+
export declare interface ScannedCode {
|
|
146
|
+
type: string
|
|
147
|
+
data: string
|
|
148
|
+
}
|
|
149
|
+
export declare interface FilesApi {
|
|
150
|
+
openPDF: (source: string, page?: number) => Promise<boolean>
|
|
151
|
+
takeScreenshot: () => Promise<string | null>
|
|
152
|
+
scanQRCode: () => Promise<ScannedCode | null>
|
|
153
|
+
pickFile: (types?: string[]) => Promise<PickedFile | null>
|
|
154
|
+
saveFile: (data: string, filename: string, mimeType?: string) => Promise<string | null>
|
|
155
|
+
downloadFile: (url: string, filename: string) => Promise<string | null>
|
|
156
|
+
}
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
// Home screen quick actions
|
|
159
|
+
export declare interface HomeScreenShortcut {
|
|
160
|
+
type: string
|
|
161
|
+
title: string
|
|
162
|
+
subtitle?: string
|
|
163
|
+
symbol?: string
|
|
164
|
+
userInfo?: Record<string, string>
|
|
165
|
+
}
|
|
166
|
+
export declare interface ShortcutsApi {
|
|
167
|
+
set: (shortcuts: HomeScreenShortcut[]) => Promise<boolean>
|
|
168
|
+
clear: () => Promise<boolean>
|
|
169
|
+
onShortcut: (callback: (type: string) => void) => () => void
|
|
170
|
+
}
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Home screen widgets (WidgetKit)
|
|
173
|
+
export declare interface WidgetsApi {
|
|
174
|
+
update: (data: Record<string, unknown>) => Promise<boolean>
|
|
175
|
+
reload: () => Promise<boolean>
|
|
176
|
+
}
|
|
177
|
+
export declare interface OrientationApi {
|
|
178
|
+
lock: (orientation: OrientationLock) => Promise<boolean>
|
|
179
|
+
unlock: () => Promise<boolean>
|
|
180
|
+
}
|
|
181
|
+
declare interface LockableOrientation { lock?: (orientation: string) => Promise<void>, unlock?: () => void }
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// Sign in with Apple
|
|
184
|
+
export declare interface AppleSignInResult {
|
|
185
|
+
userId: string
|
|
186
|
+
email?: string
|
|
187
|
+
name?: string
|
|
188
|
+
identityToken?: string
|
|
189
|
+
authorizationCode?: string
|
|
190
|
+
}
|
|
191
|
+
export declare interface AuthApi {
|
|
192
|
+
signInWithApple: () => Promise<AppleSignInResult | null>
|
|
193
|
+
}
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// In-app purchase (StoreKit 2)
|
|
196
|
+
export declare interface StoreProduct {
|
|
197
|
+
id: string
|
|
198
|
+
displayName: string
|
|
199
|
+
description: string
|
|
200
|
+
price: string
|
|
201
|
+
displayPrice: string
|
|
202
|
+
}
|
|
203
|
+
export declare interface StoreTransaction {
|
|
204
|
+
transactionId: string
|
|
205
|
+
productId: string
|
|
206
|
+
}
|
|
207
|
+
export declare interface StoreKitApi {
|
|
208
|
+
isAvailable: () => boolean
|
|
209
|
+
products: (ids: string[]) => Promise<StoreProduct[]>
|
|
210
|
+
purchase: (id: string) => Promise<StoreTransaction | null>
|
|
211
|
+
restore: () => Promise<StoreTransaction[]>
|
|
212
|
+
}
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
// System chrome
|
|
215
|
+
export type StatusBarStyle = 'default' | 'light' | 'dark';
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
// Orientation
|
|
218
|
+
export type OrientationLock = 'portrait' | 'portraitUpsideDown' | 'landscape' | 'landscapeLeft' | 'landscapeRight';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Whether an element is laid out in view: connected, and not inside something hidden. */
|
|
2
|
+
export declare function isShown(element: HTMLElement): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Refreshes the screen `element` belongs to with the native control, for as
|
|
5
|
+
* long as the returned function is not called. Check `refresh.isAvailable()`
|
|
6
|
+
* first: a shell without the control needs the web gesture instead.
|
|
7
|
+
*/
|
|
8
|
+
export declare function observeNativeRefresh(element: HTMLElement, options: NativeRefreshOptions): () => void;
|
|
9
|
+
export declare interface NativeRefreshOptions {
|
|
10
|
+
tintColor?: string
|
|
11
|
+
onRefresh: () => unknown
|
|
12
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where each detent leaves a panel `height` tall on a `viewport` tall screen:
|
|
3
|
+
* large shows all of it, medium the bottom half of the screen, and dismissed
|
|
4
|
+
* none.
|
|
5
|
+
*/
|
|
6
|
+
export declare function sheetStops(height: number, viewport: number, detents: readonly SheetDetent[]): SheetStop[];
|
|
7
|
+
/**
|
|
8
|
+
* Where a released sheet goes.
|
|
9
|
+
*
|
|
10
|
+
* A flick (faster than 0.5px/ms) goes on to the next stop in its direction,
|
|
11
|
+
* past the lowest detent meaning dismissed. A slow release dismisses once the
|
|
12
|
+
* sheet is more than half way down from its lowest detent, and otherwise
|
|
13
|
+
* springs back to the nearest detent.
|
|
14
|
+
*/
|
|
15
|
+
export declare function settleSheet(state: { y: number, velocity: number, stops: SheetStop[] }): SheetSettle;
|
|
16
|
+
/** iOS's resistance past the top: the further it is pulled, the less it gives. */
|
|
17
|
+
export declare function rubberBand(overshoot: number, dimension?: number): number;
|
|
18
|
+
/**
|
|
19
|
+
* Lets a sheet be dragged by its handles. While dragging, the panel follows
|
|
20
|
+
* the finger with `is-dragging` set (the stylesheet turns its transition off)
|
|
21
|
+
* and its parent's `--native-sheet-presence` (1 open, 0 gone) dims the
|
|
22
|
+
* backdrop to match; on release both are handed back to the stylesheet, which
|
|
23
|
+
* animates to wherever `onSettle` puts it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function observeSheetDrag(options: SheetDragOptions): () => void;
|
|
26
|
+
/**
|
|
27
|
+
* Holds the page still and out of reach behind `keep`: everything outside it
|
|
28
|
+
* becomes inert (no taps, no focus, hidden from VoiceOver) and the document
|
|
29
|
+
* stops scrolling. Returns the release. Nested sheets count, so the page
|
|
30
|
+
* scrolls again only once the last has closed.
|
|
31
|
+
*/
|
|
32
|
+
export declare function lockBackground(keep: HTMLElement): () => void;
|
|
33
|
+
/**
|
|
34
|
+
* Moves `element` to the end of the body, out of every stacking context and
|
|
35
|
+
* transform on the way, and returns the way back: to where it was, or out of
|
|
36
|
+
* the document when that place has gone (the page navigated away).
|
|
37
|
+
*/
|
|
38
|
+
export declare function liftToBody(element: HTMLElement): () => void;
|
|
39
|
+
/**
|
|
40
|
+
* The iOS card presentation: while a large sheet is up, the page behind it
|
|
41
|
+
* shrinks back from the screen's edges, centred on what was in view. Undone by
|
|
42
|
+
* calling it with `false`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function presentPageAsCard(doc: Document, on: boolean): void;
|
|
45
|
+
/** A flick faster than this (CSS pixels a millisecond) moves on to the next stop. */
|
|
46
|
+
export declare const SHEET_FLICK_VELOCITY: 0.5;
|
|
47
|
+
/** A resting place, as the panel's downward offset from its fully open position. */
|
|
48
|
+
export declare interface SheetStop {
|
|
49
|
+
name: SheetSettle
|
|
50
|
+
y: number
|
|
51
|
+
}
|
|
52
|
+
export declare interface SheetDragOptions {
|
|
53
|
+
panel: HTMLElement
|
|
54
|
+
handles: HTMLElement[]
|
|
55
|
+
detents: () => SheetDetent[]
|
|
56
|
+
detent: () => SheetDetent
|
|
57
|
+
viewport?: () => number
|
|
58
|
+
onSettle: (to: SheetSettle) => void
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* What makes a bottom sheet behave like a UISheetPresentationController:
|
|
62
|
+
* dragged by its grabber or header, flicked away, resting at a medium or a
|
|
63
|
+
* large detent, and holding the page behind it still and out of reach.
|
|
64
|
+
*/
|
|
65
|
+
export type SheetDetent = 'medium' | 'large';
|
|
66
|
+
export type SheetSettle = SheetDetent | 'dismiss';
|
package/dist/sheets.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps Tab and Shift+Tab inside `container`: called from a keydown listener,
|
|
3
|
+
* it moves focus from one end to the other instead of out of it.
|
|
4
|
+
*/
|
|
5
|
+
export declare function trapFocus(container: HTMLElement, event: KeyboardEvent): void;
|
|
6
|
+
/**
|
|
7
|
+
* An alert or action sheet drawn in HTML. Resolves with the chosen action's
|
|
8
|
+
* id, or null when it is dismissed or Cancel is chosen.
|
|
9
|
+
*/
|
|
10
|
+
export declare function presentChoice(options: ChoiceOptions): Promise<string | null>;
|
|
11
|
+
export declare function presentAlert(options: AlertOptions): Promise<void>;
|
|
12
|
+
export declare function presentConfirm(options: ConfirmOptions): Promise<boolean>;
|
|
13
|
+
export declare function presentActionSheet(options: ActionSheetOptions): Promise<string | null>;
|
|
14
|
+
/** Where a menu of `size` opens beside `anchor` within a `viewport`, 12px clear of its edges. */
|
|
15
|
+
export declare function placeMenu(anchor: NativeRect, size: { width: number, height: number }, viewport: { width: number, height: number }): { top: number, left: number, origin: string };
|
|
16
|
+
/**
|
|
17
|
+
* A context menu drawn in HTML over a blurred page, beside the element that
|
|
18
|
+
* was pressed. Resolves with the chosen item's id, or null when dismissed.
|
|
19
|
+
*/
|
|
20
|
+
export declare function presentContextMenu(options: ContextMenuOptions): Promise<string | null>;
|
|
21
|
+
export declare interface DialogAction {
|
|
22
|
+
id: string
|
|
23
|
+
title: string
|
|
24
|
+
style?: DialogActionStyle
|
|
25
|
+
}
|
|
26
|
+
/** A rectangle in CSS pixels relative to the viewport, as getBoundingClientRect() reports. */
|
|
27
|
+
export declare interface NativeRect {
|
|
28
|
+
x: number
|
|
29
|
+
y: number
|
|
30
|
+
width: number
|
|
31
|
+
height: number
|
|
32
|
+
}
|
|
33
|
+
export declare interface ChoiceOptions {
|
|
34
|
+
variant: 'alert' | 'sheet'
|
|
35
|
+
title?: string
|
|
36
|
+
message?: string
|
|
37
|
+
actions: DialogAction[]
|
|
38
|
+
cancelLabel?: string
|
|
39
|
+
}
|
|
40
|
+
export declare interface ContextMenuItem {
|
|
41
|
+
id: string
|
|
42
|
+
title: string
|
|
43
|
+
symbol?: string
|
|
44
|
+
icon?: string
|
|
45
|
+
destructive?: boolean
|
|
46
|
+
disabled?: boolean
|
|
47
|
+
}
|
|
48
|
+
export declare interface ContextMenuOptions {
|
|
49
|
+
items: ContextMenuItem[]
|
|
50
|
+
anchor: NativeRect
|
|
51
|
+
title?: string
|
|
52
|
+
}
|
|
53
|
+
export declare interface AlertOptions {
|
|
54
|
+
title: string
|
|
55
|
+
message?: string
|
|
56
|
+
okLabel?: string
|
|
57
|
+
}
|
|
58
|
+
export declare interface ConfirmOptions {
|
|
59
|
+
title: string
|
|
60
|
+
message?: string
|
|
61
|
+
confirmLabel?: string
|
|
62
|
+
cancelLabel?: string
|
|
63
|
+
destructive?: boolean
|
|
64
|
+
}
|
|
65
|
+
export declare interface ActionSheetOptions {
|
|
66
|
+
title?: string
|
|
67
|
+
message?: string
|
|
68
|
+
actions: DialogAction[]
|
|
69
|
+
anchor?: NativeRect
|
|
70
|
+
cancelLabel?: string
|
|
71
|
+
}
|
|
72
|
+
export type DialogActionStyle = 'default' | 'destructive' | 'cancel';
|
package/dist/shell.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { NativeAppearance } from './events';
|
|
2
|
+
/** Writes an appearance where CSS can read it: `--native-font-scale` and `data-native-reduce-*`. */
|
|
3
|
+
export declare function applyAppearance(root: HTMLElement, appearance: NativeAppearance): void;
|
|
4
|
+
/**
|
|
5
|
+
* The colour behind the page: the first opaque background of the body or the
|
|
6
|
+
* root element. The under-page area should read as more of the page when it
|
|
7
|
+
* is pulled past its top or bottom, not as a white or black band.
|
|
8
|
+
*/
|
|
9
|
+
export declare function pageBackground(doc: Document): string | null;
|
|
10
|
+
/** Whether the page draws dark: the `.dark` class, or the system's preference where the app follows it. */
|
|
11
|
+
export declare function pageIsDark(doc: Document): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Keeps the native chrome in step with the page until the returned function
|
|
14
|
+
* is called: on install, whenever the colour scheme flips (the `.dark` class
|
|
15
|
+
* or the system's), after each navigation, and on every appearance change.
|
|
16
|
+
*/
|
|
17
|
+
export declare function installNativeChrome(doc: Document, options?: NativeChromeOptions): () => void;
|
|
18
|
+
export declare interface NativeChromeOptions {
|
|
19
|
+
root?: HTMLElement
|
|
20
|
+
keyboardAccessory?: boolean
|
|
21
|
+
}
|